summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/JavaScriptCore
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/API/APICast.h46
-rw-r--r--Source/JavaScriptCore/API/APIShims.h58
-rw-r--r--Source/JavaScriptCore/API/JSAPIWrapperObject.h60
-rw-r--r--Source/JavaScriptCore/API/JSAPIWrapperObject.mm112
-rw-r--r--Source/JavaScriptCore/API/JSBase.cpp41
-rw-r--r--Source/JavaScriptCore/API/JSBase.h9
-rw-r--r--Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp72
-rw-r--r--Source/JavaScriptCore/API/JSCTestRunnerUtils.h39
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.cpp22
-rw-r--r--Source/JavaScriptCore/API/JSCallbackConstructor.h4
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.cpp32
-rw-r--r--Source/JavaScriptCore/API/JSCallbackFunction.h18
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.cpp23
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObject.h26
-rw-r--r--Source/JavaScriptCore/API/JSCallbackObjectFunctions.h103
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.cpp17
-rw-r--r--Source/JavaScriptCore/API/JSClassRef.h11
-rw-r--r--Source/JavaScriptCore/API/JSContext.h129
-rw-r--r--Source/JavaScriptCore/API/JSContext.mm289
-rw-r--r--Source/JavaScriptCore/API/JSContextInternal.h80
-rw-r--r--Source/JavaScriptCore/API/JSContextRef.cpp138
-rw-r--r--Source/JavaScriptCore/API/JSContextRefPrivate.h48
-rw-r--r--Source/JavaScriptCore/API/JSExport.h130
-rw-r--r--Source/JavaScriptCore/API/JSManagedValue.h66
-rw-r--r--Source/JavaScriptCore/API/JSManagedValue.mm117
-rw-r--r--Source/JavaScriptCore/API/JSObjectRef.cpp157
-rw-r--r--Source/JavaScriptCore/API/JSProfilerPrivate.cpp6
-rw-r--r--Source/JavaScriptCore/API/JSScriptRef.cpp151
-rw-r--r--Source/JavaScriptCore/API/JSScriptRefPrivate.h99
-rw-r--r--Source/JavaScriptCore/API/JSStringRef.cpp8
-rw-r--r--Source/JavaScriptCore/API/JSStringRefCF.cpp6
-rw-r--r--Source/JavaScriptCore/API/JSStringRefPrivate.h41
-rw-r--r--Source/JavaScriptCore/API/JSStringRefQt.cpp50
-rw-r--r--Source/JavaScriptCore/API/JSStringRefQt.h45
-rw-r--r--Source/JavaScriptCore/API/JSValue.h306
-rw-r--r--Source/JavaScriptCore/API/JSValue.mm1131
-rw-r--r--Source/JavaScriptCore/API/JSValueInternal.h58
-rw-r--r--Source/JavaScriptCore/API/JSValueRef.cpp121
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachine.h58
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachine.mm255
-rw-r--r--Source/JavaScriptCore/API/JSVirtualMachineInternal.h57
-rw-r--r--Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp18
-rw-r--r--Source/JavaScriptCore/API/JSWrapperMap.h47
-rw-r--r--Source/JavaScriptCore/API/JSWrapperMap.mm521
-rw-r--r--Source/JavaScriptCore/API/JavaScriptCore.h10
-rw-r--r--Source/JavaScriptCore/API/ObjCCallbackFunction.h73
-rw-r--r--Source/JavaScriptCore/API/ObjCCallbackFunction.mm615
-rw-r--r--Source/JavaScriptCore/API/ObjcRuntimeExtras.h231
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.cpp6
-rw-r--r--Source/JavaScriptCore/API/OpaqueJSString.h13
-rw-r--r--Source/JavaScriptCore/API/tests/JSNode.c1
-rw-r--r--Source/JavaScriptCore/API/tests/JSNodeList.c1
-rw-r--r--Source/JavaScriptCore/API/tests/minidom.c1
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.c315
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.js4
-rw-r--r--Source/JavaScriptCore/API/tests/testapi.mm841
-rw-r--r--Source/JavaScriptCore/CMakeLists.txt228
-rw-r--r--Source/JavaScriptCore/ChangeLog9281
-rw-r--r--Source/JavaScriptCore/ChangeLog-2013-04-2429044
-rw-r--r--Source/JavaScriptCore/Configurations/Base.xcconfig18
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig66
-rw-r--r--Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig6
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig4
-rw-r--r--Source/JavaScriptCore/DerivedSources.make21
-rw-r--r--Source/JavaScriptCore/DerivedSources.pri2
-rw-r--r--Source/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSCTestRunnerUtils.h1
-rw-r--r--Source/JavaScriptCore/GNUmakefile.am10
-rw-r--r--Source/JavaScriptCore/GNUmakefile.list.am168
-rw-r--r--Source/JavaScriptCore/Info.plist2
-rw-r--r--Source/JavaScriptCore/JSCTypedArrayStubs.h25
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.gir.in12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp94
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.gypi14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.order297
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.pri2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make41
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln170
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def439
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj2668
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCF.vsprops11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCFLite.vsprops11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops20
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj104
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedCommon.vsprops14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebug.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugAll.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedProduction.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedRelease.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleaseCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleasePGO.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePGOOptimize.vsprops15
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePostBuild.cmd2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreLink.cmd9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln80
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj173
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj173
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj476
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops20
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj473
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops20
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPostBuild.cmd25
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreLink.cmd9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops12
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj480
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpCommon.vsprops20
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebug.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugAll.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugCairoCFLite.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPostBuild.cmd25
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreLink.cmd9
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpProduction.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpRelease.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleaseCairoCFLite.vsprops8
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleasePGO.vsprops12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj448
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops21
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreLink.cmd9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.make30
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.resources/Info.plist (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist)2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.submit.sln78
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj931
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters1940
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCF.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCFLite.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCommon.props19
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebug.props16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebugCFLite.props16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make)4
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj214
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedCommon.props11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedDebug.props15
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedProduction.props13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedRelease.props13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd2
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreBuild.cmd)0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreLink.cmd0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreProduction.props14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreRelease.props16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreReleaseCFLite.props16
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make)5
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj271
-rw-r--r--[-rwxr-xr-x]Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh)6
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make)4
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj257
-rw-r--r--[-rwxr-xr-x]Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh)4
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj199
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props19
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.props13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props15
-rw-r--r--[-rwxr-xr-x]Source/JavaScriptCore/JavaScriptCore.vcxproj/build-generated-files.sh (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh)9
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcxproj/copy-files.cmd (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd)135
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj310
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscCommon.props22
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscDebug.props13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd1
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreBuild.cmd)0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreLink.cmd0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscProduction.props13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscRelease.props13
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/resource.h14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj317
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj.filters11
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props17
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpDebug.props17
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd3
-rw-r--r--[-rwxr-xr-x]Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreBuild.cmd)0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpProduction.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpRelease.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj287
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommon.props17
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props17
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebug.props14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebugCFLite.props14
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPostBuild.cmd (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPostBuild.cmd)0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd (renamed from Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreBuild.cmd)0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreLink.cmd0
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiProduction.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiRelease.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiReleaseCFLite.props12
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj1253
-rw-r--r--Source/JavaScriptCore/KeywordLookupGenerator.py7
-rw-r--r--Source/JavaScriptCore/LLIntOffsetsExtractor.pro3
-rw-r--r--Source/JavaScriptCore/PlatformBlackBerry.cmake11
-rw-r--r--Source/JavaScriptCore/PlatformEfl.cmake22
-rw-r--r--Source/JavaScriptCore/PlatformWinCE.cmake20
-rw-r--r--Source/JavaScriptCore/Target.pri75
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.cpp4
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.h83
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h99
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h86
-rw-r--r--Source/JavaScriptCore/assembler/AssemblerBuffer.h8
-rw-r--r--Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h4
-rw-r--r--Source/JavaScriptCore/assembler/LinkBuffer.cpp6
-rw-r--r--Source/JavaScriptCore/assembler/LinkBuffer.h8
-rw-r--r--Source/JavaScriptCore/assembler/MIPSAssembler.h4
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssembler.h34
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h82
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h14
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h1
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h69
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerSH4.h1404
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h6
-rw-r--r--Source/JavaScriptCore/assembler/SH4Assembler.h289
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h12
-rw-r--r--Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp2
-rw-r--r--Source/JavaScriptCore/bytecode/ArrayProfile.cpp150
-rw-r--r--Source/JavaScriptCore/bytecode/ArrayProfile.h34
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkInfo.cpp8
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkInfo.h6
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkStatus.cpp96
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkStatus.h84
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp1434
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h2342
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlockHash.cpp3
-rw-r--r--Source/JavaScriptCore/bytecode/CodeOrigin.cpp58
-rw-r--r--Source/JavaScriptCore/bytecode/CodeOrigin.h35
-rw-r--r--Source/JavaScriptCore/bytecode/Comment.h37
-rw-r--r--Source/JavaScriptCore/bytecode/DFGExitProfile.cpp27
-rw-r--r--Source/JavaScriptCore/bytecode/DFGExitProfile.h82
-rw-r--r--Source/JavaScriptCore/bytecode/DataFormat.h11
-rw-r--r--Source/JavaScriptCore/bytecode/EvalCodeCache.h13
-rw-r--r--Source/JavaScriptCore/bytecode/ExecutionCounter.cpp3
-rw-r--r--Source/JavaScriptCore/bytecode/ExitKind.cpp107
-rw-r--r--Source/JavaScriptCore/bytecode/ExitKind.h66
-rw-r--r--Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h71
-rw-r--r--Source/JavaScriptCore/bytecode/GetByIdStatus.cpp18
-rw-r--r--Source/JavaScriptCore/bytecode/GetByIdStatus.h2
-rw-r--r--Source/JavaScriptCore/bytecode/Instruction.h256
-rw-r--r--Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp2
-rw-r--r--Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp2
-rw-r--r--Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h2
-rw-r--r--Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h142
-rw-r--r--Source/JavaScriptCore/bytecode/Opcode.h445
-rw-r--r--Source/JavaScriptCore/bytecode/Operands.h30
-rw-r--r--Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h139
-rw-r--r--Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp4
-rw-r--r--Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h12
-rw-r--r--Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp128
-rw-r--r--Source/JavaScriptCore/bytecode/PreciseJumpTargets.h38
-rw-r--r--Source/JavaScriptCore/bytecode/PutByIdStatus.cpp29
-rw-r--r--Source/JavaScriptCore/bytecode/PutByIdStatus.h4
-rw-r--r--Source/JavaScriptCore/bytecode/ReduceWhitespace.cpp52
-rw-r--r--Source/JavaScriptCore/bytecode/ReduceWhitespace.h38
-rw-r--r--Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp5
-rw-r--r--Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h2
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.cpp6
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.h9
-rw-r--r--Source/JavaScriptCore/bytecode/SpeculatedType.cpp28
-rw-r--r--Source/JavaScriptCore/bytecode/SpeculatedType.h34
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.cpp2
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.h485
-rw-r--r--Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp192
-rw-r--r--Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h165
-rw-r--r--Source/JavaScriptCore/bytecode/ValueProfile.h19
-rw-r--r--Source/JavaScriptCore/bytecode/ValueRecovery.h4
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp534
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h234
-rw-r--r--Source/JavaScriptCore/bytecompiler/Label.h2
-rw-r--r--Source/JavaScriptCore/bytecompiler/LabelScope.h67
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp835
-rw-r--r--Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h67
-rw-r--r--Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h170
-rw-r--r--Source/JavaScriptCore/config.h10
-rwxr-xr-xSource/JavaScriptCore/create_hash_table3
-rw-r--r--Source/JavaScriptCore/create_regex_tables8
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.cpp25
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.h4
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.cpp11
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerActivation.h14
-rw-r--r--Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp19
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp1475
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.h134
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractValue.h45
-rw-r--r--Source/JavaScriptCore/dfg/DFGAdjacencyList.h33
-rw-r--r--Source/JavaScriptCore/dfg/DFGAllocator.h241
-rw-r--r--Source/JavaScriptCore/dfg/DFGArgumentPosition.h64
-rw-r--r--Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp374
-rw-r--r--Source/JavaScriptCore/dfg/DFGArrayMode.cpp72
-rw-r--r--Source/JavaScriptCore/dfg/DFGArrayMode.h41
-rw-r--r--Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h167
-rw-r--r--Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h53
-rw-r--r--Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp368
-rw-r--r--Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h49
-rw-r--r--Source/JavaScriptCore/dfg/DFGBasicBlock.h30
-rw-r--r--Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h51
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeCache.h185
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp2154
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGCCallHelpers.h42
-rw-r--r--Source/JavaScriptCore/dfg/DFGCFAPhase.cpp13
-rw-r--r--Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp466
-rw-r--r--Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp499
-rw-r--r--Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.h50
-rw-r--r--Source/JavaScriptCore/dfg/DFGCSEPhase.cpp1063
-rw-r--r--Source/JavaScriptCore/dfg/DFGCSEPhase.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGCapabilities.cpp40
-rw-r--r--Source/JavaScriptCore/dfg/DFGCapabilities.h105
-rw-r--r--Source/JavaScriptCore/dfg/DFGCommon.cpp127
-rw-r--r--Source/JavaScriptCore/dfg/DFGCommon.h193
-rw-r--r--Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp343
-rw-r--r--Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h164
-rw-r--r--Source/JavaScriptCore/dfg/DFGDCEPhase.cpp201
-rw-r--r--Source/JavaScriptCore/dfg/DFGDCEPhase.h49
-rw-r--r--Source/JavaScriptCore/dfg/DFGDisassembler.cpp100
-rw-r--r--Source/JavaScriptCore/dfg/DFGDisassembler.h29
-rw-r--r--Source/JavaScriptCore/dfg/DFGDoubleFormatState.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.cpp85
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGEdge.cpp (renamed from Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.cpp)17
-rw-r--r--Source/JavaScriptCore/dfg/DFGEdge.h141
-rw-r--r--Source/JavaScriptCore/dfg/DFGFPRInfo.h77
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp1495
-rw-r--r--Source/JavaScriptCore/dfg/DFGGPRInfo.h78
-rw-r--r--Source/JavaScriptCore/dfg/DFGGenerationInfo.h76
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.cpp445
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h584
-rw-r--r--Source/JavaScriptCore/dfg/DFGInsertionSet.h47
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.cpp74
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.h40
-rw-r--r--Source/JavaScriptCore/dfg/DFGLongLivedState.cpp49
-rw-r--r--Source/JavaScriptCore/dfg/DFGLongLivedState.h55
-rw-r--r--Source/JavaScriptCore/dfg/DFGMinifiedGraph.h17
-rw-r--r--Source/JavaScriptCore/dfg/DFGMinifiedID.h109
-rw-r--r--Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp24
-rw-r--r--Source/JavaScriptCore/dfg/DFGMinifiedNode.h19
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.cpp57
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h311
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeAllocator.h51
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeFlags.cpp131
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeFlags.h44
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeType.h67
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSREntry.cpp17
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExit.cpp33
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExit.h24
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h48
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp52
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp27
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp35
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.cpp51
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.h71
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp670
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.h45
-rw-r--r--Source/JavaScriptCore/dfg/DFGPhase.cpp12
-rw-r--r--Source/JavaScriptCore/dfg/DFGPhase.h14
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp97
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.h48
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp789
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h5
-rw-r--r--Source/JavaScriptCore/dfg/DFGRegisterBank.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGRepatch.cpp111
-rw-r--r--Source/JavaScriptCore/dfg/DFGRepatch.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGScoreBoard.h23
-rw-r--r--Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h10
-rw-r--r--Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h16
-rw-r--r--Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h8
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp3199
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h1600
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp2771
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp2713
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h6
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp377
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h50
-rw-r--r--Source/JavaScriptCore/dfg/DFGThunks.cpp58
-rw-r--r--Source/JavaScriptCore/dfg/DFGThunks.h16
-rw-r--r--Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp392
-rw-r--r--Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.h50
-rw-r--r--Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp93
-rw-r--r--Source/JavaScriptCore/dfg/DFGUnificationPhase.h49
-rw-r--r--Source/JavaScriptCore/dfg/DFGUseKind.cpp98
-rw-r--r--Source/JavaScriptCore/dfg/DFGUseKind.h122
-rw-r--r--Source/JavaScriptCore/dfg/DFGValidate.cpp275
-rw-r--r--Source/JavaScriptCore/dfg/DFGValidate.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGValueSource.cpp23
-rw-r--r--Source/JavaScriptCore/dfg/DFGValueSource.h39
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableAccessData.h110
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableEvent.cpp12
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableEvent.h43
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp176
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableEventStream.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariadicFunction.h57
-rw-r--r--Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp46
-rw-r--r--Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.cpp1565
-rw-r--r--Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.h1142
-rw-r--r--Source/JavaScriptCore/disassembler/ARMv7Disassembler.cpp55
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86.c1
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86_decode.c1
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86_input.c1
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86_itab_holder.c1
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86_syn-att.c1
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86_syn-intel.c1
-rw-r--r--Source/JavaScriptCore/disassembler/udis86/udis86_syn.c1
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.cpp25
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.h151
-rw-r--r--Source/JavaScriptCore/heap/CardSet.h91
-rw-r--r--Source/JavaScriptCore/heap/CopiedBlock.h5
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.cpp5
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpaceInlines.h4
-rw-r--r--Source/JavaScriptCore/heap/DFGCodeBlocks.cpp12
-rw-r--r--Source/JavaScriptCore/heap/GCAssertions.h9
-rw-r--r--Source/JavaScriptCore/heap/GCThread.cpp4
-rw-r--r--Source/JavaScriptCore/heap/GCThreadSharedData.cpp18
-rw-r--r--Source/JavaScriptCore/heap/GCThreadSharedData.h8
-rw-r--r--Source/JavaScriptCore/heap/Handle.h5
-rw-r--r--Source/JavaScriptCore/heap/HandleBlock.h73
-rw-r--r--Source/JavaScriptCore/heap/HandleBlockInlines.h74
-rw-r--r--Source/JavaScriptCore/heap/HandleSet.cpp36
-rw-r--r--Source/JavaScriptCore/heap/HandleSet.h108
-rw-r--r--Source/JavaScriptCore/heap/HandleStack.cpp2
-rw-r--r--Source/JavaScriptCore/heap/HandleStack.h2
-rw-r--r--Source/JavaScriptCore/heap/HandleTypes.h2
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp149
-rw-r--r--Source/JavaScriptCore/heap/Heap.h58
-rw-r--r--Source/JavaScriptCore/heap/HeapBlock.h2
-rw-r--r--Source/JavaScriptCore/heap/HeapStatistics.cpp1
-rw-r--r--Source/JavaScriptCore/heap/HeapStatistics.h1
-rw-r--r--Source/JavaScriptCore/heap/HeapTimer.cpp152
-rw-r--r--Source/JavaScriptCore/heap/HeapTimer.h18
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.cpp24
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.h4
-rw-r--r--Source/JavaScriptCore/heap/Local.h22
-rw-r--r--Source/JavaScriptCore/heap/LocalScope.h8
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp4
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.cpp4
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.h12
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.cpp11
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h135
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.cpp31
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h9
-rw-r--r--Source/JavaScriptCore/heap/PassWeak.h74
-rw-r--r--Source/JavaScriptCore/heap/Region.h319
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitor.cpp52
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitor.h3
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitorInlines.h11
-rw-r--r--Source/JavaScriptCore/heap/Strong.h13
-rw-r--r--Source/JavaScriptCore/heap/StrongInlines.h14
-rw-r--r--Source/JavaScriptCore/heap/SuperRegion.cpp82
-rw-r--r--Source/JavaScriptCore/heap/SuperRegion.h58
-rw-r--r--Source/JavaScriptCore/heap/VTableSpectrum.cpp1
-rw-r--r--Source/JavaScriptCore/heap/Weak.cpp41
-rw-r--r--Source/JavaScriptCore/heap/Weak.h190
-rw-r--r--Source/JavaScriptCore/heap/WeakBlock.cpp2
-rw-r--r--Source/JavaScriptCore/heap/WeakBlock.h6
-rw-r--r--Source/JavaScriptCore/heap/WeakImpl.h4
-rw-r--r--Source/JavaScriptCore/heap/WeakInlines.h178
-rw-r--r--Source/JavaScriptCore/heap/WeakSet.cpp2
-rw-r--r--Source/JavaScriptCore/heap/WeakSet.h14
-rw-r--r--Source/JavaScriptCore/heap/WeakSetInlines.h2
-rw-r--r--Source/JavaScriptCore/interpreter/AbstractPC.cpp8
-rw-r--r--Source/JavaScriptCore/interpreter/AbstractPC.h4
-rw-r--r--Source/JavaScriptCore/interpreter/CachedCall.h2
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.cpp28
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h64
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrameClosure.h2
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp538
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h67
-rw-r--r--Source/JavaScriptCore/interpreter/JSStack.cpp6
-rw-r--r--Source/JavaScriptCore/interpreter/JSStack.h6
-rw-r--r--Source/JavaScriptCore/interpreter/JSStackInlines.h1
-rw-r--r--Source/JavaScriptCore/interpreter/Register.h2
-rw-r--r--Source/JavaScriptCore/interpreter/VMInspector.h2
-rw-r--r--Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp11
-rw-r--r--Source/JavaScriptCore/jit/ClosureCallStubRoutine.h2
-rw-r--r--Source/JavaScriptCore/jit/CompactJITCodeMap.h1
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocator.cpp10
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocator.h12
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp34
-rw-r--r--Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp23
-rw-r--r--Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h10
-rw-r--r--Source/JavaScriptCore/jit/HostCallReturnValue.cpp4
-rw-r--r--Source/JavaScriptCore/jit/HostCallReturnValue.h2
-rw-r--r--Source/JavaScriptCore/jit/JIT.cpp175
-rw-r--r--Source/JavaScriptCore/jit/JIT.h231
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic.cpp69
-rw-r--r--Source/JavaScriptCore/jit/JITArithmetic32_64.cpp97
-rw-r--r--Source/JavaScriptCore/jit/JITCall.cpp62
-rw-r--r--Source/JavaScriptCore/jit/JITCall32_64.cpp59
-rw-r--r--Source/JavaScriptCore/jit/JITCode.h13
-rw-r--r--Source/JavaScriptCore/jit/JITDisassembler.cpp89
-rw-r--r--Source/JavaScriptCore/jit/JITDisassembler.h13
-rw-r--r--Source/JavaScriptCore/jit/JITDriver.h12
-rw-r--r--Source/JavaScriptCore/jit/JITExceptions.cpp27
-rw-r--r--Source/JavaScriptCore/jit/JITExceptions.h8
-rw-r--r--Source/JavaScriptCore/jit/JITInlines.h190
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp495
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp442
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess.cpp201
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp124
-rw-r--r--Source/JavaScriptCore/jit/JITStubRoutine.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp558
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.h755
-rw-r--r--Source/JavaScriptCore/jit/JITThunks.cpp108
-rw-r--r--Source/JavaScriptCore/jit/JITThunks.h76
-rw-r--r--Source/JavaScriptCore/jit/JITWriteBarrier.h18
-rw-r--r--Source/JavaScriptCore/jit/JSInterfaceJIT.h166
-rw-r--r--Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h7
-rw-r--r--Source/JavaScriptCore/jit/SpecializedThunkJIT.h17
-rw-r--r--Source/JavaScriptCore/jit/ThunkGenerator.h44
-rw-r--r--Source/JavaScriptCore/jit/ThunkGenerators.cpp538
-rw-r--r--Source/JavaScriptCore/jit/ThunkGenerators.h44
-rw-r--r--Source/JavaScriptCore/jit/UnusedPointer.h37
-rw-r--r--Source/JavaScriptCore/jsc.cpp213
-rw-r--r--Source/JavaScriptCore/llint/LLIntCLoop.h2
-rw-r--r--Source/JavaScriptCore/llint/LLIntData.cpp15
-rw-r--r--Source/JavaScriptCore/llint/LLIntData.h8
-rw-r--r--Source/JavaScriptCore/llint/LLIntEntrypoints.cpp26
-rw-r--r--Source/JavaScriptCore/llint/LLIntEntrypoints.h16
-rw-r--r--Source/JavaScriptCore/llint/LLIntExceptions.cpp35
-rw-r--r--Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h22
-rw-r--r--Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp2
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp229
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.h7
-rw-r--r--Source/JavaScriptCore/llint/LLIntThunks.cpp28
-rw-r--r--Source/JavaScriptCore/llint/LLIntThunks.h14
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm140
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.cpp15
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm284
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm231
-rw-r--r--Source/JavaScriptCore/offlineasm/arm.rb587
-rw-r--r--Source/JavaScriptCore/offlineasm/armv7.rb531
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb12
-rw-r--r--Source/JavaScriptCore/offlineasm/backends.rb9
-rw-r--r--Source/JavaScriptCore/offlineasm/cloop.rb58
-rw-r--r--Source/JavaScriptCore/offlineasm/instructions.rb19
-rw-r--r--Source/JavaScriptCore/offlineasm/mips.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/parser.rb7
-rw-r--r--Source/JavaScriptCore/offlineasm/risc.rb9
-rw-r--r--Source/JavaScriptCore/offlineasm/sh4.rb778
-rw-r--r--Source/JavaScriptCore/offlineasm/x86.rb276
-rw-r--r--Source/JavaScriptCore/os-win32/WinMain.cpp81
-rw-r--r--Source/JavaScriptCore/os-win32/inttypes.h5
-rw-r--r--Source/JavaScriptCore/os-win32/stdint.h67
-rw-r--r--Source/JavaScriptCore/parser/ASTBuilder.h515
-rw-r--r--Source/JavaScriptCore/parser/Lexer.cpp173
-rw-r--r--Source/JavaScriptCore/parser/Lexer.h105
-rw-r--r--Source/JavaScriptCore/parser/NodeConstructors.h158
-rw-r--r--Source/JavaScriptCore/parser/Nodes.cpp89
-rw-r--r--Source/JavaScriptCore/parser/Nodes.h414
-rw-r--r--Source/JavaScriptCore/parser/Parser.cpp321
-rw-r--r--Source/JavaScriptCore/parser/Parser.h239
-rw-r--r--Source/JavaScriptCore/parser/ParserArena.h26
-rw-r--r--Source/JavaScriptCore/parser/ParserError.h110
-rw-r--r--Source/JavaScriptCore/parser/ParserModes.h21
-rw-r--r--Source/JavaScriptCore/parser/ParserTokens.h40
-rw-r--r--Source/JavaScriptCore/parser/ResultType.h5
-rw-r--r--Source/JavaScriptCore/parser/SourceCode.h34
-rw-r--r--Source/JavaScriptCore/parser/SourceProvider.cpp (renamed from Source/JavaScriptCore/assembler/MacroAssemblerSH4.cpp)38
-rw-r--r--Source/JavaScriptCore/parser/SourceProvider.h36
-rw-r--r--Source/JavaScriptCore/parser/SourceProviderCache.cpp9
-rw-r--r--Source/JavaScriptCore/parser/SourceProviderCache.h9
-rw-r--r--Source/JavaScriptCore/parser/SourceProviderCacheItem.h100
-rw-r--r--Source/JavaScriptCore/parser/SyntaxChecker.h74
-rw-r--r--Source/JavaScriptCore/profiler/LegacyProfiler.cpp (renamed from Source/JavaScriptCore/profiler/Profiler.cpp)51
-rw-r--r--Source/JavaScriptCore/profiler/LegacyProfiler.h (renamed from Source/JavaScriptCore/profiler/Profiler.h)58
-rw-r--r--Source/JavaScriptCore/profiler/ProfileGenerator.cpp5
-rw-r--r--Source/JavaScriptCore/profiler/ProfileNode.cpp2
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecode.cpp45
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecode.h65
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp90
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h65
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp69
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerBytecodes.h63
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilation.cpp138
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilation.h88
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp52
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompilationKind.h47
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp56
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h55
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.cpp187
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerDatabase.h93
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h50
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp60
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExit.h61
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp46
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h52
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOrigin.cpp57
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOrigin.h120
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp111
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerOriginStack.h102
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp56
-rw-r--r--Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h51
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/ArgList.h3
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp41
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h34
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/ArrayConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp218
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/ArrayStorage.h6
-rw-r--r--Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h8
-rw-r--r--Source/JavaScriptCore/runtime/BigInteger.h2
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.cpp15
-rw-r--r--Source/JavaScriptCore/runtime/BooleanConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/BooleanObject.h14
-rw-r--r--Source/JavaScriptCore/runtime/BooleanPrototype.cpp17
-rw-r--r--Source/JavaScriptCore/runtime/BooleanPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/Butterfly.h68
-rw-r--r--Source/JavaScriptCore/runtime/ButterflyInlines.h51
-rw-r--r--Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h2
-rw-r--r--Source/JavaScriptCore/runtime/CallData.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/CallData.h2
-rw-r--r--Source/JavaScriptCore/runtime/CodeCache.cpp143
-rw-r--r--Source/JavaScriptCore/runtime/CodeCache.h256
-rw-r--r--Source/JavaScriptCore/runtime/CommonIdentifiers.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/CommonIdentifiers.h69
-rw-r--r--Source/JavaScriptCore/runtime/CommonSlowPaths.h4
-rw-r--r--Source/JavaScriptCore/runtime/Completion.cpp26
-rw-r--r--Source/JavaScriptCore/runtime/Completion.h7
-rw-r--r--Source/JavaScriptCore/runtime/ConstructData.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/ConstructData.h2
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp35
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/DateInstance.h12
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp64
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/Error.cpp30
-rw-r--r--Source/JavaScriptCore/runtime/Error.h8
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/ErrorConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/ErrorInstance.h20
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/ErrorPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/ExceptionHelpers.cpp93
-rw-r--r--Source/JavaScriptCore/runtime/ExceptionHelpers.h53
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp124
-rw-r--r--Source/JavaScriptCore/runtime/Executable.h205
-rw-r--r--Source/JavaScriptCore/runtime/ExecutionHarness.h8
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp37
-rw-r--r--Source/JavaScriptCore/runtime/FunctionExecutableDump.h49
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.cpp17
-rw-r--r--Source/JavaScriptCore/runtime/FunctionPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallback.cpp53
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallback.h22
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/GetterSetter.h12
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.cpp64
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.h52
-rw-r--r--Source/JavaScriptCore/runtime/IndexingHeader.h32
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.h25
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.cpp15
-rw-r--r--Source/JavaScriptCore/runtime/InternalFunction.h6
-rw-r--r--Source/JavaScriptCore/runtime/Intrinsic.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSAPIValueWrapper.h12
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.cpp19
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h30
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp185
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h70
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.cpp10
-rw-r--r--Source/JavaScriptCore/runtime/JSBoundFunction.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSCJSValue.cpp (renamed from Source/JavaScriptCore/runtime/JSValue.cpp)77
-rw-r--r--Source/JavaScriptCore/runtime/JSCJSValue.h (renamed from Source/JavaScriptCore/runtime/JSValue.h)26
-rw-r--r--Source/JavaScriptCore/runtime/JSCJSValueInlines.h810
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.cpp29
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h189
-rw-r--r--Source/JavaScriptCore/runtime/JSCellInlines.h204
-rw-r--r--Source/JavaScriptCore/runtime/JSDateMath.cpp102
-rw-r--r--Source/JavaScriptCore/runtime/JSDestructibleObject.h39
-rw-r--r--Source/JavaScriptCore/runtime/JSExportMacros.h2
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp73
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.h66
-rw-r--r--Source/JavaScriptCore/runtime/JSFunctionInlines.h69
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp311
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h876
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h58
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.cpp54
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.h29
-rw-r--r--Source/JavaScriptCore/runtime/JSNameScope.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/JSNameScope.h8
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSNotAnObject.h8
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.cpp103
-rw-r--r--Source/JavaScriptCore/runtime/JSONObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp712
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h610
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/JSPropertyNameIterator.h29
-rw-r--r--Source/JavaScriptCore/runtime/JSProxy.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSProxy.h28
-rw-r--r--Source/JavaScriptCore/runtime/JSScope.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/JSScope.h20
-rw-r--r--Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h9
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h892
-rw-r--r--Source/JavaScriptCore/runtime/JSStringBuilder.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSStringJoiner.cpp22
-rw-r--r--Source/JavaScriptCore/runtime/JSStringJoiner.h13
-rw-r--r--Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/JSSymbolTableObject.h22
-rw-r--r--Source/JavaScriptCore/runtime/JSTypeInfo.h3
-rw-r--r--Source/JavaScriptCore/runtime/JSValueInlines.h497
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSVariableObject.h5
-rw-r--r--Source/JavaScriptCore/runtime/JSWithScope.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSWithScope.h16
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSWrapperObject.h32
-rw-r--r--Source/JavaScriptCore/runtime/LiteralParser.cpp42
-rw-r--r--Source/JavaScriptCore/runtime/LiteralParser.h2
-rw-r--r--Source/JavaScriptCore/runtime/Lookup.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/Lookup.h47
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.cpp45
-rw-r--r--Source/JavaScriptCore/runtime/MathObject.h4
-rw-r--r--Source/JavaScriptCore/runtime/MemoryStatistics.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/MemoryStatistics.h2
-rw-r--r--Source/JavaScriptCore/runtime/NameConstructor.cpp9
-rw-r--r--Source/JavaScriptCore/runtime/NameConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NameInstance.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/NameInstance.h16
-rw-r--r--Source/JavaScriptCore/runtime/NamePrototype.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/NamePrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorConstructor.h12
-rw-r--r--Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/NumberConstructor.h4
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/NumberObject.h14
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.cpp38
-rw-r--r--Source/JavaScriptCore/runtime/NumberPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.cpp50
-rw-r--r--Source/JavaScriptCore/runtime/ObjectConstructor.h30
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.cpp59
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.h17
-rw-r--r--Source/JavaScriptCore/runtime/Operations.cpp26
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h526
-rw-r--r--Source/JavaScriptCore/runtime/Options.cpp63
-rw-r--r--Source/JavaScriptCore/runtime/Options.h47
-rw-r--r--Source/JavaScriptCore/runtime/PropertyDescriptor.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/PropertyDescriptor.h2
-rw-r--r--Source/JavaScriptCore/runtime/PropertyMapHashTable.h131
-rw-r--r--Source/JavaScriptCore/runtime/PropertyNameArray.h12
-rw-r--r--Source/JavaScriptCore/runtime/PropertyOffset.h21
-rw-r--r--Source/JavaScriptCore/runtime/PropertySlot.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/PropertySlot.h2
-rw-r--r--Source/JavaScriptCore/runtime/PropertyTable.cpp146
-rw-r--r--Source/JavaScriptCore/runtime/Protect.h2
-rw-r--r--Source/JavaScriptCore/runtime/PrototypeMap.cpp75
-rw-r--r--Source/JavaScriptCore/runtime/PrototypeMap.h65
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.cpp64
-rw-r--r--Source/JavaScriptCore/runtime/RegExp.h26
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.cpp14
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCache.h5
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCachedResult.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/RegExpCachedResult.h12
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.cpp11
-rw-r--r--Source/JavaScriptCore/runtime/RegExpConstructor.h20
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.h8
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/RegExpObject.h12
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.cpp7
-rw-r--r--Source/JavaScriptCore/runtime/RegExpPrototype.h4
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.cpp32
-rw-r--r--Source/JavaScriptCore/runtime/SmallStrings.h27
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.h8
-rw-r--r--Source/JavaScriptCore/runtime/StrictEvalActivation.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/StrictEvalActivation.h6
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.cpp12
-rw-r--r--Source/JavaScriptCore/runtime/StringConstructor.h6
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.cpp13
-rw-r--r--Source/JavaScriptCore/runtime/StringObject.h16
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp159
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.h19
-rw-r--r--Source/JavaScriptCore/runtime/StringRecursionChecker.cpp3
-rw-r--r--Source/JavaScriptCore/runtime/StringRecursionChecker.h10
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp469
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h843
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.cpp5
-rw-r--r--Source/JavaScriptCore/runtime/StructureChain.h16
-rw-r--r--Source/JavaScriptCore/runtime/StructureInlines.h226
-rw-r--r--Source/JavaScriptCore/runtime/StructureRareData.cpp83
-rw-r--r--Source/JavaScriptCore/runtime/StructureRareData.h76
-rw-r--r--Source/JavaScriptCore/runtime/StructureRareDataInlines.h60
-rw-r--r--Source/JavaScriptCore/runtime/StructureTransitionTable.h22
-rw-r--r--Source/JavaScriptCore/runtime/SymbolTable.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/SymbolTable.h661
-rw-r--r--Source/JavaScriptCore/runtime/Terminator.h47
-rw-r--r--Source/JavaScriptCore/runtime/TimeoutChecker.cpp147
-rw-r--r--Source/JavaScriptCore/runtime/TimeoutChecker.h74
-rw-r--r--Source/JavaScriptCore/runtime/Uint16WithFraction.h2
-rw-r--r--Source/JavaScriptCore/runtime/VM.cpp (renamed from Source/JavaScriptCore/runtime/JSGlobalData.cpp)165
-rw-r--r--Source/JavaScriptCore/runtime/VM.h (renamed from Source/JavaScriptCore/runtime/JSGlobalData.h)157
-rw-r--r--Source/JavaScriptCore/runtime/VMStackBounds.h71
-rw-r--r--Source/JavaScriptCore/runtime/Watchdog.cpp199
-rw-r--r--Source/JavaScriptCore/runtime/Watchdog.h116
-rw-r--r--Source/JavaScriptCore/runtime/WatchdogMac.cpp72
-rw-r--r--Source/JavaScriptCore/runtime/WatchdogNone.cpp50
-rw-r--r--Source/JavaScriptCore/runtime/WeakGCMap.h118
-rw-r--r--Source/JavaScriptCore/runtime/WriteBarrier.h34
-rw-r--r--Source/JavaScriptCore/shell/CMakeLists.txt39
-rw-r--r--Source/JavaScriptCore/shell/PlatformBlackBerry.cmake9
-rw-r--r--Source/JavaScriptCore/shell/PlatformEfl.cmake3
-rw-r--r--Source/JavaScriptCore/shell/PlatformGTK.cmake3
-rw-r--r--Source/JavaScriptCore/shell/PlatformWinCE.cmake3
-rw-r--r--Source/JavaScriptCore/testRegExp.cpp50
-rw-r--r--Source/JavaScriptCore/tests/mozilla/jsDriver.pl21
-rw-r--r--Source/JavaScriptCore/tools/CodeProfile.cpp2
-rw-r--r--Source/JavaScriptCore/tools/TieredMMapArray.h3
-rw-r--r--Source/JavaScriptCore/wscript90
-rw-r--r--Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.h6
-rw-r--r--Source/JavaScriptCore/yarr/YarrInterpreter.cpp59
-rw-r--r--Source/JavaScriptCore/yarr/YarrInterpreter.h25
-rw-r--r--Source/JavaScriptCore/yarr/YarrJIT.cpp39
-rw-r--r--Source/JavaScriptCore/yarr/YarrJIT.h6
-rw-r--r--Source/JavaScriptCore/yarr/YarrParser.h4
-rw-r--r--Source/JavaScriptCore/yarr/YarrPattern.cpp76
-rw-r--r--Source/JavaScriptCore/yarr/YarrPattern.h68
851 files changed, 86306 insertions, 45952 deletions
diff --git a/Source/JavaScriptCore/API/APICast.h b/Source/JavaScriptCore/API/APICast.h
index f019a7a4b..fc5d71b2e 100644
--- a/Source/JavaScriptCore/API/APICast.h
+++ b/Source/JavaScriptCore/API/APICast.h
@@ -27,14 +27,13 @@
#define APICast_h
#include "JSAPIValueWrapper.h"
+#include "JSCJSValue.h"
#include "JSGlobalObject.h"
-#include "JSValue.h"
-#include <wtf/UnusedParam.h>
namespace JSC {
class ExecState;
class PropertyNameArray;
- class JSGlobalData;
+ class VM;
class JSObject;
class JSValue;
}
@@ -63,46 +62,63 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c)
inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v)
{
ASSERT_UNUSED(exec, exec);
- ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
if (!jsCell)
- return JSC::JSValue();
+ return JSC::jsNull();
+ JSC::JSValue result;
if (jsCell->isAPIValueWrapper())
- return JSC::jsCast<JSC::JSAPIValueWrapper*>(jsCell)->value();
- return jsCell;
+ result = JSC::jsCast<JSC::JSAPIValueWrapper*>(jsCell)->value();
+ else
+ result = jsCell;
#else
- return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
+ JSC::JSValue result = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
#endif
+ if (!result)
+ return JSC::jsNull();
+ if (result.isCell())
+ RELEASE_ASSERT(result.asCell()->methodTable());
+ return result;
}
inline JSC::JSValue toJSForGC(JSC::ExecState* exec, JSValueRef v)
{
ASSERT_UNUSED(exec, exec);
- ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
if (!jsCell)
return JSC::JSValue();
- return jsCell;
+ JSC::JSValue result = jsCell;
#else
- return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
+ JSC::JSValue result = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
#endif
+ if (result && result.isCell())
+ RELEASE_ASSERT(result.asCell()->methodTable());
+ return result;
}
-inline JSC::JSObject* toJS(JSObjectRef o)
+// Used in JSObjectGetPrivate as that may be called during finalization
+inline JSC::JSObject* uncheckedToJS(JSObjectRef o)
{
return reinterpret_cast<JSC::JSObject*>(o);
}
+inline JSC::JSObject* toJS(JSObjectRef o)
+{
+ JSC::JSObject* object = uncheckedToJS(o);
+ if (object)
+ RELEASE_ASSERT(object->methodTable());
+ return object;
+}
+
inline JSC::PropertyNameArray* toJS(JSPropertyNameAccumulatorRef a)
{
return reinterpret_cast<JSC::PropertyNameArray*>(a);
}
-inline JSC::JSGlobalData* toJS(JSContextGroupRef g)
+inline JSC::VM* toJS(JSContextGroupRef g)
{
- return reinterpret_cast<JSC::JSGlobalData*>(const_cast<OpaqueJSContextGroup*>(g));
+ return reinterpret_cast<JSC::VM*>(const_cast<OpaqueJSContextGroup*>(g));
}
inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v)
@@ -145,7 +161,7 @@ inline JSPropertyNameAccumulatorRef toRef(JSC::PropertyNameArray* l)
return reinterpret_cast<JSPropertyNameAccumulatorRef>(l);
}
-inline JSContextGroupRef toRef(JSC::JSGlobalData* g)
+inline JSContextGroupRef toRef(JSC::VM* g)
{
return reinterpret_cast<JSContextGroupRef>(g);
}
diff --git a/Source/JavaScriptCore/API/APIShims.h b/Source/JavaScriptCore/API/APIShims.h
index ef5f10466..d8e1fb790 100644
--- a/Source/JavaScriptCore/API/APIShims.h
+++ b/Source/JavaScriptCore/API/APIShims.h
@@ -35,34 +35,22 @@
namespace JSC {
class APIEntryShimWithoutLock {
-public:
- enum RefGlobalDataTag { DontRefGlobalData = 0, RefGlobalData };
-
protected:
- APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread, RefGlobalDataTag shouldRefGlobalData)
- : m_shouldRefGlobalData(shouldRefGlobalData)
- , m_globalData(globalData)
- , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
+ APIEntryShimWithoutLock(VM* vm, bool registerThread)
+ : m_vm(vm)
+ , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(vm->identifierTable))
{
- if (shouldRefGlobalData)
- m_globalData->ref();
- UNUSED_PARAM(registerThread);
if (registerThread)
- globalData->heap.machineThreads().addCurrentThread();
- m_globalData->heap.activityCallback()->synchronize();
- m_globalData->heap.sweeper()->synchronize();
+ vm->heap.machineThreads().addCurrentThread();
}
~APIEntryShimWithoutLock()
{
wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
- if (m_shouldRefGlobalData)
- m_globalData->deref();
}
protected:
- RefGlobalDataTag m_shouldRefGlobalData;
- JSGlobalData* m_globalData;
+ RefPtr<VM> m_vm;
IdentifierTable* m_entryIdentifierTable;
};
@@ -70,57 +58,45 @@ class APIEntryShim : public APIEntryShimWithoutLock {
public:
// Normal API entry
APIEntryShim(ExecState* exec, bool registerThread = true)
- : APIEntryShimWithoutLock(&exec->globalData(), registerThread, RefGlobalData)
+ : APIEntryShimWithoutLock(&exec->vm(), registerThread)
+ , m_lockHolder(exec)
{
- init();
}
- // This constructor is necessary for HeapTimer to prevent it from accidentally resurrecting
- // the ref count of a "dead" JSGlobalData.
- APIEntryShim(JSGlobalData* globalData, RefGlobalDataTag refGlobalData, bool registerThread = true)
- : APIEntryShimWithoutLock(globalData, registerThread, refGlobalData)
+ // JSPropertyNameAccumulator only has a vm.
+ APIEntryShim(VM* vm, bool registerThread = true)
+ : APIEntryShimWithoutLock(vm, registerThread)
+ , m_lockHolder(vm)
{
- init();
- }
-
- // JSPropertyNameAccumulator only has a globalData.
- APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
- : APIEntryShimWithoutLock(globalData, registerThread, RefGlobalData)
- {
- init();
}
~APIEntryShim()
{
- m_globalData->timeoutChecker.stop();
- m_globalData->apiLock().unlock();
+ // Destroying our JSLockHolder should also destroy the VM.
+ m_vm.clear();
}
private:
- void init()
- {
- m_globalData->apiLock().lock();
- m_globalData->timeoutChecker.start();
- }
+ JSLockHolder m_lockHolder;
};
class APICallbackShim {
public:
APICallbackShim(ExecState* exec)
: m_dropAllLocks(exec)
- , m_globalData(&exec->globalData())
+ , m_vm(&exec->vm())
{
wtfThreadData().resetCurrentIdentifierTable();
}
~APICallbackShim()
{
- wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
+ wtfThreadData().setCurrentIdentifierTable(m_vm->identifierTable);
}
private:
JSLock::DropAllLocks m_dropAllLocks;
- JSGlobalData* m_globalData;
+ VM* m_vm;
};
}
diff --git a/Source/JavaScriptCore/API/JSAPIWrapperObject.h b/Source/JavaScriptCore/API/JSAPIWrapperObject.h
new file mode 100644
index 000000000..909039771
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSAPIWrapperObject.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSAPIWrapperObject_h
+#define JSAPIWrapperObject_h
+
+#include "JSBase.h"
+#include "JSDestructibleObject.h"
+#include "WeakReferenceHarvester.h"
+
+#if JSC_OBJC_API_ENABLED
+
+namespace JSC {
+
+class JSAPIWrapperObject : public JSDestructibleObject {
+public:
+ typedef JSDestructibleObject Base;
+
+ void finishCreation(VM&);
+ static void visitChildren(JSCell*, JSC::SlotVisitor&);
+
+ void* wrappedObject() { return m_wrappedObject; }
+ void setWrappedObject(void*);
+
+protected:
+ static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
+
+ JSAPIWrapperObject(VM&, Structure*);
+
+private:
+ void* m_wrappedObject;
+};
+
+} // namespace JSC
+
+#endif // JSC_OBJC_API_ENABLED
+
+#endif // JSAPIWrapperObject_h
diff --git a/Source/JavaScriptCore/API/JSAPIWrapperObject.mm b/Source/JavaScriptCore/API/JSAPIWrapperObject.mm
new file mode 100644
index 000000000..c06de3978
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSAPIWrapperObject.mm
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSAPIWrapperObject.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSCallbackObject.h"
+#include "JSCellInlines.h"
+#include "JSVirtualMachineInternal.h"
+#include "SlotVisitorInlines.h"
+#include "Structure.h"
+#include "StructureInlines.h"
+
+#if JSC_OBJC_API_ENABLED
+
+class JSAPIWrapperObjectHandleOwner : public JSC::WeakHandleOwner {
+public:
+ virtual void finalize(JSC::Handle<JSC::Unknown>, void*);
+ virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
+};
+
+static JSAPIWrapperObjectHandleOwner* jsAPIWrapperObjectHandleOwner()
+{
+ DEFINE_STATIC_LOCAL(JSAPIWrapperObjectHandleOwner, jsWrapperObjectHandleOwner, ());
+ return &jsWrapperObjectHandleOwner;
+}
+
+void JSAPIWrapperObjectHandleOwner::finalize(JSC::Handle<JSC::Unknown> handle, void*)
+{
+ JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast<JSC::JSAPIWrapperObject*>(handle.get().asCell());
+ if (!wrapperObject->wrappedObject())
+ return;
+ [static_cast<id>(wrapperObject->wrappedObject()) release];
+ JSC::WeakSet::deallocate(JSC::WeakImpl::asWeakImpl(handle.slot()));
+}
+
+bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
+{
+ JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast<JSC::JSAPIWrapperObject*>(handle.get().asCell());
+ // We use the JSGlobalObject when processing weak handles to prevent the situation where using
+ // the same Objective-C object in multiple global objects keeps all of the global objects alive.
+ if (!wrapperObject->wrappedObject())
+ return false;
+ return JSC::Heap::isMarked(wrapperObject->structure()->globalObject()) && visitor.containsOpaqueRoot(wrapperObject->wrappedObject());
+}
+
+namespace JSC {
+
+template <> const ClassInfo JSCallbackObject<JSAPIWrapperObject>::s_info = { "JSAPIWrapperObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
+
+template<> const bool JSCallbackObject<JSAPIWrapperObject>::needsDestruction = true;
+
+template <>
+Structure* JSCallbackObject<JSAPIWrapperObject>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+{
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+}
+
+JSAPIWrapperObject::JSAPIWrapperObject(VM& vm, Structure* structure)
+ : Base(vm, structure)
+ , m_wrappedObject(0)
+{
+}
+
+void JSAPIWrapperObject::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ WeakSet::allocate(this, jsAPIWrapperObjectHandleOwner(), 0); // Balanced in JSAPIWrapperObjectHandleOwner::finalize.
+}
+
+void JSAPIWrapperObject::setWrappedObject(void* wrappedObject)
+{
+ ASSERT(!m_wrappedObject);
+ m_wrappedObject = [static_cast<id>(wrappedObject) retain];
+}
+
+void JSAPIWrapperObject::visitChildren(JSCell* cell, JSC::SlotVisitor& visitor)
+{
+ JSAPIWrapperObject* thisObject = JSC::jsCast<JSAPIWrapperObject*>(cell);
+ COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
+ Base::visitChildren(cell, visitor);
+
+ if (thisObject->wrappedObject())
+ scanExternalObjectGraph(cell->structure()->globalObject()->vm(), visitor, thisObject->wrappedObject());
+}
+
+} // namespace JSC
+
+#endif // JSC_OBJC_API_ENABLED
diff --git a/Source/JavaScriptCore/API/JSBase.cpp b/Source/JavaScriptCore/API/JSBase.cpp
index 677c68187..7669ff1a9 100644
--- a/Source/JavaScriptCore/API/JSBase.cpp
+++ b/Source/JavaScriptCore/API/JSBase.cpp
@@ -29,20 +29,25 @@
#include "APICast.h"
#include "APIShims.h"
+#include "CallFrame.h"
+#include "Completion.h"
+#include "InitializeThreading.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "JSObject.h"
#include "OpaqueJSString.h"
+#include "Operations.h"
#include "SourceCode.h"
-#include <interpreter/CallFrame.h>
-#include <runtime/InitializeThreading.h>
-#include <runtime/Completion.h>
-#include <runtime/JSGlobalObject.h>
-#include <runtime/JSLock.h>
-#include <runtime/JSObject.h>
#include <wtf/text/StringHash.h>
using namespace JSC;
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -70,6 +75,10 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -100,12 +109,28 @@ void JSGarbageCollect(JSContextRef ctx)
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec, false);
- exec->globalData().heap.reportAbandonedObjectGraph();
+ exec->vm().heap.reportAbandonedObjectGraph();
}
void JSReportExtraMemoryCost(JSContextRef ctx, size_t size)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ExecState* exec = toJS(ctx);
+ APIEntryShim entryShim(exec);
+ exec->vm().heap.reportExtraMemoryCost(size);
+}
+
+extern "C" JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef);
+
+void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx)
+{
+ if (!ctx)
+ return;
+
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- exec->globalData().heap.reportExtraMemoryCost(size);
+ exec->vm().heap.collectAllGarbage();
}
diff --git a/Source/JavaScriptCore/API/JSBase.h b/Source/JavaScriptCore/API/JSBase.h
index f46a41755..50e8f1e64 100644
--- a/Source/JavaScriptCore/API/JSBase.h
+++ b/Source/JavaScriptCore/API/JSBase.h
@@ -30,6 +30,10 @@
#include <stdbool.h>
#endif
+#ifdef __OBJC__
+#import <Foundation/Foundation.h>
+#endif
+
/* JavaScript engine interface */
/*! @typedef JSContextGroupRef A group that associates JavaScript contexts with one another. Contexts in the same group may share and exchange JavaScript objects. */
@@ -135,4 +139,9 @@ JS_EXPORT void JSGarbageCollect(JSContextRef ctx);
}
#endif
+/* Enable the Objective-C API for platforms with a modern runtime. */
+#if !defined(JSC_OBJC_API_ENABLED)
+#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 && !defined(__i386__))
+#endif
+
#endif /* JSBase_h */
diff --git a/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp b/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
new file mode 100644
index 000000000..394246711
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSCTestRunnerUtils.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSCTestRunnerUtils.h"
+
+#include "APICast.h"
+#include "CodeBlock.h"
+#include "Operations.h"
+
+namespace JSC {
+
+static FunctionExecutable* getExecutable(JSContextRef context, JSValueRef theFunctionValueRef)
+{
+ ExecState* exec = toJS(context);
+ JSValue theFunctionValue = toJS(exec, theFunctionValueRef);
+
+ JSFunction* theFunction = jsDynamicCast<JSFunction*>(theFunctionValue);
+ if (!theFunction)
+ return 0;
+
+ FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(
+ theFunction->executable());
+ return executable;
+}
+
+JSValueRef numberOfDFGCompiles(JSContextRef context, JSValueRef theFunctionValueRef)
+{
+ if (FunctionExecutable* executable = getExecutable(context, theFunctionValueRef)) {
+ CodeBlock* baselineCodeBlock = executable->baselineCodeBlockFor(CodeForCall);
+
+ if (!baselineCodeBlock)
+ return JSValueMakeNumber(context, 0);
+
+ return JSValueMakeNumber(context, baselineCodeBlock->numberOfDFGCompiles());
+ }
+
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef setNeverInline(JSContextRef context, JSValueRef theFunctionValueRef)
+{
+ if (FunctionExecutable* executable = getExecutable(context, theFunctionValueRef))
+ executable->setNeverInline(true);
+
+ return JSValueMakeUndefined(context);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/API/JSCTestRunnerUtils.h b/Source/JavaScriptCore/API/JSCTestRunnerUtils.h
new file mode 100644
index 000000000..aaecdd5c9
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSCTestRunnerUtils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSCTestRunnerUtils_h
+#define JSCTestRunnerUtils_h
+
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSValueRef.h>
+
+namespace JSC {
+
+JS_EXPORT_PRIVATE JSValueRef numberOfDFGCompiles(JSContextRef, JSValueRef theFunction);
+JS_EXPORT_PRIVATE JSValueRef setNeverInline(JSContextRef, JSValueRef theFunction);
+
+} // namespace JSC
+
+#endif // JSCTestRunnerUtils_h
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.cpp b/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
index c43182e8f..8340c10b4 100644
--- a/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
+++ b/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
@@ -28,10 +28,11 @@
#include "APIShims.h"
#include "APICast.h"
-#include <runtime/Error.h>
-#include <runtime/JSGlobalObject.h>
-#include <runtime/JSLock.h>
-#include <runtime/ObjectPrototype.h>
+#include "Error.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "ObjectPrototype.h"
+#include "Operations.h"
#include <wtf/Vector.h>
namespace JSC {
@@ -39,7 +40,7 @@ namespace JSC {
const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
- : JSDestructibleObject(globalObject->globalData(), structure)
+ : JSDestructibleObject(globalObject->vm(), structure)
, m_class(jsClass)
, m_callback(callback)
{
@@ -47,7 +48,7 @@ JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Struc
void JSCallbackConstructor::finishCreation(JSGlobalObject* globalObject, JSClassRef jsClass)
{
- Base::finishCreation(globalObject->globalData());
+ Base::finishCreation(globalObject->vm());
ASSERT(inherits(&s_info));
if (m_class)
JSClassRetain(jsClass);
@@ -72,10 +73,11 @@ static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec)
JSObjectCallAsConstructorCallback callback = jsCast<JSCallbackConstructor*>(constructor)->callback();
if (callback) {
- int argumentCount = static_cast<int>(exec->argumentCount());
- Vector<JSValueRef, 16> arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
+ size_t argumentCount = exec->argumentCount();
+ Vector<JSValueRef, 16> arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
JSValueRef exception = 0;
JSObjectRef result;
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.h b/Source/JavaScriptCore/API/JSCallbackConstructor.h
index 2bb4d07af..72100e672 100644
--- a/Source/JavaScriptCore/API/JSCallbackConstructor.h
+++ b/Source/JavaScriptCore/API/JSCallbackConstructor.h
@@ -48,9 +48,9 @@ public:
JSObjectCallAsConstructorCallback callback() const { return m_callback; }
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.cpp b/Source/JavaScriptCore/API/JSCallbackFunction.cpp
index aada87bfa..c29b9077c 100644
--- a/Source/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/Source/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -29,11 +29,13 @@
#include "APIShims.h"
#include "APICast.h"
#include "CodeBlock.h"
+#include "Error.h"
#include "ExceptionHelpers.h"
-#include "JSFunction.h"
#include "FunctionPrototype.h"
-#include <runtime/JSGlobalObject.h>
-#include <runtime/JSLock.h>
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "Operations.h"
#include <wtf/Vector.h>
namespace JSC {
@@ -42,28 +44,36 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCallbackFunction);
const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) };
-JSCallbackFunction::JSCallbackFunction(JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback)
- : InternalFunction(globalObject, globalObject->callbackFunctionStructure())
+JSCallbackFunction::JSCallbackFunction(JSGlobalObject* globalObject, Structure* structure, JSObjectCallAsFunctionCallback callback)
+ : InternalFunction(globalObject, structure)
, m_callback(callback)
{
}
-void JSCallbackFunction::finishCreation(JSGlobalData& globalData, const String& name)
+void JSCallbackFunction::finishCreation(VM& vm, const String& name)
{
- Base::finishCreation(globalData, name);
+ Base::finishCreation(vm, name);
ASSERT(inherits(&s_info));
}
+JSCallbackFunction* JSCallbackFunction::create(ExecState* exec, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const String& name)
+{
+ JSCallbackFunction* function = new (NotNull, allocateCell<JSCallbackFunction>(*exec->heap())) JSCallbackFunction(globalObject, globalObject->callbackFunctionStructure(), callback);
+ function->finishCreation(exec->vm(), name);
+ return function;
+}
+
EncodedJSValue JSCallbackFunction::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
- int argumentCount = static_cast<int>(exec->argumentCount());
- Vector<JSValueRef, 16> arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
+ size_t argumentCount = exec->argumentCount();
+ Vector<JSValueRef, 16> arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
JSValueRef exception = 0;
JSValueRef result;
diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.h b/Source/JavaScriptCore/API/JSCallbackFunction.h
index 50630b550..885ef949d 100644
--- a/Source/JavaScriptCore/API/JSCallbackFunction.h
+++ b/Source/JavaScriptCore/API/JSCallbackFunction.h
@@ -33,31 +33,27 @@ namespace JSC {
class JSCallbackFunction : public InternalFunction {
protected:
- JSCallbackFunction(JSGlobalObject*, JSObjectCallAsFunctionCallback);
- void finishCreation(JSGlobalData&, const String& name);
+ JSCallbackFunction(JSGlobalObject*, Structure*, JSObjectCallAsFunctionCallback);
+ void finishCreation(VM&, const String& name);
public:
typedef InternalFunction Base;
- static JSCallbackFunction* create(ExecState* exec, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const String& name)
- {
- JSCallbackFunction* function = new (NotNull, allocateCell<JSCallbackFunction>(*exec->heap())) JSCallbackFunction(globalObject, callback);
- function->finishCreation(exec->globalData(), name);
- return function;
- }
+ static JSCallbackFunction* create(ExecState*, JSGlobalObject*, JSObjectCallAsFunctionCallback, const String& name);
static const ClassInfo s_info;
// InternalFunction mish-mashes constructor and function behavior -- we should
// refactor the code so this override isn't necessary
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
}
-private:
+protected:
static CallType getCallData(JSCell*, CallData&);
+private:
static EncodedJSValue JSC_HOST_CALL call(ExecState*);
JSObjectCallAsFunctionCallback m_callback;
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.cpp b/Source/JavaScriptCore/API/JSCallbackObject.cpp
index 76866feb0..7436e71f7 100644
--- a/Source/JavaScriptCore/API/JSCallbackObject.cpp
+++ b/Source/JavaScriptCore/API/JSCallbackObject.cpp
@@ -28,6 +28,7 @@
#include "JSCallbackObject.h"
#include "Heap.h"
+#include "Operations.h"
#include <wtf/text/StringHash.h>
namespace JSC {
@@ -40,30 +41,24 @@ template<> const bool JSCallbackObject<JSDestructibleObject>::needsDestruction =
template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false;
template<>
-JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure)
+JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(VM& vm, JSClassRef classRef, Structure* structure)
{
- JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject> >(globalData.heap)) JSCallbackObject(globalData, classRef, structure);
- callbackObject->finishCreation(globalData);
- globalData.heap.addFinalizer(callbackObject, destroy);
+ JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject> >(vm.heap)) JSCallbackObject(vm, classRef, structure);
+ callbackObject->finishCreation(vm);
+ vm.heap.addFinalizer(callbackObject, destroy);
return callbackObject;
}
template <>
-Structure* JSCallbackObject<JSDestructibleObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+Structure* JSCallbackObject<JSDestructibleObject>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
}
template <>
-Structure* JSCallbackObject<JSGlobalObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+Structure* JSCallbackObject<JSGlobalObject>::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
-}
-
-template <class Parent>
-void JSCallbackObject<Parent>::destroy(JSCell* cell)
-{
- static_cast<JSCallbackObject*>(cell)->JSCallbackObject::~JSCallbackObject();
+ return Structure::create(vm, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
}
void JSCallbackObjectData::finalize(Handle<Unknown> handle, void* context)
diff --git a/Source/JavaScriptCore/API/JSCallbackObject.h b/Source/JavaScriptCore/API/JSCallbackObject.h
index 3acf2ef10..16d8aa2c6 100644
--- a/Source/JavaScriptCore/API/JSCallbackObject.h
+++ b/Source/JavaScriptCore/API/JSCallbackObject.h
@@ -54,11 +54,11 @@ struct JSCallbackObjectData : WeakHandleOwner {
return m_privateProperties->getPrivateProperty(propertyName);
}
- void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value)
+ void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
{
if (!m_privateProperties)
m_privateProperties = adoptPtr(new JSPrivatePropertyMap);
- m_privateProperties->setPrivateProperty(globalData, owner, propertyName, value);
+ m_privateProperties->setPrivateProperty(vm, owner, propertyName, value);
}
void deletePrivateProperty(const Identifier& propertyName)
@@ -86,10 +86,10 @@ struct JSCallbackObjectData : WeakHandleOwner {
return location->value.get();
}
- void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value)
+ void setPrivateProperty(VM& vm, JSCell* owner, const Identifier& propertyName, JSValue value)
{
WriteBarrier<Unknown> empty;
- m_propertyMap.add(propertyName.impl(), empty).iterator->value.set(globalData, owner, value);
+ m_propertyMap.add(propertyName.impl(), empty).iterator->value.set(vm, owner, value);
}
void deletePrivateProperty(const Identifier& propertyName)
@@ -118,10 +118,10 @@ template <class Parent>
class JSCallbackObject : public Parent {
protected:
JSCallbackObject(ExecState*, Structure*, JSClassRef, void* data);
- JSCallbackObject(JSGlobalData&, JSClassRef, Structure*);
+ JSCallbackObject(VM&, JSClassRef, Structure*);
void finishCreation(ExecState*);
- void finishCreation(JSGlobalData&);
+ void finishCreation(VM&);
public:
typedef Parent Base;
@@ -133,10 +133,13 @@ public:
callbackObject->finishCreation(exec);
return callbackObject;
}
- static JSCallbackObject<Parent>* create(JSGlobalData&, JSClassRef, Structure*);
+ static JSCallbackObject<Parent>* create(VM&, JSClassRef, Structure*);
static const bool needsDestruction;
- static void destroy(JSCell*);
+ static void destroy(JSCell* cell)
+ {
+ static_cast<JSCallbackObject*>(cell)->JSCallbackObject::~JSCallbackObject();
+ }
void setPrivate(void* data);
void* getPrivate();
@@ -146,16 +149,16 @@ public:
JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
bool inherits(JSClassRef) const;
- static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue);
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
JSValue getPrivateProperty(const Identifier& propertyName) const
{
return m_callbackObjectData->getPrivateProperty(propertyName);
}
- void setPrivateProperty(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
+ void setPrivateProperty(VM& vm, const Identifier& propertyName, JSValue value)
{
- m_callbackObjectData->setPrivateProperty(globalData, this, propertyName, value);
+ m_callbackObjectData->setPrivateProperty(vm, this, propertyName, value);
}
void deletePrivateProperty(const Identifier& propertyName)
@@ -178,6 +181,7 @@ private:
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+ static void putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool shouldThrow);
static bool deleteProperty(JSCell*, ExecState*, PropertyName);
static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned);
diff --git a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
index 1a063e620..b92e3161e 100644
--- a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -51,7 +51,7 @@ inline JSCallbackObject<Parent>* JSCallbackObject<Parent>::asCallbackObject(JSVa
template <class Parent>
JSCallbackObject<Parent>::JSCallbackObject(ExecState* exec, Structure* structure, JSClassRef jsClass, void* data)
- : Parent(exec->globalData(), structure)
+ : Parent(exec->vm(), structure)
, m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data, jsClass)))
{
}
@@ -59,8 +59,8 @@ JSCallbackObject<Parent>::JSCallbackObject(ExecState* exec, Structure* structure
// Global object constructor.
// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
template <class Parent>
-JSCallbackObject<Parent>::JSCallbackObject(JSGlobalData& globalData, JSClassRef jsClass, Structure* structure)
- : Parent(globalData, structure)
+JSCallbackObject<Parent>::JSCallbackObject(VM& vm, JSClassRef jsClass, Structure* structure)
+ : Parent(vm, structure)
, m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass)))
{
}
@@ -68,18 +68,18 @@ JSCallbackObject<Parent>::JSCallbackObject(JSGlobalData& globalData, JSClassRef
template <class Parent>
void JSCallbackObject<Parent>::finishCreation(ExecState* exec)
{
- Base::finishCreation(exec->globalData());
+ Base::finishCreation(exec->vm());
ASSERT(Parent::inherits(&s_info));
init(exec);
}
// This is just for Global object, so we can assume that Base::finishCreation is JSGlobalObject::finishCreation.
template <class Parent>
-void JSCallbackObject<Parent>::finishCreation(JSGlobalData& globalData)
+void JSCallbackObject<Parent>::finishCreation(VM& vm)
{
ASSERT(Parent::inherits(&s_info));
ASSERT(Parent::isGlobalObject());
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
init(jsCast<JSGlobalObject*>(this)->globalExec());
}
@@ -216,7 +216,7 @@ template <class Parent>
bool JSCallbackObject<Parent>::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(object);
- PropertySlot slot;
+ PropertySlot slot(thisObject);
if (thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
// Ideally we should return an access descriptor, but returning a value descriptor is better than nothing.
JSValue value = slot.getValue(exec, propertyName);
@@ -283,7 +283,7 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
if (StaticFunctionEntry* entry = staticFunctions->get(name)) {
if (entry->attributes & kJSPropertyAttributeReadOnly)
return;
- thisObject->JSCallbackObject<Parent>::putDirect(exec->globalData(), propertyName, value); // put as override property
+ thisObject->JSCallbackObject<Parent>::putDirect(exec->vm(), propertyName, value); // put as override property
return;
}
}
@@ -294,6 +294,65 @@ void JSCallbackObject<Parent>::put(JSCell* cell, ExecState* exec, PropertyName p
}
template <class Parent>
+void JSCallbackObject<Parent>::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyIndex, JSValue value, bool shouldThrow)
+{
+ JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
+ JSContextRef ctx = toRef(exec);
+ JSObjectRef thisRef = toRef(thisObject);
+ RefPtr<OpaqueJSString> propertyNameRef;
+ JSValueRef valueRef = toRef(exec, value);
+ Identifier propertyName = Identifier(exec, String::number(propertyIndex));
+
+ for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(propertyName.impl());
+ JSValueRef exception = 0;
+ bool result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ }
+ if (exception)
+ throwError(exec, toJS(exec, exception));
+ if (result || exception)
+ return;
+ }
+
+ if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
+ if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
+ if (entry->attributes & kJSPropertyAttributeReadOnly)
+ return;
+ if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
+ if (!propertyNameRef)
+ propertyNameRef = OpaqueJSString::create(propertyName.impl());
+ JSValueRef exception = 0;
+ bool result;
+ {
+ APICallbackShim callbackShim(exec);
+ result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ }
+ if (exception)
+ throwError(exec, toJS(exec, exception));
+ if (result || exception)
+ return;
+ }
+ }
+ }
+
+ if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
+ if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
+ if (entry->attributes & kJSPropertyAttributeReadOnly)
+ return;
+ break;
+ }
+ }
+ }
+
+ return Parent::putByIndex(thisObject, exec, propertyIndex, value, shouldThrow);
+}
+
+template <class Parent>
bool JSCallbackObject<Parent>::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
{
JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(cell);
@@ -368,10 +427,11 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
- int argumentCount = static_cast<int>(exec->argumentCount());
- Vector<JSValueRef, 16> arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
+ size_t argumentCount = exec->argumentCount();
+ Vector<JSValueRef, 16> arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
JSValueRef exception = 0;
JSObject* result;
{
@@ -384,7 +444,7 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
}
}
- ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
+ RELEASE_ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
return JSValue::encode(JSValue());
}
@@ -434,10 +494,11 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
- int argumentCount = static_cast<int>(exec->argumentCount());
- Vector<JSValueRef, 16> arguments(argumentCount);
- for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, exec->argument(i));
+ size_t argumentCount = exec->argumentCount();
+ Vector<JSValueRef, 16> arguments;
+ arguments.reserveInitialCapacity(argumentCount);
+ for (size_t i = 0; i < argumentCount; ++i)
+ arguments.uncheckedAppend(toRef(exec, exec->argument(i)));
JSValueRef exception = 0;
JSValue result;
{
@@ -450,7 +511,7 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
}
}
- ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
+ RELEASE_ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
return JSValue::encode(JSValue());
}
@@ -508,10 +569,10 @@ void* JSCallbackObject<Parent>::getPrivate()
template <class Parent>
bool JSCallbackObject<Parent>::inherits(JSClassRef c) const
{
- for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
+ for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
if (jsClass == c)
return true;
-
+ }
return false;
}
@@ -566,7 +627,7 @@ JSValue JSCallbackObject<Parent>::staticFunctionGetter(ExecState* exec, JSValue
if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
JSObject* o = JSCallbackFunction::create(exec, thisObj->globalObject(), callAsFunction, name);
- thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes);
+ thisObj->putDirect(exec->vm(), propertyName, o, entry->attributes);
return o;
}
}
diff --git a/Source/JavaScriptCore/API/JSClassRef.cpp b/Source/JavaScriptCore/API/JSClassRef.cpp
index f30b02a2a..c77f63cf9 100644
--- a/Source/JavaScriptCore/API/JSClassRef.cpp
+++ b/Source/JavaScriptCore/API/JSClassRef.cpp
@@ -27,12 +27,13 @@
#include "JSClassRef.h"
#include "APICast.h"
+#include "Identifier.h"
+#include "InitializeThreading.h"
#include "JSCallbackObject.h"
+#include "JSGlobalObject.h"
#include "JSObjectRef.h"
-#include <runtime/InitializeThreading.h>
-#include <runtime/JSGlobalObject.h>
-#include <runtime/ObjectPrototype.h>
-#include <runtime/Identifier.h>
+#include "ObjectPrototype.h"
+#include "Operations.h"
#include <wtf/text/StringHash.h>
#include <wtf/unicode/UTF8.h>
@@ -126,7 +127,7 @@ PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientD
return adoptRef(new OpaqueJSClass(&definition, protoClass.get()));
}
-OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass* jsClass)
+OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass* jsClass)
: m_class(jsClass)
{
if (jsClass->m_staticValues) {
@@ -150,9 +151,9 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSC
OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec)
{
- OwnPtr<OpaqueJSClassContextData>& contextData = exec->globalData().opaqueJSClassData.add(this, nullptr).iterator->value;
+ OwnPtr<OpaqueJSClassContextData>& contextData = exec->lexicalGlobalObject()->opaqueJSClassData().add(this, nullptr).iterator->value;
if (!contextData)
- contextData = adoptPtr(new OpaqueJSClassContextData(exec->globalData(), this));
+ contextData = adoptPtr(new OpaqueJSClassContextData(exec->vm(), this));
return *contextData;
}
@@ -202,7 +203,7 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec)
JSObject* prototype = JSCallbackObject<JSDestructibleObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction
if (parentClass) {
if (JSObject* parentPrototype = parentClass->prototype(exec))
- prototype->setPrototype(exec->globalData(), parentPrototype);
+ prototype->setPrototype(exec->vm(), parentPrototype);
}
jsClassData.cachedPrototype = PassWeak<JSObject>(prototype);
diff --git a/Source/JavaScriptCore/API/JSClassRef.h b/Source/JavaScriptCore/API/JSClassRef.h
index 44d5d11b9..7bf18e758 100644
--- a/Source/JavaScriptCore/API/JSClassRef.h
+++ b/Source/JavaScriptCore/API/JSClassRef.h
@@ -26,10 +26,9 @@
#ifndef JSClassRef_h
#define JSClassRef_h
-#include "JSObjectRef.h"
+#include <JavaScriptCore/JSObjectRef.h>
#include "Weak.h"
-#include "JSObject.h"
#include "Protect.h"
#include <wtf/HashMap.h>
#include <wtf/text/WTFString.h>
@@ -69,14 +68,14 @@ struct OpaqueJSClass;
struct OpaqueJSClassContextData {
WTF_MAKE_NONCOPYABLE(OpaqueJSClassContextData); WTF_MAKE_FAST_ALLOCATED;
public:
- OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass*);
+ OpaqueJSClassContextData(JSC::VM&, OpaqueJSClass*);
// It is necessary to keep OpaqueJSClass alive because of the following rare scenario:
- // 1. A class is created and used, so its context data is stored in JSGlobalData hash map.
+ // 1. A class is created and used, so its context data is stored in VM hash map.
// 2. The class is released, and when all JS objects that use it are collected, OpaqueJSClass
// is deleted (that's the part prevented by this RefPtr).
// 3. Another class is created at the same address.
- // 4. When it is used, the old context data is found in JSGlobalData and used.
+ // 4. When it is used, the old context data is found in VM and used.
RefPtr<OpaqueJSClass> m_class;
OwnPtr<OpaqueJSClassStaticValuesTable> staticValues;
@@ -87,7 +86,7 @@ public:
struct OpaqueJSClass : public ThreadSafeRefCounted<OpaqueJSClass> {
static PassRefPtr<OpaqueJSClass> create(const JSClassDefinition*);
static PassRefPtr<OpaqueJSClass> createNoAutomaticPrototype(const JSClassDefinition*);
- ~OpaqueJSClass();
+ JS_EXPORT_PRIVATE ~OpaqueJSClass();
String className();
OpaqueJSClassStaticValuesTable* staticValues(JSC::ExecState*);
diff --git a/Source/JavaScriptCore/API/JSContext.h b/Source/JavaScriptCore/API/JSContext.h
new file mode 100644
index 000000000..ef3e51f17
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContext.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSContext_h
+#define JSContext_h
+
+#include <JavaScriptCore/JavaScript.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@class JSVirtualMachine, JSValue;
+
+// An instance of JSContext represents a JavaScript execution environment. All
+// JavaScript execution takes place within a context.
+// JSContext is also used to manage the life-cycle of objects within the
+// JavaScript virtual machine. Every instance of JSValue is associated with a
+// JSContext via a strong reference. The JSValue will keep the JSContext it
+// references alive so long as the JSValue remains alive. When all of the JSValues
+// that reference a particular JSContext have been deallocated the JSContext
+// will be deallocated unless it has been previously retained.
+
+NS_CLASS_AVAILABLE(10_9, NA)
+@interface JSContext : NSObject
+
+// Create a JSContext.
+- (id)init;
+// Create a JSContext in the specified virtual machine.
+- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;
+
+// Evaluate a string of JavaScript code.
+- (JSValue *)evaluateScript:(NSString *)script;
+
+// This method retrieves the global object of the JavaScript execution context.
+// Instances of JSContext originating from WebKit will return a reference to the
+// WindowProxy object.
+- (JSValue *)globalObject;
+
+// This method may be called from within an Objective-C block or method invoked
+// as a callback from JavaScript to retrieve the callback's context. Outside of
+// a callback from JavaScript this method will return nil.
++ (JSContext *)currentContext;
+// This method may be called from within an Objective-C block or method invoked
+// as a callback from JavaScript to retrieve the callback's this value. Outside
+// of a callback from JavaScript this method will return nil.
++ (JSValue *)currentThis;
+// This method may be called from within an Objective-C block or method invoked
+// as a callback from JavaScript to retrieve the callback's arguments, objects
+// in the returned array are instances of JSValue. Outside of a callback from
+// JavaScript this method will return nil.
++ (NSArray *)currentArguments;
+
+// The "exception" property may be used to throw an exception to JavaScript.
+// Before a callback is made from JavaScript to an Objective-C block or method,
+// the prior value of the exception property will be preserved and the property
+// will be set to nil. After the callback has completed the new value of the
+// exception property will be read, and prior value restored. If the new value
+// of exception is not nil, the callback will result in that value being thrown.
+// This property may also be used to check for uncaught exceptions arising from
+// API function calls (since the default behaviour of "exceptionHandler" is to
+// assign an uncaught exception to this property).
+// If a JSValue originating from a different JSVirtualMachine than this context
+// is assigned to this property, an Objective-C exception will be raised.
+@property(retain) JSValue *exception;
+
+// If a call to an API function results in an uncaught JavaScript exception, the
+// "exceptionHandler" block will be invoked. The default implementation for the
+// exception handler will store the exception to the exception property on
+// context. As a consequence the default behaviour is for unhandled exceptions
+// occurring within a callback from JavaScript to be rethrown upon return.
+// Setting this value to nil will result in all uncaught exceptions thrown from
+// the API being silently consumed.
+@property(copy) void(^exceptionHandler)(JSContext *context, JSValue *exception);
+
+// All instances of JSContext are associated with a single JSVirtualMachine. The
+// virtual machine provides an "object space" or set of execution resources.
+@property(readonly, retain) JSVirtualMachine *virtualMachine;
+
+@end
+
+// Instances of JSContext implement the following methods in order to enable
+// support for subscript access by key and index, for example:
+//
+// JSContext *context;
+// JSValue *v = context[@"X"]; // Get value for "X" from the global object.
+// context[@"Y"] = v; // Assign 'v' to "Y" on the global object.
+//
+// An object key passed as a subscript will be converted to a JavaScript value,
+// and then the value converted to a string used to resolve a property of the
+// global object.
+@interface JSContext(SubscriptSupport)
+
+- (JSValue *)objectForKeyedSubscript:(id)key;
+- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
+
+@end
+
+// These functions are for bridging between the C API and the Objective-C API.
+@interface JSContext(JSContextRefSupport)
+// Creates a JSContext, wrapping its C API counterpart.
++ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)jsGlobalContextRef;
+// Returns the C API counterpart wrapped by a JSContext.
+- (JSGlobalContextRef)JSGlobalContextRef;
+@end
+
+#endif
+
+#endif // JSContext_h
diff --git a/Source/JavaScriptCore/API/JSContext.mm b/Source/JavaScriptCore/API/JSContext.mm
new file mode 100644
index 000000000..58754b38c
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContext.mm
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#import "APICast.h"
+#import "APIShims.h"
+#import "JSContextInternal.h"
+#import "JSGlobalObject.h"
+#import "JSValueInternal.h"
+#import "JSVirtualMachineInternal.h"
+#import "JSWrapperMap.h"
+#import "JavaScriptCore.h"
+#import "ObjcRuntimeExtras.h"
+#import "Operations.h"
+#import "StrongInlines.h"
+#import <wtf/HashSet.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@implementation JSContext {
+ JSVirtualMachine *m_virtualMachine;
+ JSGlobalContextRef m_context;
+ JSWrapperMap *m_wrapperMap;
+ JSC::Strong<JSC::JSObject> m_exception;
+}
+
+@synthesize exceptionHandler;
+
+- (JSGlobalContextRef)JSGlobalContextRef
+{
+ return m_context;
+}
+
+- (id)init
+{
+ return [self initWithVirtualMachine:[[[JSVirtualMachine alloc] init] autorelease]];
+}
+
+- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ m_virtualMachine = [virtualMachine retain];
+ m_context = JSGlobalContextCreateInGroup(getGroupFromVirtualMachine(virtualMachine), 0);
+ m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self];
+
+ self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
+ context.exception = exceptionValue;
+ };
+
+ [m_virtualMachine addContext:self forGlobalContextRef:m_context];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [m_wrapperMap release];
+ JSGlobalContextRelease(m_context);
+ [m_virtualMachine release];
+ [self.exceptionHandler release];
+ [super dealloc];
+}
+
+- (JSValue *)evaluateScript:(NSString *)script
+{
+ JSValueRef exceptionValue = 0;
+ JSStringRef scriptJS = JSStringCreateWithCFString((CFStringRef)script);
+ JSValueRef result = JSEvaluateScript(m_context, scriptJS, 0, 0, 0, &exceptionValue);
+ JSStringRelease(scriptJS);
+
+ if (exceptionValue)
+ return [self valueFromNotifyException:exceptionValue];
+
+ return [JSValue valueWithJSValueRef:result inContext:self];
+}
+
+- (void)setException:(JSValue *)value
+{
+ if (value)
+ m_exception.set(toJS(m_context)->vm(), toJS(JSValueToObject(m_context, valueInternalValue(value), 0)));
+ else
+ m_exception.clear();
+}
+
+- (JSValue *)exception
+{
+ if (!m_exception)
+ return nil;
+ return [JSValue valueWithJSValueRef:toRef(m_exception.get()) inContext:self];
+}
+
+- (JSWrapperMap *)wrapperMap
+{
+ return m_wrapperMap;
+}
+
+- (JSValue *)globalObject
+{
+ return [JSValue valueWithJSValueRef:JSContextGetGlobalObject(m_context) inContext:self];
+}
+
++ (JSContext *)currentContext
+{
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
+ return entry ? entry->context : nil;
+}
+
++ (JSValue *)currentThis
+{
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
+
+ if (!entry->currentThis)
+ entry->currentThis = [[JSValue alloc] initWithValue:entry->thisValue inContext:[JSContext currentContext]];
+
+ return entry->currentThis;
+}
+
++ (NSArray *)currentArguments
+{
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
+
+ if (!entry->currentArguments) {
+ JSContext *context = [JSContext currentContext];
+ size_t count = entry->argumentCount;
+ JSValue * argumentArray[count];
+ for (size_t i =0; i < count; ++i)
+ argumentArray[i] = [JSValue valueWithJSValueRef:entry->arguments[i] inContext:context];
+ entry->currentArguments = [[NSArray alloc] initWithObjects:argumentArray count:count];
+ }
+
+ return entry->currentArguments;
+}
+
+- (JSVirtualMachine *)virtualMachine
+{
+ return m_virtualMachine;
+}
+
+@end
+
+@implementation JSContext(SubscriptSupport)
+
+- (JSValue *)objectForKeyedSubscript:(id)key
+{
+ return [self globalObject][key];
+}
+
+- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key
+{
+ [self globalObject][key] = object;
+}
+
+@end
+
+@implementation JSContext(Internal)
+
+- (id)initWithGlobalContextRef:(JSGlobalContextRef)context
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ JSC::JSGlobalObject* globalObject = toJS(context)->lexicalGlobalObject();
+ m_virtualMachine = [[JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&globalObject->vm())] retain];
+ ASSERT(m_virtualMachine);
+ m_context = JSGlobalContextRetain(context);
+ m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self];
+
+ self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
+ context.exception = exceptionValue;
+ };
+
+ [m_virtualMachine addContext:self forGlobalContextRef:m_context];
+
+ return self;
+}
+
+- (void)notifyException:(JSValueRef)exceptionValue
+{
+ self.exceptionHandler(self, [JSValue valueWithJSValueRef:exceptionValue inContext:self]);
+}
+
+- (JSValue *)valueFromNotifyException:(JSValueRef)exceptionValue
+{
+ [self notifyException:exceptionValue];
+ return [JSValue valueWithUndefinedInContext:self];
+}
+
+- (BOOL)boolFromNotifyException:(JSValueRef)exceptionValue
+{
+ [self notifyException:exceptionValue];
+ return NO;
+}
+
+- (void)beginCallbackWithData:(CallbackData *)callbackData thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments
+{
+ WTFThreadData& threadData = wtfThreadData();
+ [self retain];
+ CallbackData *prevStack = (CallbackData *)threadData.m_apiData;
+ *callbackData = (CallbackData){ prevStack, self, [self.exception retain], thisValue, nil, argumentCount, arguments, nil };
+ threadData.m_apiData = callbackData;
+ self.exception = nil;
+}
+
+- (void)endCallbackWithData:(CallbackData *)callbackData
+{
+ WTFThreadData& threadData = wtfThreadData();
+ self.exception = callbackData->preservedException;
+ [callbackData->preservedException release];
+ [callbackData->currentThis release];
+ [callbackData->currentArguments release];
+ threadData.m_apiData = callbackData->next;
+ [self release];
+}
+
+- (JSValue *)wrapperForObjCObject:(id)object
+{
+ // Lock access to m_wrapperMap
+ JSC::JSLockHolder lock(toJS(m_context));
+ return [m_wrapperMap jsWrapperForObject:object];
+}
+
+- (JSValue *)wrapperForJSObject:(JSValueRef)value
+{
+ JSC::JSLockHolder lock(toJS(m_context));
+ return [m_wrapperMap objcWrapperForJSValueRef:value];
+}
+
++ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext
+{
+ JSVirtualMachine *virtualMachine = [JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&toJS(globalContext)->vm())];
+ JSContext *context = [virtualMachine contextForGlobalContextRef:globalContext];
+ if (!context)
+ context = [[[JSContext alloc] initWithGlobalContextRef:globalContext] autorelease];
+ return context;
+}
+
+@end
+
+WeakContextRef::WeakContextRef(JSContext *context)
+{
+ objc_initWeak(&m_weakContext, context);
+}
+
+WeakContextRef::~WeakContextRef()
+{
+ objc_destroyWeak(&m_weakContext);
+}
+
+JSContext * WeakContextRef::get()
+{
+ return objc_loadWeak(&m_weakContext);
+}
+
+void WeakContextRef::set(JSContext *context)
+{
+ objc_storeWeak(&m_weakContext, context);
+}
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSContextInternal.h b/Source/JavaScriptCore/API/JSContextInternal.h
new file mode 100644
index 000000000..d08e97d93
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSContextInternal.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSContextInternal_h
+#define JSContextInternal_h
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+#import <JavaScriptCore/JSContext.h>
+
+struct CallbackData {
+ CallbackData *next;
+ JSContext *context;
+ JSValue *preservedException;
+ JSValueRef thisValue;
+ JSValue *currentThis;
+ size_t argumentCount;
+ const JSValueRef *arguments;
+ NSArray *currentArguments;
+};
+
+class WeakContextRef {
+public:
+ WeakContextRef(JSContext * = nil);
+ ~WeakContextRef();
+
+ JSContext * get();
+ void set(JSContext *);
+
+private:
+ JSContext *m_weakContext;
+};
+
+@class JSWrapperMap;
+
+@interface JSContext(Internal)
+
+- (id)initWithGlobalContextRef:(JSGlobalContextRef)context;
+
+- (void)notifyException:(JSValueRef)exception;
+- (JSValue *)valueFromNotifyException:(JSValueRef)exception;
+- (BOOL)boolFromNotifyException:(JSValueRef)exception;
+
+- (void)beginCallbackWithData:(CallbackData *)callbackData thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments;
+- (void)endCallbackWithData:(CallbackData *)callbackData;
+
+- (JSValue *)wrapperForObjCObject:(id)object;
+- (JSValue *)wrapperForJSObject:(JSValueRef)value;
+
+@property (readonly, retain) JSWrapperMap *wrapperMap;
+
+@end
+
+#endif
+
+#endif // JSContextInternal_h
diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp
index 162c825aa..3869e87bf 100644
--- a/Source/JavaScriptCore/API/JSContextRef.cpp
+++ b/Source/JavaScriptCore/API/JSContextRef.cpp
@@ -35,6 +35,8 @@
#include "JSClassRef.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
+#include "Operations.h"
+#include "SourceProvider.h"
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringHash.h>
@@ -54,7 +56,7 @@ using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
initializeThreading();
- return toRef(JSGlobalData::createContextGroup().leakRef());
+ return toRef(VM::createContextGroup().leakRef());
}
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -65,7 +67,44 @@ JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
void JSContextGroupRelease(JSContextGroupRef group)
{
- toJS(group)->deref();
+ IdentifierTable* savedIdentifierTable;
+ VM& vm = *toJS(group);
+
+ {
+ JSLockHolder lock(vm);
+ savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(vm.identifierTable);
+ vm.deref();
+ }
+
+ wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
+}
+
+static bool internalScriptTimeoutCallback(ExecState* exec, void* callbackPtr, void* callbackData)
+{
+ JSShouldTerminateCallback callback = reinterpret_cast<JSShouldTerminateCallback>(callbackPtr);
+ JSContextRef contextRef = toRef(exec);
+ ASSERT(callback);
+ return callback(contextRef, callbackData);
+}
+
+void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef group, double limit, JSShouldTerminateCallback callback, void* callbackData)
+{
+ VM& vm = *toJS(group);
+ APIEntryShim entryShim(&vm);
+ Watchdog& watchdog = vm.watchdog;
+ if (callback) {
+ void* callbackPtr = reinterpret_cast<void*>(callback);
+ watchdog.setTimeLimit(vm, limit, internalScriptTimeoutCallback, callbackPtr, callbackData);
+ } else
+ watchdog.setTimeLimit(vm, limit);
+}
+
+void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef group)
+{
+ VM& vm = *toJS(group);
+ APIEntryShim entryShim(&vm);
+ Watchdog& watchdog = vm.watchdog;
+ watchdog.setTimeLimit(vm, std::numeric_limits<double>::infinity());
}
// From the API's perspective, a global context remains alive iff it has been JSGlobalContextRetained.
@@ -75,10 +114,10 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
initializeThreading();
#if OS(DARWIN)
- // If the application was linked before JSGlobalContextCreate was changed to use a unique JSGlobalData,
+ // If the application was linked before JSGlobalContextCreate was changed to use a unique VM,
// we use a shared one for backwards compatibility.
if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) {
- return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
+ return JSGlobalContextCreateInGroup(toRef(&VM::sharedInstance()), globalObjectClass);
}
#endif // OS(DARWIN)
@@ -89,22 +128,22 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
{
initializeThreading();
- RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createContextGroup();
+ RefPtr<VM> vm = group ? PassRefPtr<VM>(toJS(group)) : VM::createContextGroup();
- APIEntryShim entryShim(globalData.get(), false);
- globalData->makeUsableFromMultipleThreads();
+ APIEntryShim entryShim(vm.get(), false);
+ vm->makeUsableFromMultipleThreads();
if (!globalObjectClass) {
- JSGlobalObject* globalObject = JSGlobalObject::create(*globalData, JSGlobalObject::createStructure(*globalData, jsNull()));
+ JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
- JSGlobalObject* globalObject = JSCallbackObject<JSGlobalObject>::create(*globalData, globalObjectClass, JSCallbackObject<JSGlobalObject>::createStructure(*globalData, 0, jsNull()));
+ JSGlobalObject* globalObject = JSCallbackObject<JSGlobalObject>::create(*vm, globalObjectClass, JSCallbackObject<JSGlobalObject>::createStructure(*vm, 0, jsNull()));
ExecState* exec = globalObject->globalExec();
JSValue prototype = globalObjectClass->prototype(exec);
if (!prototype)
prototype = jsNull();
- globalObject->resetPrototype(*globalData, prototype);
+ globalObject->resetPrototype(*vm, prototype);
return JSGlobalContextRetain(toGlobalRef(exec));
}
@@ -113,9 +152,9 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
gcProtect(exec->dynamicGlobalObject());
- globalData.ref();
+ vm.ref();
return ctx;
}
@@ -126,13 +165,13 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx)
{
JSLockHolder lock(exec);
- JSGlobalData& globalData = exec->globalData();
- savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable);
+ VM& vm = exec->vm();
+ savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(vm.identifierTable);
bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject());
if (protectCountIsZero)
- globalData.heap.reportAbandonedObjectGraph();
- globalData.deref();
+ vm.heap.reportAbandonedObjectGraph();
+ vm.deref();
}
wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
@@ -140,6 +179,10 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx)
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -149,12 +192,20 @@ JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
JSContextGroupRef JSContextGetGroup(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
- return toRef(&exec->globalData());
+ return toRef(&exec->vm());
}
JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -163,53 +214,46 @@ JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx)
JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
JSLockHolder lock(exec);
-
- unsigned count = 0;
StringBuilder builder;
- CallFrame* callFrame = exec;
- String functionName;
- if (exec->callee()) {
- if (asObject(exec->callee())->inherits(&InternalFunction::s_info)) {
- functionName = asInternalFunction(exec->callee())->name(exec);
- builder.appendLiteral("#0 ");
- builder.append(functionName);
- builder.appendLiteral("() ");
- count++;
- }
- }
- while (true) {
- ASSERT(callFrame);
- int signedLineNumber;
- intptr_t sourceID;
- String urlString;
- JSValue function;
+ Vector<StackFrame> stackTrace;
+ Interpreter::getStackTrace(&exec->vm(), stackTrace, maxStackSize);
- exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function);
-
- if (function)
- functionName = jsCast<JSFunction*>(function)->name(exec);
+ for (size_t i = 0; i < stackTrace.size(); i++) {
+ String urlString;
+ String functionName;
+ StackFrame& frame = stackTrace[i];
+ JSValue function = frame.callee.get();
+ if (frame.callee)
+ functionName = frame.friendlyFunctionName(exec);
else {
// Caller is unknown, but if frame is empty we should still add the frame, because
// something called us, and gave us arguments.
- if (count)
+ if (i)
break;
}
- unsigned lineNumber = signedLineNumber >= 0 ? signedLineNumber : 0;
+ unsigned lineNumber;
+ unsigned column;
+ frame.computeLineAndColumn(lineNumber, column);
if (!builder.isEmpty())
builder.append('\n');
builder.append('#');
- builder.appendNumber(count);
+ builder.appendNumber(i);
builder.append(' ');
builder.append(functionName);
builder.appendLiteral("() at ");
builder.append(urlString);
- builder.append(':');
- builder.appendNumber(lineNumber);
- if (!function || ++count == maxStackSize)
+ if (frame.codeType != StackFrameNativeCode) {
+ builder.append(':');
+ builder.appendNumber(lineNumber);
+ }
+ if (!function)
break;
- callFrame = callFrame->callerFrame();
}
return OpaqueJSString::create(builder.toString()).leakRef();
}
diff --git a/Source/JavaScriptCore/API/JSContextRefPrivate.h b/Source/JavaScriptCore/API/JSContextRefPrivate.h
index 4f77aeada..8d7684ac0 100644
--- a/Source/JavaScriptCore/API/JSContextRefPrivate.h
+++ b/Source/JavaScriptCore/API/JSContextRefPrivate.h
@@ -55,6 +55,54 @@ JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx);
*/
JS_EXPORT JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+
+/*!
+@typedef JSShouldTerminateCallback
+@abstract The callback invoked when script execution has exceeded the allowed
+ time limit previously specified via JSContextGroupSetExecutionTimeLimit.
+@param ctx The execution context to use.
+@param context User specified context data previously passed to
+ JSContextGroupSetExecutionTimeLimit.
+@discussion If you named your function Callback, you would declare it like this:
+
+ bool Callback(JSContextRef ctx, void* context);
+
+ If you return true, the timed out script will terminate.
+ If you return false, the script will run for another period of the allowed
+ time limit specified via JSContextGroupSetExecutionTimeLimit.
+
+ Within this callback function, you may call JSContextGroupSetExecutionTimeLimit
+ to set a new time limit, or JSContextGroupClearExecutionTimeLimit to cancel the
+ timeout.
+*/
+typedef bool
+(*JSShouldTerminateCallback) (JSContextRef ctx, void* context);
+
+/*!
+@function
+@abstract Sets the script execution time limit.
+@param group The JavaScript context group that this time limit applies to.
+@param limit The time limit of allowed script execution time in seconds.
+@param callback The callback function that will be invoked when the time limit
+ has been reached. This will give you a chance to decide if you want to
+ terminate the script or not. If you pass a NULL callback, the script will be
+ terminated unconditionally when the time limit has been reached.
+@param context User data that you can provide to be passed back to you
+ in your callback.
+
+ In order to guarantee that the execution time limit will take effect, you will
+ need to call JSContextGroupSetExecutionTimeLimit before you start executing
+ any scripts.
+*/
+JS_EXPORT void JSContextGroupSetExecutionTimeLimit(JSContextGroupRef, double limit, JSShouldTerminateCallback, void* context) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+
+/*!
+@function
+@abstract Clears the script execution time limit.
+@param group The JavaScript context group that the time limit is cleared on.
+*/
+JS_EXPORT void JSContextGroupClearExecutionTimeLimit(JSContextGroupRef) AVAILABLE_IN_WEBKIT_VERSION_4_0;
+
#ifdef __cplusplus
}
#endif
diff --git a/Source/JavaScriptCore/API/JSExport.h b/Source/JavaScriptCore/API/JSExport.h
new file mode 100644
index 000000000..96e9fec35
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSExport.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+// When a JavaScript value is created from an instance of an Objective-C class
+// for which no copying conversion is specified a JavaScript wrapper object will
+// be created.
+//
+// In JavaScript inheritance is supported via a chain of prototype objects, and
+// for each Objective-C class (and per JSContext) an object appropriate for use
+// as a prototype will be provided. For the class NSObject the prototype object
+// will be the JavaScript context's Object Prototype. For all other Objective-C
+// classes a Prototype object will be created. The Prototype object for a given
+// Objective-C class will have its internal [Prototype] property set to point to
+// the Prototype object of the Objective-C class's superclass. As such the
+// prototype chain for a JavaScript wrapper object will reflect the wrapped
+// Objective-C type's inheritance hierarchy.
+//
+// In addition to the Prototype object a JavaScript Constructor object will also
+// be produced for each Objective-C class. The Constructor object has a property
+// named 'prototype' that references the Prototype object, and the Prototype
+// object has a property named 'constructor' that references the Constructor.
+// The Constructor object is not callable.
+//
+// By default no methods or properties of the Objective-C class will be exposed
+// to JavaScript, however methods and properties may explicitly be exported.
+// For each protocol that a class conforms to, if the protocol incorporates the
+// protocol JSExport, then the protocol will be interpreted as a list of methods
+// and properties to be exported to JavaScript.
+//
+// For each instance method being exported, a corresponding JavaScript function
+// will be assigned as a property of the Prototype object, for each Objective-C
+// property being exported a JavaScript accessor property will be created on the
+// Prototype, and for each class method exported a JavaScript function will be
+// created on the Constructor object. For example:
+//
+// @protocol MyClassJavaScriptMethods <JSExport>
+// - (void)foo;
+// @end
+//
+// @interface MyClass : NSObject <MyClassJavaScriptMethods>
+// - (void)foo;
+// - (void)bar;
+// @end
+//
+// Data properties that are created on the prototype or constructor objects have
+// the attributes: writable:true, enumerable:false, configurable:true. Accessor
+// properties have the attributes: enumerable:false and configurable:true.
+//
+// If an instance of MyClass is converted to a JavaScript value, the resulting
+// wrapper object will (via its prototype) export the method "foo" to JavaScript,
+// since the class conforms to the MyClassJavaScriptMethods protocol, and this
+// protocol incorporates JSExport. "bar" will not be exported.
+//
+// Properties, arguments, and return values of the following types are
+// supported:
+//
+// Primitive numbers: signed values of up to 32-bits are converted in a manner
+// consistent with valueWithInt32/toInt32, unsigned values of up to 32-bits
+// are converted in a manner consistent with valueWithUInt32/toUInt32, all
+// other numeric values are converted consistently with valueWithDouble/
+// toDouble.
+// BOOL: values are converted consistently with valueWithBool/toBool.
+// id: values are converted consistently with valueWithObject/toObject.
+// <Objective-C Class>: - where the type is a pointer to a specified Objective-C
+// class, conversion is consistent with valueWithObjectOfClass/toObject.
+// struct types: C struct types are supported, where JSValue provides support
+// for the given type. Support is built in for CGPoint, NSRange, CGRect, and
+// CGSize.
+// block types: In addition to support provided by valueWithObject/toObject for
+// block types, if a JavaScript Function is passed as an argument, where the
+// type required is a block with a void return value (and where the block's
+// arguments are all of supported types), then a special adaptor block
+// will be created, allowing the JavaScript function to be used in the place
+// of a block.
+//
+// For any interface that conforms to JSExport the normal copying conversion for
+// built in types will be inhibited - so, for example, if an instance that
+// derives from NSString but conforms to JSExport is passed to valueWithObject:
+// then a wrapper object for the Objective-C object will be returned rather than
+// a JavaScript string primitive.
+@protocol JSExport
+@end
+
+// When a selector that takes one or more arguments is converted to a JavaScript
+// property name, by default a property name will be generated by performing the
+// following conversion:
+// - All colons are removed from the selector
+// - Any lowercase letter that had followed a colon will be capitalized.
+// Under the default conversion a selector "doFoo:withBar:" will be exported as
+// "doFooWithBar". The default conversion may be overriden using the JSExportAs
+// macro, for example to export a method "doFoo:withBar:" as "doFoo":
+//
+// @protocol MyClassJavaScriptMethods <JSExport>
+// JSExportAs(doFoo,
+// - (void)doFoo:(id)foo withBar:(id)bar
+// );
+// @end
+//
+// Note that the JSExport macro may only be applied to a selector that takes one
+// or more argument.
+#define JSExportAs(PropertyName, Selector) \
+ @optional Selector __JS_EXPORT_AS__##PropertyName:(id)argument; @required Selector
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSManagedValue.h b/Source/JavaScriptCore/API/JSManagedValue.h
new file mode 100644
index 000000000..5ff3f83cb
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSManagedValue.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSManagedValue_h
+#define JSManagedValue_h
+
+#import <JavaScriptCore/JSBase.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@class JSValue;
+@class JSContext;
+
+// JSManagedValue represents a "conditionally retained" JSValue.
+// "Conditionally retained" means that as long as either the JSManagedValue
+// JavaScript value is reachable through the JavaScript object graph
+// or the JSManagedValue object is reachable through the external Objective-C
+// object graph as reported to the JSVirtualMachine using
+// addManagedReference:withOwner:, the corresponding JavaScript value will
+// be retained. However, if neither of these conditions are true, the
+// corresponding JSValue will be released and set to nil.
+//
+// The primary use case for JSManagedValue is for safely referencing JSValues
+// from the Objective-C heap. It is incorrect to store a JSValue into an
+// Objective-C heap object, as this can very easily create a reference cycle,
+// keeping the entire JSContext alive.
+NS_CLASS_AVAILABLE(10_9, NA)
+@interface JSManagedValue : NSObject
+
+// Convenience method for creating JSManagedValues from JSValues.
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value;
+
+// Create a JSManagedValue.
+- (id)initWithValue:(JSValue *)value;
+
+// Get the JSValue to which this JSManagedValue refers. If the JavaScript value has been collected,
+// this method returns nil.
+- (JSValue *)value;
+
+@end
+
+#endif // JSC_OBJC_API_ENABLED
+
+#endif // JSManagedValue_h
diff --git a/Source/JavaScriptCore/API/JSManagedValue.mm b/Source/JavaScriptCore/API/JSManagedValue.mm
new file mode 100644
index 000000000..f336ba662
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSManagedValue.mm
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#import "config.h"
+#import "JSManagedValue.h"
+
+#if JSC_OBJC_API_ENABLED
+
+#import "APICast.h"
+#import "Heap.h"
+#import "JSCJSValueInlines.h"
+#import "JSContextInternal.h"
+#import "JSValueInternal.h"
+#import "Weak.h"
+#import "WeakHandleOwner.h"
+#import "ObjcRuntimeExtras.h"
+
+class JSManagedValueHandleOwner : public JSC::WeakHandleOwner {
+public:
+ virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
+ virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
+};
+
+static JSManagedValueHandleOwner* managedValueHandleOwner()
+{
+ DEFINE_STATIC_LOCAL(JSManagedValueHandleOwner, jsManagedValueHandleOwner, ());
+ return &jsManagedValueHandleOwner;
+}
+
+@implementation JSManagedValue {
+ JSC::Weak<JSC::JSObject> m_value;
+}
+
++ (JSManagedValue *)managedValueWithValue:(JSValue *)value
+{
+ return [[[self alloc] initWithValue:value] autorelease];
+}
+
+- (id)init
+{
+ return [self initWithValue:nil];
+}
+
+- (id)initWithValue:(JSValue *)value
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ if (!value || !JSValueIsObject([value.context JSGlobalContextRef], [value JSValueRef])) {
+ JSC::Weak<JSC::JSObject> weak;
+ m_value.swap(weak);
+ } else {
+ JSC::JSObject* object = toJS(const_cast<OpaqueJSValue*>([value JSValueRef]));
+ JSC::Weak<JSC::JSObject> weak(object, managedValueHandleOwner(), self);
+ m_value.swap(weak);
+ }
+
+ return self;
+}
+
+- (JSValue *)value
+{
+ if (!m_value)
+ return nil;
+ JSC::JSObject* object = m_value.get();
+ JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(object->structure()->globalObject()->globalExec())];
+ return [JSValue valueWithJSValueRef:toRef(object) inContext:context];
+}
+
+- (void)disconnectValue
+{
+ m_value.clear();
+}
+
+@end
+
+@interface JSManagedValue (PrivateMethods)
+- (void)disconnectValue;
+@end
+
+bool JSManagedValueHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor& visitor)
+{
+ JSManagedValue *managedValue = static_cast<JSManagedValue *>(context);
+ return visitor.containsOpaqueRoot(managedValue);
+}
+
+void JSManagedValueHandleOwner::finalize(JSC::Handle<JSC::Unknown>, void* context)
+{
+ JSManagedValue *managedValue = static_cast<JSManagedValue *>(context);
+ [managedValue disconnectValue];
+}
+
+#endif // JSC_OBJC_API_ENABLED
diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp
index c62efc60d..5ba446513 100644
--- a/Source/JavaScriptCore/API/JSObjectRef.cpp
+++ b/Source/JavaScriptCore/API/JSObjectRef.cpp
@@ -37,6 +37,7 @@
#include "FunctionConstructor.h"
#include "Identifier.h"
#include "InitializeThreading.h"
+#include "JSAPIWrapperObject.h"
#include "JSArray.h"
#include "JSCallbackConstructor.h"
#include "JSCallbackFunction.h"
@@ -48,7 +49,9 @@
#include "JSRetainPtr.h"
#include "JSString.h"
#include "JSValueRef.h"
+#include "ObjectConstructor.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
#include "RegExpConstructor.h"
@@ -77,6 +80,10 @@ void JSClassRelease(JSClassRef jsClass)
JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -85,13 +92,17 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
JSCallbackObject<JSDestructibleObject>* object = JSCallbackObject<JSDestructibleObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data);
if (JSObject* prototype = jsClass->prototype(exec))
- object->setPrototype(exec->globalData(), prototype);
+ object->setPrototype(exec->vm(), prototype);
return toRef(object);
}
JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
return toRef(JSCallbackFunction::create(exec, exec->lexicalGlobalObject(), callAsFunction, name ? name->string() : ASCIILiteral("anonymous")));
@@ -99,6 +110,10 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -107,16 +122,20 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
JSCallbackConstructor* constructor = JSCallbackConstructor::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor);
- constructor->putDirect(exec->globalData(), exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
+ constructor->putDirect(exec->vm(), exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
return toRef(constructor);
}
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
+ Identifier nameID = name ? name->identifier(&exec->vm()) : Identifier(exec, "anonymous");
MarkedArgumentBuffer args;
for (unsigned i = 0; i < parameterCount; i++)
@@ -135,6 +154,10 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -160,6 +183,10 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -180,6 +207,10 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -199,6 +230,10 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -219,6 +254,10 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -228,33 +267,45 @@ JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
- jsObject->setPrototypeWithCycleCheck(exec->globalData(), jsValue.isObject() ? jsValue : jsNull());
+ jsObject->setPrototypeWithCycleCheck(exec->vm(), jsValue.isObject() ? jsValue : jsNull());
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
- return jsObject->hasProperty(exec, propertyName->identifier(&exec->globalData()));
+ return jsObject->hasProperty(exec, propertyName->identifier(&exec->vm()));
}
JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
- JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
+ JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->vm()));
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
@@ -265,11 +316,15 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
- Identifier name(propertyName->identifier(&exec->globalData()));
+ Identifier name(propertyName->identifier(&exec->vm()));
JSValue jsValue = toJS(exec, value);
if (attributes && !jsObject->hasProperty(exec, name))
@@ -288,6 +343,10 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -305,6 +364,10 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -321,12 +384,16 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
- bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->globalData()));
+ bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->vm()));
if (exec->hadException()) {
if (exception)
*exception = toRef(exec, exec->exception());
@@ -337,19 +404,23 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
void* JSObjectGetPrivate(JSObjectRef object)
{
- JSObject* jsObject = toJS(object);
+ JSObject* jsObject = uncheckedToJS(object);
if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
return jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate();
if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
return jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivate();
+#if JSC_OBJC_API_ENABLED
+ if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->getPrivate();
+#endif
return 0;
}
bool JSObjectSetPrivate(JSObjectRef object, void* data)
{
- JSObject* jsObject = toJS(object);
+ JSObject* jsObject = uncheckedToJS(object);
if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data);
@@ -359,6 +430,12 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data)
jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivate(data);
return true;
}
+#if JSC_OBJC_API_ENABLED
+ if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) {
+ jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->setPrivate(data);
+ return true;
+ }
+#endif
return false;
}
@@ -369,11 +446,15 @@ JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSSt
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
JSValue result;
- Identifier name(propertyName->identifier(&exec->globalData()));
+ Identifier name(propertyName->identifier(&exec->vm()));
if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name);
else if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name);
+#if JSC_OBJC_API_ENABLED
+ else if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ result = jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->getPrivateProperty(name);
+#endif
return toRef(exec, result);
}
@@ -383,15 +464,21 @@ bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRe
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = value ? toJS(exec, value) : JSValue();
- Identifier name(propertyName->identifier(&exec->globalData()));
+ Identifier name(propertyName->identifier(&exec->vm()));
if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
- jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);
+ jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue);
return true;
}
if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
- jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);
+ jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue);
return true;
}
+#if JSC_OBJC_API_ENABLED
+ if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) {
+ jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue);
+ return true;
+ }
+#endif
return false;
}
@@ -400,7 +487,7 @@ bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStrin
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
- Identifier name(propertyName->identifier(&exec->globalData()));
+ Identifier name(propertyName->identifier(&exec->vm()));
if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name);
return true;
@@ -409,11 +496,19 @@ bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStrin
jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->deletePrivateProperty(name);
return true;
}
+#if JSC_OBJC_API_ENABLED
+ if (jsObject->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info)) {
+ jsCast<JSCallbackObject<JSAPIWrapperObject>*>(jsObject)->deletePrivateProperty(name);
+ return true;
+ }
+#endif
return false;
}
bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
{
+ if (!object)
+ return false;
CallData callData;
JSCell* cell = toJS(object);
return cell->methodTable()->getCallData(cell, callData) != CallTypeNone;
@@ -424,6 +519,9 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
+ if (!object)
+ return 0;
+
JSObject* jsObject = toJS(object);
JSObject* jsThisObject = toJS(thisObject);
@@ -453,6 +551,8 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
{
+ if (!object)
+ return false;
JSObject* jsObject = toJS(object);
ConstructData constructData;
return jsObject->methodTable()->getConstructData(jsObject, constructData) != ConstructTypeNone;
@@ -463,6 +563,9 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
+ if (!object)
+ return 0;
+
JSObject* jsObject = toJS(object);
ConstructData constructData;
@@ -486,33 +589,37 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
struct OpaqueJSPropertyNameArray {
WTF_MAKE_FAST_ALLOCATED;
public:
- OpaqueJSPropertyNameArray(JSGlobalData* globalData)
+ OpaqueJSPropertyNameArray(VM* vm)
: refCount(0)
- , globalData(globalData)
+ , vm(vm)
{
}
unsigned refCount;
- JSGlobalData* globalData;
+ VM* vm;
Vector<JSRetainPtr<JSStringRef> > array;
};
JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
JSObject* jsObject = toJS(object);
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
- JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData);
- PropertyNameArray array(globalData);
+ JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(vm);
+ PropertyNameArray array(vm);
jsObject->methodTable()->getPropertyNames(jsObject, exec, array, ExcludeDontEnumProperties);
size_t size = array.size();
propertyNames->array.reserveInitialCapacity(size);
for (size_t i = 0; i < size; ++i)
- propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].string()).leakRef()));
+ propertyNames->array.uncheckedAppend(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].string()).leakRef()));
return JSPropertyNameArrayRetain(propertyNames);
}
@@ -526,7 +633,7 @@ JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
{
if (--array->refCount == 0) {
- APIEntryShim entryShim(array->globalData, false);
+ APIEntryShim entryShim(array->vm, false);
delete array;
}
}
@@ -544,6 +651,6 @@ JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size
void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
{
PropertyNameArray* propertyNames = toJS(array);
- APIEntryShim entryShim(propertyNames->globalData());
- propertyNames->add(propertyName->identifier(propertyNames->globalData()));
+ APIEntryShim entryShim(propertyNames->vm());
+ propertyNames->add(propertyName->identifier(propertyNames->vm()));
}
diff --git a/Source/JavaScriptCore/API/JSProfilerPrivate.cpp b/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
index c83bc63bd..0405b4b26 100644
--- a/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
+++ b/Source/JavaScriptCore/API/JSProfilerPrivate.cpp
@@ -27,20 +27,20 @@
#include "JSProfilerPrivate.h"
#include "APICast.h"
+#include "LegacyProfiler.h"
#include "OpaqueJSString.h"
-#include "Profiler.h"
using namespace JSC;
void JSStartProfiling(JSContextRef ctx, JSStringRef title)
{
- Profiler::profiler()->startProfiling(toJS(ctx), title->string());
+ LegacyProfiler::profiler()->startProfiling(toJS(ctx), title->string());
}
void JSEndProfiling(JSContextRef ctx, JSStringRef title)
{
ExecState* exec = toJS(ctx);
- Profiler* profiler = Profiler::profiler();
+ LegacyProfiler* profiler = LegacyProfiler::profiler();
profiler->stopProfiling(exec, title->string());
}
diff --git a/Source/JavaScriptCore/API/JSScriptRef.cpp b/Source/JavaScriptCore/API/JSScriptRef.cpp
new file mode 100644
index 000000000..8a5f3caf3
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSScriptRef.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "APICast.h"
+#include "APIShims.h"
+#include "Completion.h"
+#include "JSBasePrivate.h"
+#include "VM.h"
+#include "JSScriptRefPrivate.h"
+#include "OpaqueJSString.h"
+#include "Operations.h"
+#include "Parser.h"
+#include "SourceCode.h"
+#include "SourceProvider.h"
+
+using namespace JSC;
+
+struct OpaqueJSScript : public SourceProvider {
+public:
+ static WTF::PassRefPtr<OpaqueJSScript> create(VM* vm, const String& url, int startingLineNumber, const String& source)
+ {
+ return WTF::adoptRef(new OpaqueJSScript(vm, url, startingLineNumber, source));
+ }
+
+ const String& source() const OVERRIDE
+ {
+ return m_source;
+ }
+
+ VM* vm() const { return m_vm; }
+
+private:
+ OpaqueJSScript(VM* vm, const String& url, int startingLineNumber, const String& source)
+ : SourceProvider(url, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()))
+ , m_vm(vm)
+ , m_source(source)
+ {
+ }
+
+ ~OpaqueJSScript() { }
+
+ VM* m_vm;
+ String m_source;
+};
+
+static bool parseScript(VM* vm, const SourceCode& source, ParserError& error)
+{
+ return JSC::parse<JSC::ProgramNode>(vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
+}
+
+extern "C" {
+
+JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, const char* source, size_t length, JSStringRef* errorMessage, int* errorLine)
+{
+ VM* vm = toJS(contextGroup);
+ APIEntryShim entryShim(vm);
+ for (size_t i = 0; i < length; i++) {
+ if (!isASCII(source[i]))
+ return 0;
+ }
+
+ RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, String(StringImpl::createFromLiteral(source, length)));
+
+ ParserError error;
+ if (!parseScript(vm, SourceCode(result), error)) {
+ if (errorMessage)
+ *errorMessage = OpaqueJSString::create(error.m_message).leakRef();
+ if (errorLine)
+ *errorLine = error.m_line;
+ return 0;
+ }
+
+ return result.release().leakRef();
+}
+
+JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, JSStringRef source, JSStringRef* errorMessage, int* errorLine)
+{
+ VM* vm = toJS(contextGroup);
+ APIEntryShim entryShim(vm);
+
+ RefPtr<OpaqueJSScript> result = OpaqueJSScript::create(vm, url->string(), startingLineNumber, source->string());
+
+ ParserError error;
+ if (!parseScript(vm, SourceCode(result), error)) {
+ if (errorMessage)
+ *errorMessage = OpaqueJSString::create(error.m_message).leakRef();
+ if (errorLine)
+ *errorLine = error.m_line;
+ return 0;
+ }
+
+ return result.release().leakRef();
+}
+
+void JSScriptRetain(JSScriptRef script)
+{
+ APIEntryShim entryShim(script->vm());
+ script->ref();
+}
+
+void JSScriptRelease(JSScriptRef script)
+{
+ APIEntryShim entryShim(script->vm());
+ script->deref();
+}
+
+JSValueRef JSScriptEvaluate(JSContextRef context, JSScriptRef script, JSValueRef thisValueRef, JSValueRef* exception)
+{
+ ExecState* exec = toJS(context);
+ APIEntryShim entryShim(exec);
+ if (script->vm() != &exec->vm()) {
+ RELEASE_ASSERT_NOT_REACHED();
+ return 0;
+ }
+ JSValue internalException;
+ JSValue thisValue = thisValueRef ? toJS(exec, thisValueRef) : jsUndefined();
+ JSValue result = evaluate(exec, SourceCode(script), thisValue, &internalException);
+ if (internalException) {
+ if (exception)
+ *exception = toRef(exec, internalException);
+ return 0;
+ }
+ ASSERT(result);
+ return toRef(exec, result);
+}
+
+}
diff --git a/Source/JavaScriptCore/API/JSScriptRefPrivate.h b/Source/JavaScriptCore/API/JSScriptRefPrivate.h
new file mode 100644
index 000000000..e1992052a
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSScriptRefPrivate.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSScriptRefPrivate_h
+#define JSScriptRefPrivate_h
+
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSValueRef.h>
+
+/*! @typedef JSScriptRef A JavaScript script reference. */
+typedef struct OpaqueJSScript* JSScriptRef;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ @function
+ @abstract Creates a script reference from an ascii string, without copying or taking ownership of the string
+ @param contextGroup The context group the script is to be used in.
+ @param url The source url to be reported in errors and exceptions.
+ @param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+ @param source The source string. This is required to be pure ASCII and to never be deallocated.
+ @param length The length of the source string.
+ @param errorMessage A pointer to a JSStringRef in which to store the parse error message if the source is not valid. Pass NULL if you do not care to store an error message.
+ @param errorLine A pointer to an int in which to store the line number of a parser error. Pass NULL if you do not care to store an error line.
+ @result A JSScriptRef for the provided source, or NULL if any non-ASCII character is found in source or if the source is not a valid JavaScript program. Ownership follows the Create Rule.
+ @discussion Use this function to create a reusable script reference with a constant
+ buffer as the backing string. The source string must outlive the global context.
+ */
+JS_EXPORT JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, const char* source, size_t length, JSStringRef* errorMessage, int* errorLine);
+
+/*!
+ @function
+ @abstract Creates a script reference from a string
+ @param contextGroup The context group the script is to be used in.
+ @param url The source url to be reported in errors and exceptions.
+ @param startingLineNumber An integer value specifying the script's starting line number in the file located at sourceURL. This is only used when reporting exceptions.
+ @param source The source string.
+ @param errorMessage A pointer to a JSStringRef in which to store the parse error message if the source is not valid. Pass NULL if you do not care to store an error message.
+ @param errorLine A pointer to an int in which to store the line number of a parser error. Pass NULL if you do not care to store an error line.
+ @result A JSScriptRef for the provided source, or NULL is the source is not a valid JavaScript program. Ownership follows the Create Rule.
+ */
+JS_EXPORT JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, JSStringRef source, JSStringRef* errorMessage, int* errorLine);
+
+/*!
+ @function
+ @abstract Retains a JavaScript script.
+ @param script The script to retain.
+ */
+JS_EXPORT void JSScriptRetain(JSScriptRef script);
+
+/*!
+ @function
+ @abstract Releases a JavaScript script.
+ @param script The script to release.
+ */
+JS_EXPORT void JSScriptRelease(JSScriptRef script);
+
+/*!
+ @function
+ @abstract Evaluates a JavaScript script.
+ @param ctx The execution context to use.
+ @param script The JSScript to evaluate.
+ @param thisValue The value to use as "this" when evaluating the script.
+ @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
+ @result The JSValue that results from evaluating script, or NULL if an exception is thrown.
+ */
+JS_EXPORT JSValueRef JSScriptEvaluate(JSContextRef ctx, JSScriptRef script, JSValueRef thisValue, JSValueRef* exception);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSScriptRefPrivate_h */
diff --git a/Source/JavaScriptCore/API/JSStringRef.cpp b/Source/JavaScriptCore/API/JSStringRef.cpp
index 7f2168dc2..a03afed5b 100644
--- a/Source/JavaScriptCore/API/JSStringRef.cpp
+++ b/Source/JavaScriptCore/API/JSStringRef.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "JSStringRef.h"
+#include "JSStringRefPrivate.h"
#include "InitializeThreading.h"
#include "OpaqueJSString.h"
@@ -55,10 +56,15 @@ JSStringRef JSStringCreateWithUTF8CString(const char* string)
}
}
- // Null string.
return OpaqueJSString::create().leakRef();
}
+JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars)
+{
+ initializeThreading();
+ return OpaqueJSString::create(StringImpl::createWithoutCopying(chars, numChars)).leakRef();
+}
+
JSStringRef JSStringRetain(JSStringRef string)
{
string->ref();
diff --git a/Source/JavaScriptCore/API/JSStringRefCF.cpp b/Source/JavaScriptCore/API/JSStringRefCF.cpp
index fd72a593c..64d2d6251 100644
--- a/Source/JavaScriptCore/API/JSStringRefCF.cpp
+++ b/Source/JavaScriptCore/API/JSStringRefCF.cpp
@@ -30,7 +30,7 @@
#include "InitializeThreading.h"
#include "JSStringRef.h"
#include "OpaqueJSString.h"
-#include <runtime/JSValue.h>
+#include <runtime/JSCJSValue.h>
#include <wtf/OwnArrayPtr.h>
JSStringRef JSStringCreateWithCFString(CFStringRef string)
@@ -51,9 +51,9 @@ JSStringRef JSStringCreateWithCFString(CFStringRef string)
CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get());
COMPILE_ASSERT(sizeof(UniChar) == sizeof(UChar), unichar_and_uchar_must_be_same_size);
return OpaqueJSString::create(reinterpret_cast<UChar*>(buffer.get()), length).leakRef();
- } else {
- return OpaqueJSString::create(static_cast<const LChar*>(0), 0).leakRef();
}
+
+ return OpaqueJSString::create(reinterpret_cast<const LChar*>(""), 0).leakRef();
}
CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string)
diff --git a/Source/JavaScriptCore/API/JSStringRefPrivate.h b/Source/JavaScriptCore/API/JSStringRefPrivate.h
new file mode 100644
index 000000000..f1db806ee
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefPrivate.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 JSStringRefPrivate_h
+#define JSStringRefPrivate_h
+
+#include <JavaScriptCore/JSStringRef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JS_EXPORT JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSStringRefPrivate_h */
diff --git a/Source/JavaScriptCore/API/JSStringRefQt.cpp b/Source/JavaScriptCore/API/JSStringRefQt.cpp
new file mode 100644
index 000000000..259bad8e6
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefQt.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "JSStringRefQt.h"
+
+#include "APICast.h"
+#include "InitializeThreading.h"
+#include "JSStringRef.h"
+#include "OpaqueJSString.h"
+#include <runtime/JSCJSValue.h>
+#include <wtf/OwnArrayPtr.h>
+
+QString JSStringCopyQString(JSStringRef string)
+{
+ return string->qString();
+}
+
+JSRetainPtr<JSStringRef> JSStringCreateWithQString(const QString& qString)
+{
+ RefPtr<OpaqueJSString> jsString = OpaqueJSString::create(qString);
+
+ if (jsString)
+ return JSRetainPtr<JSStringRef>(Adopt, jsString.release().leakRef());
+
+ return JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create().leakRef());
+}
diff --git a/Source/JavaScriptCore/API/JSStringRefQt.h b/Source/JavaScriptCore/API/JSStringRefQt.h
new file mode 100644
index 000000000..63a059fdb
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSStringRefQt.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 JSStringRefQt_h
+#define JSStringRefQt_h
+
+#include "JSBase.h"
+#include "JSRetainPtr.h"
+#include <QString>
+
+/* QString convenience methods */
+
+/*!
+@function
+@abstract Creates a QString from a JavaScript string.
+@param string The JSString to copy into the new QString.
+@result A QString containing string.
+*/
+JS_EXPORT QString JSStringCopyQString(JSStringRef string);
+JS_EXPORT JSRetainPtr<JSStringRef> JSStringCreateWithQString(const QString&);
+
+#endif /* JSStringRefQt_h */
diff --git a/Source/JavaScriptCore/API/JSValue.h b/Source/JavaScriptCore/API/JSValue.h
new file mode 100644
index 000000000..c77707538
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSValue.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSValue_h
+#define JSValue_h
+
+#if JSC_OBJC_API_ENABLED
+
+@class JSContext;
+
+// A JSValue is a reference to a value within the JavaScript object space of a
+// JSVirtualMachine. All instances of JSValue originate from a JSContext and
+// hold a strong reference to this JSContext. As long as any value associated with
+// a particular JSContext is retained, that JSContext will remain alive.
+// Where an instance method is invoked upon a JSValue, and this returns another
+// JSValue, the returned JSValue will originate from the same JSContext as the
+// JSValue on which the method was invoked.
+//
+// For all methods taking arguments of type id, arguments will be converted
+// into a JavaScript value according to the conversion specified below.
+// All JavaScript values are associated with a particular JSVirtualMachine
+// (the associated JSVirtualMachine is available indirectly via the context
+// property). An instance of JSValue may only be passed as an argument to
+// methods on instances of JSValue and JSContext that belong to the same
+// JSVirtualMachine - passing a JSValue to a method on an object originating
+// from a different JSVirtualMachine will result in an Objective-C exception
+// being raised.
+//
+// Conversion between Objective-C and JavaScript types.
+//
+// When converting between JavaScript values and Objective-C objects a copy is
+// performed. Values of types listed below are copied to the corresponding
+// types on conversion in each direction. For NSDictionaries, entries in the
+// dictionary that are keyed by strings are copied onto a JavaScript object.
+// For dictionaries and arrays, conversion is recursive, with the same object
+// conversion being applied to all entries in the collection.
+//
+// Objective-C type | JavaScript type
+// --------------------+---------------------
+// nil | undefined
+// NSNull | null
+// NSString | string
+// NSNumber | number, boolean
+// NSDictionary | Object object
+// NSArray | Array object
+// NSDate | Date object
+// NSBlock * | Function object *
+// id ** | Wrapper object **
+// Class *** | Constructor object ***
+//
+// * Instances of NSBlock with supported arguments types will be presented to
+// JavaScript as a callable Function object. For more information on supported
+// argument types see JSExport.h. If a JavaScript Function originating from an
+// Objective-C block is converted back to an Objective-C object the block will
+// be returned. All other JavaScript functions will be converted in the same
+// manner as a JavaScript object of type Object.
+//
+// ** For Objective-C instances that do not derive from the set of types listed
+// above, a wrapper object to provide a retaining handle to the Objective-C
+// instance from JavaScript. For more information on these wrapper objects, see
+// JSExport.h. When a JavaScript wrapper object is converted back to Objective-C
+// the Objective-C instance being retained by the wrapper is returned.
+//
+// *** For Objective-C Class objects a constructor object containing exported
+// class methods will be returned. See JSExport.h for more information on
+// constructor objects.
+
+NS_CLASS_AVAILABLE(10_9, NA)
+@interface JSValue : NSObject
+
+// Create a JSValue by converting an Objective-C object.
++ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context;
+// Create a JavaScript value from an Objective-C primitive type.
++ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context;
++ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context;
++ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context;
++ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context;
+// Create a JavaScript value in this context.
++ (JSValue *)valueWithNewObjectInContext:(JSContext *)context;
++ (JSValue *)valueWithNewArrayInContext:(JSContext *)context;
++ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context;
++ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context;
++ (JSValue *)valueWithNullInContext:(JSContext *)context;
++ (JSValue *)valueWithUndefinedInContext:(JSContext *)context;
+
+// Convert this value to a corresponding Objective-C object, according to the
+// conversion specified above.
+- (id)toObject;
+// Convert this value to a corresponding Objective-C object, if the result is
+// not of the specified class then nil will be returned.
+- (id)toObjectOfClass:(Class)expectedClass;
+// The value is copied to a boolean according to the conversion specified by the
+// JavaScript language.
+- (BOOL)toBool;
+// The value is copied to a number according to the conversion specified by the
+// JavaScript language.
+- (double)toDouble;
+// The value is copied to an integer according to the conversion specified by
+// the JavaScript language.
+- (int32_t)toInt32;
+// The value is copied to an integer according to the conversion specified by
+// the JavaScript language.
+- (uint32_t)toUInt32;
+// If the value is a boolean, a NSNumber value of @YES or @NO will be returned.
+// For all other types the value will be copied to a number according to the
+// conversion specified by the JavaScript language.
+- (NSNumber *)toNumber;
+// The value is copied to a string according to the conversion specified by the
+// JavaScript language.
+- (NSString *)toString;
+// The value is converted to a number representing a time interval since 1970,
+// and a new NSDate instance is returned.
+- (NSDate *)toDate;
+// If the value is null or undefined then nil is returned.
+// If the value is not an object then a JavaScript TypeError will be thrown.
+// The property "length" is read from the object, converted to an unsigned
+// integer, and an NSArray of this size is allocated. Properties corresponding
+// to indicies within the array bounds will be copied to the array, with
+// Objective-C objects converted to equivalent JSValues as specified.
+- (NSArray *)toArray;
+// If the value is null or undefined then nil is returned.
+// If the value is not an object then a JavaScript TypeError will be thrown.
+// All enumerable properties of the object are copied to the dictionary, with
+// Objective-C objects converted to equivalent JSValues as specified.
+- (NSDictionary *)toDictionary;
+
+// Access a property from the value. This method will return the JavaScript value
+// 'undefined' if the property does not exist.
+- (JSValue *)valueForProperty:(NSString *)property;
+// Set a property on the value.
+- (void)setValue:(id)value forProperty:(NSString *)property;
+// Delete a property from the value, returns YES if deletion is successful.
+- (BOOL)deleteProperty:(NSString *)property;
+// Returns YES if property is present on the value.
+// This method has the same function as the JavaScript operator "in".
+- (BOOL)hasProperty:(NSString *)property;
+// This method may be used to create a data or accessor property on an object;
+// this method operates in accordance with the Object.defineProperty method in
+// the JavaScript language.
+- (void)defineProperty:(NSString *)property descriptor:(id)descriptor;
+
+// Access an indexed property from the value. This method will return the
+// JavaScript value 'undefined' if no property exists at that index.
+- (JSValue *)valueAtIndex:(NSUInteger)index;
+// Set an indexed property on the value. For JSValues that are JavaScript arrays,
+// indices greater than UINT_MAX - 1 will not affect the length of the array.
+- (void)setValue:(id)value atIndex:(NSUInteger)index;
+
+// All JavaScript values are precisely one of these types.
+- (BOOL)isUndefined;
+- (BOOL)isNull;
+- (BOOL)isBoolean;
+- (BOOL)isNumber;
+- (BOOL)isString;
+- (BOOL)isObject;
+
+// This method has the same function as the JavaScript operator "===".
+- (BOOL)isEqualToObject:(id)value;
+// This method has the same function as the JavaScript operator "==".
+- (BOOL)isEqualWithTypeCoercionToObject:(id)value;
+// This method has the same function as the JavaScript operator "instanceof".
+- (BOOL)isInstanceOf:(id)value;
+
+// Call this value as a function passing the specified arguments.
+- (JSValue *)callWithArguments:(NSArray *)arguments;
+// Call this value as a constructor passing the specified arguments.
+- (JSValue *)constructWithArguments:(NSArray *)arguments;
+// Access the property named "method" from this value; call the value resulting
+// from the property access as a function, passing this value as the "this"
+// value, and the specified arguments.
+- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments;
+
+// The JSContext that this value originates from.
+@property(readonly, retain) JSContext *context;
+
+@end
+
+// Objective-C methods exported to JavaScript may have argument and/or return
+// values of struct types, provided that conversion to and from the struct is
+// supported by JSValue. Support is provided for any types where JSValue
+// contains both a class method "valueWith<Type>:inContext:", and and instance
+// method "to<Type>" - where the string "<Type>" in these selector names match,
+// with the first argument to the former being of the same struct type as the
+// return type of the latter.
+// Support is provided for structs of type CGPoint, NSRange, CGRect and CGSize.
+@interface JSValue(StructSupport)
+
+// This method returns a newly allocated JavaScript object containing properties
+// named "x" and "y", with values from the CGPoint.
++ (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context;
+// This method returns a newly allocated JavaScript object containing properties
+// named "location" and "length", with values from the NSRange.
++ (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context;
+// This method returns a newly allocated JavaScript object containing properties
+// named "x", "y", "width", and "height", with values from the CGRect.
++ (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context;
+// This method returns a newly allocated JavaScript object containing properties
+// named "width" and "height", with values from the CGSize.
++ (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context;
+
+// Convert a value to type CGPoint by reading properties named "x" and "y" from
+// this value, and converting the results to double.
+- (CGPoint)toPoint;
+// Convert a value to type NSRange by accessing properties named "location" and
+// "length" from this value converting the results to double.
+- (NSRange)toRange;
+// Convert a value to type CGRect by reading properties named "x", "y", "width",
+// and "height" from this value, and converting the results to double.
+- (CGRect)toRect;
+// Convert a value to type CGSize by accessing properties named "width" and
+// "height" from this value converting the results to double.
+- (CGSize)toSize;
+
+@end
+
+// Instances of JSValue implement the following methods in order to enable
+// support for subscript access by key and index, for example:
+//
+// JSValue *objectA, *objectB;
+// JSValue *v1 = object[@"X"]; // Get value for property "X" from 'object'.
+// JSValue *v2 = object[42]; // Get value for index 42 from 'object'.
+// object[@"Y"] = v1; // Assign 'v1' to property "Y" of 'object'.
+// object[101] = v2; // Assign 'v2' to index 101 of 'object'.
+//
+// An object key passed as a subscript will be converted to a JavaScript value,
+// and then the value converted to a string used as a property name.
+@interface JSValue(SubscriptSupport)
+
+- (JSValue *)objectForKeyedSubscript:(id)key;
+- (JSValue *)objectAtIndexedSubscript:(NSUInteger)index;
+- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key;
+- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index;
+
+@end
+
+// These functions are for bridging between the C API and the Objective-C API.
+@interface JSValue(JSValueRefSupport)
+// Creates a JSValue, wrapping its C API counterpart.
++ (JSValue *)valueWithJSValueRef:(JSValueRef)value inContext:(JSContext *)context;
+// Returns the C API counterpart wrapped by a JSContext.
+- (JSValueRef)JSValueRef;
+@end
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// These keys may assist in creating a property descriptor for use with the
+// defineProperty method on JSValue.
+// Property descriptors must fit one of three descriptions:
+// Data Descriptor:
+// - A descriptor containing one or both of the keys "value" and "writable",
+// and optionally containing one or both of the keys "enumerable" and
+// "configurable". A data descriptor may not contain either the "get" or
+// "set" key.
+// A data descriptor may be used to create or modify the attributes of a
+// data property on an object (replacing any existing accessor property).
+// Accessor Descriptor:
+// - A descriptor containing one or both of the keys "get" and "set", and
+// optionally containing one or both of the keys "enumerable" and
+// "configurable". An accessor descriptor may not contain either the "value"
+// or "writable" key.
+// An accessor descriptor may be used to create or modify the attributes of
+// an accessor property on an object (replacing any existing data property).
+// Generic Descriptor:
+// - A descriptor containing one or both of the keys "enumerable" and
+// "configurable". A generic descriptor may not contain any of the keys
+// "value", " writable", "get", or "set".
+// A generic descriptor may be used to modify the attributes of an existing
+// data or accessor property, or to create a new data property.
+JS_EXPORT extern NSString * const JSPropertyDescriptorWritableKey;
+JS_EXPORT extern NSString * const JSPropertyDescriptorEnumerableKey;
+JS_EXPORT extern NSString * const JSPropertyDescriptorConfigurableKey;
+JS_EXPORT extern NSString * const JSPropertyDescriptorValueKey;
+JS_EXPORT extern NSString * const JSPropertyDescriptorGetKey;
+JS_EXPORT extern NSString * const JSPropertyDescriptorSetKey;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
+
+#endif // JSValue_h
diff --git a/Source/JavaScriptCore/API/JSValue.mm b/Source/JavaScriptCore/API/JSValue.mm
new file mode 100644
index 000000000..e708cc674
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSValue.mm
@@ -0,0 +1,1131 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#import "APICast.h"
+#import "APIShims.h"
+#import "DateInstance.h"
+#import "Error.h"
+#import "JavaScriptCore.h"
+#import "JSContextInternal.h"
+#import "JSVirtualMachineInternal.h"
+#import "JSValueInternal.h"
+#import "JSWrapperMap.h"
+#import "ObjcRuntimeExtras.h"
+#import "Operations.h"
+#import "JSCJSValue.h"
+#import <wtf/HashMap.h>
+#import <wtf/HashSet.h>
+#import <wtf/Vector.h>
+#import <wtf/TCSpinLock.h>
+#import <wtf/text/WTFString.h>
+#import <wtf/text/StringHash.h>
+
+#if JSC_OBJC_API_ENABLED
+
+NSString * const JSPropertyDescriptorWritableKey = @"writable";
+NSString * const JSPropertyDescriptorEnumerableKey = @"enumerable";
+NSString * const JSPropertyDescriptorConfigurableKey = @"configurable";
+NSString * const JSPropertyDescriptorValueKey = @"value";
+NSString * const JSPropertyDescriptorGetKey = @"get";
+NSString * const JSPropertyDescriptorSetKey = @"set";
+
+@implementation JSValue {
+ JSValueRef m_value;
+}
+
+- (JSValueRef)JSValueRef
+{
+ return m_value;
+}
+
++ (JSValue *)valueWithObject:(id)value inContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:objectToValue(context, value) inContext:context];
+}
+
++ (JSValue *)valueWithBool:(BOOL)value inContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSValueMakeBoolean([context JSGlobalContextRef], value) inContext:context];
+}
+
++ (JSValue *)valueWithDouble:(double)value inContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSValueMakeNumber([context JSGlobalContextRef], value) inContext:context];
+}
+
++ (JSValue *)valueWithInt32:(int32_t)value inContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSValueMakeNumber([context JSGlobalContextRef], value) inContext:context];
+}
+
++ (JSValue *)valueWithUInt32:(uint32_t)value inContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSValueMakeNumber([context JSGlobalContextRef], value) inContext:context];
+}
+
++ (JSValue *)valueWithNewObjectInContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSObjectMake([context JSGlobalContextRef], 0, 0) inContext:context];
+}
+
++ (JSValue *)valueWithNewArrayInContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSObjectMakeArray([context JSGlobalContextRef], 0, NULL, 0) inContext:context];
+}
+
++ (JSValue *)valueWithNewRegularExpressionFromPattern:(NSString *)pattern flags:(NSString *)flags inContext:(JSContext *)context
+{
+ JSStringRef patternString = JSStringCreateWithCFString((CFStringRef)pattern);
+ JSStringRef flagsString = JSStringCreateWithCFString((CFStringRef)flags);
+ JSValueRef arguments[2] = { JSValueMakeString([context JSGlobalContextRef], patternString), JSValueMakeString([context JSGlobalContextRef], flagsString) };
+ JSStringRelease(patternString);
+ JSStringRelease(flagsString);
+
+ return [JSValue valueWithJSValueRef:JSObjectMakeRegExp([context JSGlobalContextRef], 2, arguments, 0) inContext:context];
+}
+
++ (JSValue *)valueWithNewErrorFromMessage:(NSString *)message inContext:(JSContext *)context
+{
+ JSStringRef string = JSStringCreateWithCFString((CFStringRef)message);
+ JSValueRef argument = JSValueMakeString([context JSGlobalContextRef], string);
+ JSStringRelease(string);
+
+ return [JSValue valueWithJSValueRef:JSObjectMakeError([context JSGlobalContextRef], 1, &argument, 0) inContext:context];
+}
+
++ (JSValue *)valueWithNullInContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSValueMakeNull([context JSGlobalContextRef]) inContext:context];
+}
+
++ (JSValue *)valueWithUndefinedInContext:(JSContext *)context
+{
+ return [JSValue valueWithJSValueRef:JSValueMakeUndefined([context JSGlobalContextRef]) inContext:context];
+}
+
+- (id)toObject
+{
+ return valueToObject(_context, m_value);
+}
+
+- (id)toObjectOfClass:(Class)expectedClass
+{
+ id result = [self toObject];
+ return [result isKindOfClass:expectedClass] ? result : nil;
+}
+
+- (BOOL)toBool
+{
+ return JSValueToBoolean([_context JSGlobalContextRef], m_value);
+}
+
+- (double)toDouble
+{
+ JSValueRef exception = 0;
+ double result = JSValueToNumber([_context JSGlobalContextRef], m_value, &exception);
+ if (exception) {
+ [_context notifyException:exception];
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+
+ return result;
+}
+
+- (int32_t)toInt32
+{
+ return JSC::toInt32([self toDouble]);
+}
+
+- (uint32_t)toUInt32
+{
+ return JSC::toUInt32([self toDouble]);
+}
+
+- (NSNumber *)toNumber
+{
+ JSValueRef exception = 0;
+ id result = valueToNumber([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ [_context notifyException:exception];
+ return result;
+}
+
+- (NSString *)toString
+{
+ JSValueRef exception = 0;
+ id result = valueToString([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ [_context notifyException:exception];
+ return result;
+}
+
+- (NSDate *)toDate
+{
+ JSValueRef exception = 0;
+ id result = valueToDate([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ [_context notifyException:exception];
+ return result;
+}
+
+- (NSArray *)toArray
+{
+ JSValueRef exception = 0;
+ id result = valueToArray([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ [_context notifyException:exception];
+ return result;
+}
+
+- (NSDictionary *)toDictionary
+{
+ JSValueRef exception = 0;
+ id result = valueToDictionary([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ [_context notifyException:exception];
+ return result;
+}
+
+- (JSValue *)valueForProperty:(NSString *)propertyName
+{
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
+ JSValueRef result = JSObjectGetProperty([_context JSGlobalContextRef], object, name, &exception);
+ JSStringRelease(name);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ return [JSValue valueWithJSValueRef:result inContext:_context];
+}
+
+- (void)setValue:(id)value forProperty:(NSString *)propertyName
+{
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception) {
+ [_context notifyException:exception];
+ return;
+ }
+
+ JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
+ JSObjectSetProperty([_context JSGlobalContextRef], object, name, objectToValue(_context, value), 0, &exception);
+ JSStringRelease(name);
+ if (exception) {
+ [_context notifyException:exception];
+ return;
+ }
+}
+
+- (BOOL)deleteProperty:(NSString *)propertyName
+{
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context boolFromNotifyException:exception];
+
+ JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
+ BOOL result = JSObjectDeleteProperty([_context JSGlobalContextRef], object, name, &exception);
+ JSStringRelease(name);
+ if (exception)
+ return [_context boolFromNotifyException:exception];
+
+ return result;
+}
+
+- (BOOL)hasProperty:(NSString *)propertyName
+{
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context boolFromNotifyException:exception];
+
+ JSStringRef name = JSStringCreateWithCFString((CFStringRef)propertyName);
+ BOOL result = JSObjectHasProperty([_context JSGlobalContextRef], object, name);
+ JSStringRelease(name);
+ return result;
+}
+
+- (void)defineProperty:(NSString *)property descriptor:(id)descriptor
+{
+ [[_context globalObject][@"Object"] invokeMethod:@"defineProperty" withArguments:@[ self, property, descriptor ]];
+}
+
+- (JSValue *)valueAtIndex:(NSUInteger)index
+{
+ // Properties that are higher than an unsigned value can hold are converted to a double then inserted as a normal property.
+ // Indices that are bigger than the max allowed index size (UINT_MAX - 1) will be handled internally in get().
+ if (index != (unsigned)index)
+ return [self valueForProperty:[[JSValue valueWithDouble:index inContext:_context] toString]];
+
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSValueRef result = JSObjectGetPropertyAtIndex([_context JSGlobalContextRef], object, (unsigned)index, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ return [JSValue valueWithJSValueRef:result inContext:_context];
+}
+
+- (void)setValue:(id)value atIndex:(NSUInteger)index
+{
+ // Properties that are higher than an unsigned value can hold are converted to a double, then inserted as a normal property.
+ // Indices that are bigger than the max allowed index size (UINT_MAX - 1) will be handled internally in putByIndex().
+ if (index != (unsigned)index)
+ return [self setValue:value forProperty:[[JSValue valueWithDouble:index inContext:_context] toString]];
+
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception) {
+ [_context notifyException:exception];
+ return;
+ }
+
+ JSObjectSetPropertyAtIndex([_context JSGlobalContextRef], object, (unsigned)index, objectToValue(_context, value), &exception);
+ if (exception) {
+ [_context notifyException:exception];
+ return;
+ }
+}
+
+- (BOOL)isUndefined
+{
+ return JSValueIsUndefined([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isNull
+{
+ return JSValueIsNull([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isBoolean
+{
+ return JSValueIsBoolean([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isNumber
+{
+ return JSValueIsNumber([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isString
+{
+ return JSValueIsString([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isObject
+{
+ return JSValueIsObject([_context JSGlobalContextRef], m_value);
+}
+
+- (BOOL)isEqualToObject:(id)value
+{
+ return JSValueIsStrictEqual([_context JSGlobalContextRef], m_value, objectToValue(_context, value));
+}
+
+- (BOOL)isEqualWithTypeCoercionToObject:(id)value
+{
+ JSValueRef exception = 0;
+ BOOL result = JSValueIsEqual([_context JSGlobalContextRef], m_value, objectToValue(_context, value), &exception);
+ if (exception)
+ return [_context boolFromNotifyException:exception];
+
+ return result;
+}
+
+- (BOOL)isInstanceOf:(id)value
+{
+ JSValueRef exception = 0;
+ JSObjectRef constructor = JSValueToObject([_context JSGlobalContextRef], objectToValue(_context, value), &exception);
+ if (exception)
+ return [_context boolFromNotifyException:exception];
+
+ BOOL result = JSValueIsInstanceOfConstructor([_context JSGlobalContextRef], m_value, constructor, &exception);
+ if (exception)
+ return [_context boolFromNotifyException:exception];
+
+ return result;
+}
+
+- (JSValue *)callWithArguments:(NSArray *)argumentArray
+{
+ NSUInteger argumentCount = [argumentArray count];
+ JSValueRef arguments[argumentCount];
+ for (unsigned i = 0; i < argumentCount; ++i)
+ arguments[i] = objectToValue(_context, [argumentArray objectAtIndex:i]);
+
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSValueRef result = JSObjectCallAsFunction([_context JSGlobalContextRef], object, 0, argumentCount, arguments, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ return [JSValue valueWithJSValueRef:result inContext:_context];
+}
+
+- (JSValue *)constructWithArguments:(NSArray *)argumentArray
+{
+ NSUInteger argumentCount = [argumentArray count];
+ JSValueRef arguments[argumentCount];
+ for (unsigned i = 0; i < argumentCount; ++i)
+ arguments[i] = objectToValue(_context, [argumentArray objectAtIndex:i]);
+
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSObjectRef result = JSObjectCallAsConstructor([_context JSGlobalContextRef], object, argumentCount, arguments, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ return [JSValue valueWithJSValueRef:result inContext:_context];
+}
+
+- (JSValue *)invokeMethod:(NSString *)method withArguments:(NSArray *)arguments
+{
+ NSUInteger argumentCount = [arguments count];
+ JSValueRef argumentArray[argumentCount];
+ for (unsigned i = 0; i < argumentCount; ++i)
+ argumentArray[i] = objectToValue(_context, [arguments objectAtIndex:i]);
+
+ JSValueRef exception = 0;
+ JSObjectRef thisObject = JSValueToObject([_context JSGlobalContextRef], m_value, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSStringRef name = JSStringCreateWithCFString((CFStringRef)method);
+ JSValueRef function = JSObjectGetProperty([_context JSGlobalContextRef], thisObject, name, &exception);
+ JSStringRelease(name);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSObjectRef object = JSValueToObject([_context JSGlobalContextRef], function, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ JSValueRef result = JSObjectCallAsFunction([_context JSGlobalContextRef], object, thisObject, argumentCount, argumentArray, &exception);
+ if (exception)
+ return [_context valueFromNotifyException:exception];
+
+ return [JSValue valueWithJSValueRef:result inContext:_context];
+}
+
+@end
+
+@implementation JSValue(StructSupport)
+
+- (CGPoint)toPoint
+{
+ return (CGPoint){
+ [self[@"x"] toDouble],
+ [self[@"y"] toDouble]
+ };
+}
+
+- (NSRange)toRange
+{
+ return (NSRange){
+ [[self[@"location"] toNumber] unsignedIntegerValue],
+ [[self[@"length"] toNumber] unsignedIntegerValue]
+ };
+}
+
+- (CGRect)toRect
+{
+ return (CGRect){
+ [self toPoint],
+ [self toSize]
+ };
+}
+
+- (CGSize)toSize
+{
+ return (CGSize){
+ [self[@"width"] toDouble],
+ [self[@"height"] toDouble]
+ };
+}
+
++ (JSValue *)valueWithPoint:(CGPoint)point inContext:(JSContext *)context
+{
+ return [JSValue valueWithObject:@{
+ @"x":@(point.x),
+ @"y":@(point.y)
+ } inContext:context];
+}
+
++ (JSValue *)valueWithRange:(NSRange)range inContext:(JSContext *)context
+{
+ return [JSValue valueWithObject:@{
+ @"location":@(range.location),
+ @"length":@(range.length)
+ } inContext:context];
+}
+
++ (JSValue *)valueWithRect:(CGRect)rect inContext:(JSContext *)context
+{
+ return [JSValue valueWithObject:@{
+ @"x":@(rect.origin.x),
+ @"y":@(rect.origin.y),
+ @"width":@(rect.size.width),
+ @"height":@(rect.size.height)
+ } inContext:context];
+}
+
++ (JSValue *)valueWithSize:(CGSize)size inContext:(JSContext *)context
+{
+ return [JSValue valueWithObject:@{
+ @"width":@(size.width),
+ @"height":@(size.height)
+ } inContext:context];
+}
+
+@end
+
+@implementation JSValue(SubscriptSupport)
+
+- (JSValue *)objectForKeyedSubscript:(id)key
+{
+ if (![key isKindOfClass:[NSString class]]) {
+ key = [[JSValue valueWithObject:key inContext:_context] toString];
+ if (!key)
+ return [JSValue valueWithUndefinedInContext:_context];
+ }
+
+ return [self valueForProperty:(NSString *)key];
+}
+
+- (JSValue *)objectAtIndexedSubscript:(NSUInteger)index
+{
+ return [self valueAtIndex:index];
+}
+
+- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key
+{
+ if (![key isKindOfClass:[NSString class]]) {
+ key = [[JSValue valueWithObject:key inContext:_context] toString];
+ if (!key)
+ return;
+ }
+
+ [self setValue:object forProperty:(NSString *)key];
+}
+
+- (void)setObject:(id)object atIndexedSubscript:(NSUInteger)index
+{
+ [self setValue:object atIndex:index];
+}
+
+@end
+
+inline bool isDate(JSObjectRef object, JSGlobalContextRef context)
+{
+ JSC::APIEntryShim entryShim(toJS(context));
+ return toJS(object)->inherits(&JSC::DateInstance::s_info);
+}
+
+inline bool isArray(JSObjectRef object, JSGlobalContextRef context)
+{
+ JSC::APIEntryShim entryShim(toJS(context));
+ return toJS(object)->inherits(&JSC::JSArray::s_info);
+}
+
+@implementation JSValue(Internal)
+
+enum ConversionType {
+ ContainerNone,
+ ContainerArray,
+ ContainerDictionary
+};
+
+class JSContainerConvertor {
+public:
+ struct Task {
+ JSValueRef js;
+ id objc;
+ ConversionType type;
+ };
+
+ JSContainerConvertor(JSGlobalContextRef context)
+ : m_context(context)
+ {
+ }
+
+ id convert(JSValueRef property);
+ void add(Task);
+ Task take();
+ bool isWorkListEmpty() const { return !m_worklist.size(); }
+
+private:
+ JSGlobalContextRef m_context;
+ HashMap<JSValueRef, id> m_objectMap;
+ Vector<Task> m_worklist;
+};
+
+inline id JSContainerConvertor::convert(JSValueRef value)
+{
+ HashMap<JSValueRef, id>::iterator iter = m_objectMap.find(value);
+ if (iter != m_objectMap.end())
+ return iter->value;
+
+ Task result = valueToObjectWithoutCopy(m_context, value);
+ if (result.js)
+ add(result);
+ return result.objc;
+}
+
+void JSContainerConvertor::add(Task task)
+{
+ m_objectMap.add(task.js, task.objc);
+ if (task.type != ContainerNone)
+ m_worklist.append(task);
+}
+
+JSContainerConvertor::Task JSContainerConvertor::take()
+{
+ ASSERT(!isWorkListEmpty());
+ Task last = m_worklist.last();
+ m_worklist.removeLast();
+ return last;
+}
+
+static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef context, JSValueRef value)
+{
+ if (!JSValueIsObject(context, value)) {
+ id primitive;
+ if (JSValueIsBoolean(context, value))
+ primitive = JSValueToBoolean(context, value) ? @YES : @NO;
+ else if (JSValueIsNumber(context, value)) {
+ // Normalize the number, so it will unique correctly in the hash map -
+ // it's nicer not to leak this internal implementation detail!
+ value = JSValueMakeNumber(context, JSValueToNumber(context, value, 0));
+ primitive = [NSNumber numberWithDouble:JSValueToNumber(context, value, 0)];
+ } else if (JSValueIsString(context, value)) {
+ // Would be nice to unique strings, too.
+ JSStringRef jsstring = JSValueToStringCopy(context, value, 0);
+ NSString * stringNS = (NSString *)JSStringCopyCFString(kCFAllocatorDefault, jsstring);
+ JSStringRelease(jsstring);
+ primitive = [stringNS autorelease];
+ } else if (JSValueIsNull(context, value))
+ primitive = [NSNull null];
+ else {
+ ASSERT(JSValueIsUndefined(context, value));
+ primitive = nil;
+ }
+ return (JSContainerConvertor::Task){ value, primitive, ContainerNone };
+ }
+
+ JSObjectRef object = JSValueToObject(context, value, 0);
+
+ if (id wrapped = tryUnwrapObjcObject(context, object))
+ return (JSContainerConvertor::Task){ object, wrapped, ContainerNone };
+
+ if (isDate(object, context))
+ return (JSContainerConvertor::Task){ object, [NSDate dateWithTimeIntervalSince1970:JSValueToNumber(context, object, 0)], ContainerNone };
+
+ if (isArray(object, context))
+ return (JSContainerConvertor::Task){ object, [NSMutableArray array], ContainerArray };
+
+ return (JSContainerConvertor::Task){ object, [NSMutableDictionary dictionary], ContainerDictionary };
+}
+
+static id containerValueToObject(JSGlobalContextRef context, JSContainerConvertor::Task task)
+{
+ ASSERT(task.type != ContainerNone);
+ JSContainerConvertor convertor(context);
+ convertor.add(task);
+ ASSERT(!convertor.isWorkListEmpty());
+
+ do {
+ JSContainerConvertor::Task current = convertor.take();
+ ASSERT(JSValueIsObject(context, current.js));
+ JSObjectRef js = JSValueToObject(context, current.js, 0);
+
+ if (current.type == ContainerArray) {
+ ASSERT([current.objc isKindOfClass:[NSMutableArray class]]);
+ NSMutableArray *array = (NSMutableArray *)current.objc;
+
+ JSStringRef lengthString = JSStringCreateWithUTF8CString("length");
+ unsigned length = JSC::toUInt32(JSValueToNumber(context, JSObjectGetProperty(context, js, lengthString, 0), 0));
+ JSStringRelease(lengthString);
+
+ for (unsigned i = 0; i < length; ++i) {
+ id objc = convertor.convert(JSObjectGetPropertyAtIndex(context, js, i, 0));
+ [array addObject:objc ? objc : [NSNull null]];
+ }
+ } else {
+ ASSERT([current.objc isKindOfClass:[NSMutableDictionary class]]);
+ NSMutableDictionary *dictionary = (NSMutableDictionary *)current.objc;
+
+ JSPropertyNameArrayRef propertyNameArray = JSObjectCopyPropertyNames(context, js);
+ size_t length = JSPropertyNameArrayGetCount(propertyNameArray);
+
+ for (size_t i = 0; i < length; ++i) {
+ JSStringRef propertyName = JSPropertyNameArrayGetNameAtIndex(propertyNameArray, i);
+ if (id objc = convertor.convert(JSObjectGetProperty(context, js, propertyName, 0)))
+ dictionary[[(NSString *)JSStringCopyCFString(kCFAllocatorDefault, propertyName) autorelease]] = objc;
+ }
+
+ JSPropertyNameArrayRelease(propertyNameArray);
+ }
+
+ } while (!convertor.isWorkListEmpty());
+
+ return task.objc;
+}
+
+id valueToObject(JSContext *context, JSValueRef value)
+{
+ JSContainerConvertor::Task result = valueToObjectWithoutCopy([context JSGlobalContextRef], value);
+ if (result.type == ContainerNone)
+ return result.objc;
+ return containerValueToObject([context JSGlobalContextRef], result);
+}
+
+id valueToNumber(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
+{
+ ASSERT(!*exception);
+ if (id wrapped = tryUnwrapObjcObject(context, value)) {
+ if ([wrapped isKindOfClass:[NSNumber class]])
+ return wrapped;
+ }
+
+ if (JSValueIsBoolean(context, value))
+ return JSValueToBoolean(context, value) ? @YES : @NO;
+
+ double result = JSValueToNumber(context, value, exception);
+ return [NSNumber numberWithDouble:*exception ? std::numeric_limits<double>::quiet_NaN() : result];
+}
+
+id valueToString(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
+{
+ ASSERT(!*exception);
+ if (id wrapped = tryUnwrapObjcObject(context, value)) {
+ if ([wrapped isKindOfClass:[NSString class]])
+ return wrapped;
+ }
+
+ JSStringRef jsstring = JSValueToStringCopy(context, value, exception);
+ if (*exception) {
+ ASSERT(!jsstring);
+ return nil;
+ }
+
+ NSString *stringNS = [(NSString *)JSStringCopyCFString(kCFAllocatorDefault, jsstring) autorelease];
+ JSStringRelease(jsstring);
+ return stringNS;
+}
+
+id valueToDate(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
+{
+ ASSERT(!*exception);
+ if (id wrapped = tryUnwrapObjcObject(context, value)) {
+ if ([wrapped isKindOfClass:[NSDate class]])
+ return wrapped;
+ }
+
+ double result = JSValueToNumber(context, value, exception);
+ return *exception ? nil : [NSDate dateWithTimeIntervalSince1970:result];
+}
+
+id valueToArray(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
+{
+ ASSERT(!*exception);
+ if (id wrapped = tryUnwrapObjcObject(context, value)) {
+ if ([wrapped isKindOfClass:[NSArray class]])
+ return wrapped;
+ }
+
+ if (JSValueIsObject(context, value))
+ return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableArray array], ContainerArray});
+
+ if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
+ *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSArray"));
+ return nil;
+}
+
+id valueToDictionary(JSGlobalContextRef context, JSValueRef value, JSValueRef* exception)
+{
+ ASSERT(!*exception);
+ if (id wrapped = tryUnwrapObjcObject(context, value)) {
+ if ([wrapped isKindOfClass:[NSDictionary class]])
+ return wrapped;
+ }
+
+ if (JSValueIsObject(context, value))
+ return containerValueToObject(context, (JSContainerConvertor::Task){ value, [NSMutableDictionary dictionary], ContainerDictionary});
+
+ if (!(JSValueIsNull(context, value) || JSValueIsUndefined(context, value)))
+ *exception = toRef(JSC::createTypeError(toJS(context), "Cannot convert primitive to NSDictionary"));
+ return nil;
+}
+
+class ObjcContainerConvertor {
+public:
+ struct Task {
+ id objc;
+ JSValueRef js;
+ ConversionType type;
+ };
+
+ ObjcContainerConvertor(JSContext *context)
+ : m_context(context)
+ {
+ }
+
+ JSValueRef convert(id object);
+ void add(Task);
+ Task take();
+ bool isWorkListEmpty() const { return !m_worklist.size(); }
+
+private:
+ JSContext *m_context;
+ HashMap<id, JSValueRef> m_objectMap;
+ Vector<Task> m_worklist;
+};
+
+JSValueRef ObjcContainerConvertor::convert(id object)
+{
+ ASSERT(object);
+
+ auto it = m_objectMap.find(object);
+ if (it != m_objectMap.end())
+ return it->value;
+
+ ObjcContainerConvertor::Task task = objectToValueWithoutCopy(m_context, object);
+ add(task);
+ return task.js;
+}
+
+void ObjcContainerConvertor::add(ObjcContainerConvertor::Task task)
+{
+ m_objectMap.add(task.objc, task.js);
+ if (task.type != ContainerNone)
+ m_worklist.append(task);
+}
+
+ObjcContainerConvertor::Task ObjcContainerConvertor::take()
+{
+ ASSERT(!isWorkListEmpty());
+ Task last = m_worklist.last();
+ m_worklist.removeLast();
+ return last;
+}
+
+inline bool isNSBoolean(id object)
+{
+ ASSERT([@YES class] == [@NO class]);
+ ASSERT([@YES class] != [NSNumber class]);
+ ASSERT([[@YES class] isSubclassOfClass:[NSNumber class]]);
+ return [object isKindOfClass:[@YES class]];
+}
+
+static ObjcContainerConvertor::Task objectToValueWithoutCopy(JSContext *context, id object)
+{
+ JSGlobalContextRef contextRef = [context JSGlobalContextRef];
+
+ if (!object)
+ return (ObjcContainerConvertor::Task){ object, JSValueMakeUndefined(contextRef), ContainerNone };
+
+ if (!class_conformsToProtocol(object_getClass(object), getJSExportProtocol())) {
+ if ([object isKindOfClass:[NSArray class]])
+ return (ObjcContainerConvertor::Task){ object, JSObjectMakeArray(contextRef, 0, NULL, 0), ContainerArray };
+
+ if ([object isKindOfClass:[NSDictionary class]])
+ return (ObjcContainerConvertor::Task){ object, JSObjectMake(contextRef, 0, 0), ContainerDictionary };
+
+ if ([object isKindOfClass:[NSNull class]])
+ return (ObjcContainerConvertor::Task){ object, JSValueMakeNull(contextRef), ContainerNone };
+
+ if ([object isKindOfClass:[JSValue class]])
+ return (ObjcContainerConvertor::Task){ object, ((JSValue *)object)->m_value, ContainerNone };
+
+ if ([object isKindOfClass:[NSString class]]) {
+ JSStringRef string = JSStringCreateWithCFString((CFStringRef)object);
+ JSValueRef js = JSValueMakeString(contextRef, string);
+ JSStringRelease(string);
+ return (ObjcContainerConvertor::Task){ object, js, ContainerNone };
+ }
+
+ if ([object isKindOfClass:[NSNumber class]]) {
+ if (isNSBoolean(object))
+ return (ObjcContainerConvertor::Task){ object, JSValueMakeBoolean(contextRef, [object boolValue]), ContainerNone };
+ return (ObjcContainerConvertor::Task){ object, JSValueMakeNumber(contextRef, [object doubleValue]), ContainerNone };
+ }
+
+ if ([object isKindOfClass:[NSDate class]]) {
+ JSValueRef argument = JSValueMakeNumber(contextRef, [object timeIntervalSince1970]);
+ JSObjectRef result = JSObjectMakeDate(contextRef, 1, &argument, 0);
+ return (ObjcContainerConvertor::Task){ object, result, ContainerNone };
+ }
+
+ if ([object isKindOfClass:[JSManagedValue class]]) {
+ JSValue *value = [static_cast<JSManagedValue *>(object) value];
+ if (!value)
+ return (ObjcContainerConvertor::Task) { object, JSValueMakeUndefined(contextRef), ContainerNone };
+ return (ObjcContainerConvertor::Task){ object, value->m_value, ContainerNone };
+ }
+ }
+
+ return (ObjcContainerConvertor::Task){ object, valueInternalValue([context wrapperForObjCObject:object]), ContainerNone };
+}
+
+JSValueRef objectToValue(JSContext *context, id object)
+{
+ JSGlobalContextRef contextRef = [context JSGlobalContextRef];
+
+ ObjcContainerConvertor::Task task = objectToValueWithoutCopy(context, object);
+ if (task.type == ContainerNone)
+ return task.js;
+
+ ObjcContainerConvertor convertor(context);
+ convertor.add(task);
+ ASSERT(!convertor.isWorkListEmpty());
+
+ do {
+ ObjcContainerConvertor::Task current = convertor.take();
+ ASSERT(JSValueIsObject(contextRef, current.js));
+ JSObjectRef js = JSValueToObject(contextRef, current.js, 0);
+
+ if (current.type == ContainerArray) {
+ ASSERT([current.objc isKindOfClass:[NSArray class]]);
+ NSArray *array = (NSArray *)current.objc;
+ NSUInteger count = [array count];
+ for (NSUInteger index = 0; index < count; ++index)
+ JSObjectSetPropertyAtIndex(contextRef, js, index, convertor.convert([array objectAtIndex:index]), 0);
+ } else {
+ ASSERT(current.type == ContainerDictionary);
+ ASSERT([current.objc isKindOfClass:[NSDictionary class]]);
+ NSDictionary *dictionary = (NSDictionary *)current.objc;
+ for (id key in [dictionary keyEnumerator]) {
+ if ([key isKindOfClass:[NSString class]]) {
+ JSStringRef propertyName = JSStringCreateWithCFString((CFStringRef)key);
+ JSObjectSetProperty(contextRef, js, propertyName, convertor.convert([dictionary objectForKey:key]), 0, 0);
+ JSStringRelease(propertyName);
+ }
+ }
+ }
+
+ } while (!convertor.isWorkListEmpty());
+
+ return task.js;
+}
+
+JSValueRef valueInternalValue(JSValue * value)
+{
+ return value->m_value;
+}
+
++ (JSValue *)valueWithJSValueRef:(JSValueRef)value inContext:(JSContext *)context
+{
+ return [context wrapperForJSObject:value];
+}
+
+- (JSValue *)init
+{
+ return nil;
+}
+
+- (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context
+{
+ if (!value || !context)
+ return nil;
+
+ self = [super init];
+ if (!self)
+ return nil;
+
+ _context = [context retain];
+ m_value = value;
+ JSValueProtect([_context JSGlobalContextRef], m_value);
+ return self;
+}
+
+struct StructTagHandler {
+ SEL typeToValueSEL;
+ SEL valueToTypeSEL;
+};
+typedef HashMap<String, StructTagHandler> StructHandlers;
+
+static StructHandlers* createStructHandlerMap()
+{
+ StructHandlers* structHandlers = new StructHandlers();
+
+ size_t valueWithXinContextLength = strlen("valueWithX:inContext:");
+ size_t toXLength = strlen("toX");
+
+ // Step 1: find all valueWith<Foo>:inContext: class methods in JSValue.
+ forEachMethodInClass(object_getClass([JSValue class]), ^(Method method){
+ SEL selector = method_getName(method);
+ const char* name = sel_getName(selector);
+ size_t nameLength = strlen(name);
+ // Check for valueWith<Foo>:context:
+ if (nameLength < valueWithXinContextLength || memcmp(name, "valueWith", 9) || memcmp(name + nameLength - 11, ":inContext:", 11))
+ return;
+ // Check for [ id, SEL, <type>, <contextType> ]
+ if (method_getNumberOfArguments(method) != 4)
+ return;
+ char idType[3];
+ // Check 2nd argument type is "@"
+ char* secondType = method_copyArgumentType(method, 3);
+ if (strcmp(secondType, "@") != 0) {
+ free(secondType);
+ return;
+ }
+ free(secondType);
+ // Check result type is also "@"
+ method_getReturnType(method, idType, 3);
+ if (strcmp(idType, "@") != 0)
+ return;
+ char* type = method_copyArgumentType(method, 2);
+ structHandlers->add(StringImpl::create(type), (StructTagHandler){ selector, 0 });
+ free(type);
+ });
+
+ // Step 2: find all to<Foo> instance methods in JSValue.
+ forEachMethodInClass([JSValue class], ^(Method method){
+ SEL selector = method_getName(method);
+ const char* name = sel_getName(selector);
+ size_t nameLength = strlen(name);
+ // Check for to<Foo>
+ if (nameLength < toXLength || memcmp(name, "to", 2))
+ return;
+ // Check for [ id, SEL ]
+ if (method_getNumberOfArguments(method) != 2)
+ return;
+ // Try to find a matching valueWith<Foo>:context: method.
+ char* type = method_copyReturnType(method);
+
+ StructHandlers::iterator iter = structHandlers->find(type);
+ free(type);
+ if (iter == structHandlers->end())
+ return;
+ StructTagHandler& handler = iter->value;
+
+ // check that strlen(<foo>) == strlen(<Foo>)
+ const char* valueWithName = sel_getName(handler.typeToValueSEL);
+ size_t valueWithLength = strlen(valueWithName);
+ if (valueWithLength - valueWithXinContextLength != nameLength - toXLength)
+ return;
+ // Check that <Foo> == <Foo>
+ if (memcmp(valueWithName + 9, name + 2, nameLength - toXLength - 1))
+ return;
+ handler.valueToTypeSEL = selector;
+ });
+
+ // Step 3: clean up - remove entries where we found prospective valueWith<Foo>:inContext: conversions, but no matching to<Foo> methods.
+ typedef HashSet<String> RemoveSet;
+ RemoveSet removeSet;
+ for (StructHandlers::iterator iter = structHandlers->begin(); iter != structHandlers->end(); ++iter) {
+ StructTagHandler& handler = iter->value;
+ if (!handler.valueToTypeSEL)
+ removeSet.add(iter->key);
+ }
+
+ for (RemoveSet::iterator iter = removeSet.begin(); iter != removeSet.end(); ++iter)
+ structHandlers->remove(*iter);
+
+ return structHandlers;
+}
+
+static StructTagHandler* handerForStructTag(const char* encodedType)
+{
+ static SpinLock handerForStructTagLock = SPINLOCK_INITIALIZER;
+ SpinLockHolder lockHolder(&handerForStructTagLock);
+
+ static StructHandlers* structHandlers = createStructHandlerMap();
+
+ StructHandlers::iterator iter = structHandlers->find(encodedType);
+ if (iter == structHandlers->end())
+ return 0;
+ return &iter->value;
+}
+
++ (SEL)selectorForStructToValue:(const char *)structTag
+{
+ StructTagHandler* handler = handerForStructTag(structTag);
+ return handler ? handler->typeToValueSEL : nil;
+}
+
++ (SEL)selectorForValueToStruct:(const char *)structTag
+{
+ StructTagHandler* handler = handerForStructTag(structTag);
+ return handler ? handler->valueToTypeSEL : nil;
+}
+
+- (void)dealloc
+{
+ JSValueUnprotect([_context JSGlobalContextRef], m_value);
+ [_context release];
+ _context = nil;
+ [super dealloc];
+}
+
+- (NSString *)description
+{
+ if (id wrapped = tryUnwrapObjcObject([_context JSGlobalContextRef], m_value))
+ return [wrapped description];
+ return [self toString];
+}
+
+NSInvocation *typeToValueInvocationFor(const char* encodedType)
+{
+ SEL selector = [JSValue selectorForStructToValue:encodedType];
+ if (!selector)
+ return 0;
+
+ const char* methodTypes = method_getTypeEncoding(class_getClassMethod([JSValue class], selector));
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:methodTypes]];
+ [invocation setSelector:selector];
+ return invocation;
+}
+
+NSInvocation *valueToTypeInvocationFor(const char* encodedType)
+{
+ SEL selector = [JSValue selectorForValueToStruct:encodedType];
+ if (!selector)
+ return 0;
+
+ const char* methodTypes = method_getTypeEncoding(class_getInstanceMethod([JSValue class], selector));
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:methodTypes]];
+ [invocation setSelector:selector];
+ return invocation;
+}
+
+@end
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSValueInternal.h b/Source/JavaScriptCore/API/JSValueInternal.h
new file mode 100644
index 000000000..4f1a8f69c
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSValueInternal.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSValueInternal_h
+#define JSValueInternal_h
+
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <JavaScriptCore/JSValue.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@interface JSValue(Internal)
+
+JSValueRef valueInternalValue(JSValue *);
+
+- (JSValue *)initWithValue:(JSValueRef)value inContext:(JSContext *)context;
+
+JSValueRef objectToValue(JSContext *, id);
+id valueToObject(JSContext *, JSValueRef);
+id valueToNumber(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToString(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToDate(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToArray(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+id valueToDictionary(JSGlobalContextRef, JSValueRef, JSValueRef* exception);
+
++ (SEL)selectorForStructToValue:(const char *)structTag;
++ (SEL)selectorForValueToStruct:(const char *)structTag;
+
+@end
+
+NSInvocation *typeToValueInvocationFor(const char* encodedType);
+NSInvocation *valueToTypeInvocationFor(const char* encodedType);
+
+#endif
+
+#endif // JSValueInternal_h
diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp
index 5ff7c03c6..81a2db7b7 100644
--- a/Source/JavaScriptCore/API/JSValueRef.cpp
+++ b/Source/JavaScriptCore/API/JSValueRef.cpp
@@ -28,15 +28,16 @@
#include "APICast.h"
#include "APIShims.h"
+#include "JSAPIWrapperObject.h"
#include "JSCallbackObject.h"
+#include <runtime/JSCJSValue.h>
#include <runtime/JSGlobalObject.h>
#include <runtime/JSONObject.h>
#include <runtime/JSString.h>
#include <runtime/LiteralParser.h>
#include <runtime/Operations.h>
#include <runtime/Protect.h>
-#include <runtime/JSValue.h>
#include <wtf/Assertions.h>
#include <wtf/text/StringHash.h>
@@ -44,10 +45,29 @@
#include <algorithm> // for std::min
+#if PLATFORM(MAC)
+#include <mach-o/dyld.h>
+#endif
+
using namespace JSC;
+#if PLATFORM(MAC)
+static bool evernoteHackNeeded()
+{
+ static const int32_t webkitLastVersionWithEvernoteHack = 35133959;
+ static bool hackNeeded = CFEqual(CFBundleGetIdentifier(CFBundleGetMainBundle()), CFSTR("com.evernote.Evernote"))
+ && NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitLastVersionWithEvernoteHack;
+
+ return hackNeeded;
+}
+#endif
+
::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return kJSTypeUndefined;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -69,6 +89,10 @@ using namespace JSC;
bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -78,6 +102,10 @@ bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -87,6 +115,10 @@ bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -96,6 +128,10 @@ bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -105,6 +141,10 @@ bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
bool JSValueIsString(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -114,6 +154,10 @@ bool JSValueIsString(JSContextRef ctx, JSValueRef value)
bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -123,6 +167,10 @@ bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
{
+ if (!ctx || !jsClass) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -133,12 +181,20 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla
return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass);
+#if JSC_OBJC_API_ENABLED
+ if (o->inherits(&JSCallbackObject<JSAPIWrapperObject>::s_info))
+ return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(o)->inherits(jsClass);
+#endif
}
return false;
}
bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -156,6 +212,10 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -167,6 +227,10 @@ bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -186,6 +250,10 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
JSValueRef JSValueMakeUndefined(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -194,6 +262,10 @@ JSValueRef JSValueMakeUndefined(JSContextRef ctx)
JSValueRef JSValueMakeNull(JSContextRef ctx)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -202,6 +274,10 @@ JSValueRef JSValueMakeNull(JSContextRef ctx)
JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -210,13 +286,17 @@ JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
// Our JSValue representation relies on a standard bit pattern for NaN. NaNs
// generated internally to JavaScriptCore naturally have that representation,
// but an external NaN might not.
- if (isnan(value))
+ if (std::isnan(value))
value = QNaN;
return toRef(exec, jsNumber(value));
@@ -224,6 +304,10 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -232,6 +316,10 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
String str = string->string();
@@ -246,6 +334,10 @@ JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsigned indent, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSValue value = toJS(exec, apiValue);
@@ -263,6 +355,10 @@ JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsig
bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -272,6 +368,10 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return QNaN;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -289,6 +389,10 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -306,6 +410,10 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -323,6 +431,10 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
void JSValueProtect(JSContextRef ctx, JSValueRef value)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
@@ -332,6 +444,11 @@ void JSValueProtect(JSContextRef ctx, JSValueRef value)
void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
{
+#if PLATFORM(MAC)
+ if ((!value || !ctx) && evernoteHackNeeded())
+ return;
+#endif
+
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
diff --git a/Source/JavaScriptCore/API/JSVirtualMachine.h b/Source/JavaScriptCore/API/JSVirtualMachine.h
new file mode 100644
index 000000000..b50616f4c
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSVirtualMachine.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+// An instance of JSVirtualMachine represents a single JavaScript "object space"
+// or set of execution resources. Thread safety is supported by locking the
+// virtual machine, with concurrent JavaScript execution supported by allocating
+// separate instances of JSVirtualMachine.
+
+NS_CLASS_AVAILABLE(10_9, NA)
+@interface JSVirtualMachine : NSObject
+
+// Create a new JSVirtualMachine.
+- (id)init;
+
+// addManagedReference:withOwner and removeManagedReference:withOwner allow
+// clients of JSVirtualMachine to make the JavaScript runtime aware of
+// arbitrary external Objective-C object graphs. The runtime can then use
+// this information to retain any JavaScript values that are referenced
+// from somewhere in said object graph.
+//
+// For correct behavior clients must make their external object graphs
+// reachable from within the JavaScript runtime. If an Objective-C object is
+// reachable from within the JavaScript runtime, all managed references
+// transitively reachable from it as recorded with
+// addManagedReference:withOwner: will be scanned by the garbage collector.
+//
+- (void)addManagedReference:(id)object withOwner:(id)owner;
+- (void)removeManagedReference:(id)object withOwner:(id)owner;
+
+@end
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSVirtualMachine.mm b/Source/JavaScriptCore/API/JSVirtualMachine.mm
new file mode 100644
index 000000000..6bada34a6
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSVirtualMachine.mm
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#import "JavaScriptCore.h"
+
+#if JSC_OBJC_API_ENABLED
+
+#import "APICast.h"
+#import "APIShims.h"
+#import "JSVirtualMachine.h"
+#import "JSVirtualMachineInternal.h"
+#import "JSWrapperMap.h"
+
+static NSMapTable *globalWrapperCache = 0;
+
+static Mutex& wrapperCacheLock()
+{
+ DEFINE_STATIC_LOCAL(Mutex, mutex, ());
+ return mutex;
+}
+
+static void initWrapperCache()
+{
+ ASSERT(!globalWrapperCache);
+ NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
+ NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
+ globalWrapperCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
+}
+
+static NSMapTable *wrapperCache()
+{
+ if (!globalWrapperCache)
+ initWrapperCache();
+ return globalWrapperCache;
+}
+
+@interface JSVMWrapperCache : NSObject
++ (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group;
++ (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group;
+@end
+
+@implementation JSVMWrapperCache
+
++ (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group
+{
+ MutexLocker locker(wrapperCacheLock());
+ NSMapInsert(wrapperCache(), group, wrapper);
+}
+
++ (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group
+{
+ MutexLocker locker(wrapperCacheLock());
+ return static_cast<JSVirtualMachine *>(NSMapGet(wrapperCache(), group));
+}
+
+@end
+
+@implementation JSVirtualMachine {
+ JSContextGroupRef m_group;
+ NSMapTable *m_contextCache;
+ NSMapTable *m_externalObjectGraph;
+}
+
+- (id)init
+{
+ JSContextGroupRef group = JSContextGroupCreate();
+ self = [self initWithContextGroupRef:group];
+ // The extra JSContextGroupRetain is balanced here.
+ JSContextGroupRelease(group);
+ return self;
+}
+
+- (id)initWithContextGroupRef:(JSContextGroupRef)group
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ m_group = JSContextGroupRetain(group);
+
+ NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
+ NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
+ m_contextCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
+
+ NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
+ NSPointerFunctionsOptions strongIDOptions = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality;
+ m_externalObjectGraph = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:strongIDOptions capacity:0];
+
+ [JSVMWrapperCache addWrapper:self forJSContextGroupRef:group];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ JSContextGroupRelease(m_group);
+ [m_contextCache release];
+ [m_externalObjectGraph release];
+ [super dealloc];
+}
+
+static id getInternalObjcObject(id object)
+{
+ if ([object isKindOfClass:[JSManagedValue class]]) {
+ JSValue* value = [static_cast<JSManagedValue *>(object) value];
+ id temp = tryUnwrapObjcObject([value.context JSGlobalContextRef], [value JSValueRef]);
+ if (temp)
+ return temp;
+ return object;
+ }
+
+ if ([object isKindOfClass:[JSValue class]]) {
+ JSValue *value = static_cast<JSValue *>(object);
+ object = tryUnwrapObjcObject([value.context JSGlobalContextRef], [value JSValueRef]);
+ }
+
+ return object;
+}
+
+- (void)addManagedReference:(id)object withOwner:(id)owner
+{
+ object = getInternalObjcObject(object);
+ owner = getInternalObjcObject(owner);
+
+ if (!object || !owner)
+ return;
+
+ JSC::APIEntryShim shim(toJS(m_group));
+
+ NSMapTable *ownedObjects = [m_externalObjectGraph objectForKey:owner];
+ if (!ownedObjects) {
+ NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
+ NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
+ ownedObjects = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:1];
+
+ [m_externalObjectGraph setObject:ownedObjects forKey:owner];
+ [ownedObjects release];
+ }
+ NSMapInsert(ownedObjects, object, reinterpret_cast<void*>(reinterpret_cast<size_t>(NSMapGet(ownedObjects, object)) + 1));
+}
+
+- (void)removeManagedReference:(id)object withOwner:(id)owner
+{
+ object = getInternalObjcObject(object);
+ owner = getInternalObjcObject(owner);
+
+ if (!object || !owner)
+ return;
+
+ JSC::APIEntryShim shim(toJS(m_group));
+
+ NSMapTable *ownedObjects = [m_externalObjectGraph objectForKey:owner];
+ if (!ownedObjects)
+ return;
+
+ size_t count = reinterpret_cast<size_t>(NSMapGet(ownedObjects, object));
+ if (count > 1) {
+ NSMapInsert(ownedObjects, object, reinterpret_cast<void*>(count - 1));
+ return;
+ }
+
+ if (count == 1)
+ NSMapRemove(ownedObjects, object);
+
+ if (![ownedObjects count])
+ [m_externalObjectGraph removeObjectForKey:owner];
+}
+
+@end
+
+@implementation JSVirtualMachine(Internal)
+
+JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *virtualMachine)
+{
+ return virtualMachine->m_group;
+}
+
++ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group
+{
+ JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:group];
+ if (!virtualMachine)
+ virtualMachine = [[[JSVirtualMachine alloc] initWithContextGroupRef:group] autorelease];
+ return virtualMachine;
+}
+
+- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext
+{
+ return static_cast<JSContext *>(NSMapGet(m_contextCache, globalContext));
+}
+
+- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext
+{
+ NSMapInsert(m_contextCache, globalContext, wrapper);
+}
+
+- (NSMapTable *)externalObjectGraph
+{
+ return m_externalObjectGraph;
+}
+
+@end
+
+void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root)
+{
+ @autoreleasepool {
+ JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
+ if (!virtualMachine)
+ return;
+ NSMapTable *externalObjectGraph = [virtualMachine externalObjectGraph];
+ Vector<void*> stack;
+ stack.append(root);
+ while (!stack.isEmpty()) {
+ void* nextRoot = stack.last();
+ stack.removeLast();
+ if (visitor.containsOpaqueRootTriState(nextRoot) == TrueTriState)
+ continue;
+ visitor.addOpaqueRoot(nextRoot);
+
+ NSMapTable *ownedObjects = [externalObjectGraph objectForKey:static_cast<id>(nextRoot)];
+ id ownedObject;
+ NSEnumerator *enumerator = [ownedObjects keyEnumerator];
+ while ((ownedObject = [enumerator nextObject])) {
+ ASSERT(reinterpret_cast<size_t>(NSMapGet(ownedObjects, ownedObject)) == 1);
+ stack.append(static_cast<void*>(ownedObject));
+ }
+ }
+ }
+}
+
+#endif
+
diff --git a/Source/JavaScriptCore/API/JSVirtualMachineInternal.h b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
new file mode 100644
index 000000000..729226566
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSVirtualMachineInternal_h
+#define JSVirtualMachineInternal_h
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+#if JSC_OBJC_API_ENABLED
+
+namespace JSC {
+class VM;
+class SlotVisitor;
+}
+
+#if defined(__OBJC__)
+@interface JSVirtualMachine(Internal)
+
+JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *);
+
++ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group;
+
+- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext;
+- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
+
+- (NSMapTable *)externalObjectGraph;
+
+@end
+#endif // defined(__OBJC__)
+
+void scanExternalObjectGraph(JSC::VM&, JSC::SlotVisitor&, void* root);
+
+#endif
+
+#endif // JSVirtualMachineInternal_h
diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
index bdfce08ee..8cbe263a7 100644
--- a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
+++ b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
@@ -28,9 +28,11 @@
#include "APICast.h"
#include "APIShims.h"
+#include "JSCJSValue.h"
#include "JSCallbackObject.h"
-#include "JSValue.h"
#include "JSWeakObjectMapRefInternal.h"
+#include "Operations.h"
+#include "Weak.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
@@ -52,17 +54,25 @@ JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef context, void* privateData
void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
JSObject* obj = toJS(object);
if (!obj)
return;
ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSDestructibleObject>::s_info));
- map->map().set(exec->globalData(), key, obj);
+ map->map().set(key, obj);
}
JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
return toRef(jsCast<JSObject*>(map->map().get(key)));
@@ -70,6 +80,10 @@ JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* k
void JSWeakObjectMapRemove(JSContextRef ctx, JSWeakObjectMapRef map, void* key)
{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
map->map().remove(key);
diff --git a/Source/JavaScriptCore/API/JSWrapperMap.h b/Source/JavaScriptCore/API/JSWrapperMap.h
new file mode 100644
index 000000000..ce74a9c61
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSWrapperMap.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <JavaScriptCore/JavaScriptCore.h>
+#import <JSValueInternal.h>
+#import <objc/objc-runtime.h>
+
+#if JSC_OBJC_API_ENABLED
+
+@interface JSWrapperMap : NSObject
+
+- (id)initWithContext:(JSContext *)context;
+
+- (JSValue *)jsWrapperForObject:(id)object;
+
+- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value;
+
+@end
+
+id tryUnwrapObjcObject(JSGlobalContextRef, JSValueRef);
+
+Protocol *getJSExportProtocol();
+Class getNSBlockClass();
+
+#endif
diff --git a/Source/JavaScriptCore/API/JSWrapperMap.mm b/Source/JavaScriptCore/API/JSWrapperMap.mm
new file mode 100644
index 000000000..4dde1a659
--- /dev/null
+++ b/Source/JavaScriptCore/API/JSWrapperMap.mm
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#import "JavaScriptCore.h"
+
+#if JSC_OBJC_API_ENABLED
+
+#import "APICast.h"
+#import "APIShims.h"
+#import "JSAPIWrapperObject.h"
+#import "JSCallbackObject.h"
+#import "JSContextInternal.h"
+#import "JSWrapperMap.h"
+#import "ObjCCallbackFunction.h"
+#import "ObjcRuntimeExtras.h"
+#import "Operations.h"
+#import "WeakGCMap.h"
+#import <wtf/TCSpinLock.h>
+#import <wtf/Vector.h>
+
+@class JSObjCClassInfo;
+
+@interface JSWrapperMap ()
+
+- (JSObjCClassInfo*)classInfoForClass:(Class)cls;
+
+@end
+
+// Default conversion of selectors to property names.
+// All semicolons are removed, lowercase letters following a semicolon are capitalized.
+static NSString *selectorToPropertyName(const char* start)
+{
+ // Use 'index' to check for colons, if there are none, this is easy!
+ const char* firstColon = index(start, ':');
+ if (!firstColon)
+ return [NSString stringWithUTF8String:start];
+
+ // 'header' is the length of string up to the first colon.
+ size_t header = firstColon - start;
+ // The new string needs to be long enough to hold 'header', plus the remainder of the string, excluding
+ // at least one ':', but including a '\0'. (This is conservative if there are more than one ':').
+ char* buffer = static_cast<char*>(malloc(header + strlen(firstColon + 1) + 1));
+ // Copy 'header' characters, set output to point to the end of this & input to point past the first ':'.
+ memcpy(buffer, start, header);
+ char* output = buffer + header;
+ const char* input = start + header + 1;
+
+ // On entry to the loop, we have already skipped over a ':' from the input.
+ while (true) {
+ char c;
+ // Skip over any additional ':'s. We'll leave c holding the next character after the
+ // last ':', and input pointing past c.
+ while ((c = *(input++)) == ':');
+ // Copy the character, converting to upper case if necessary.
+ // If the character we copy is '\0', then we're done!
+ if (!(*(output++) = toupper(c)))
+ goto done;
+ // Loop over characters other than ':'.
+ while ((c = *(input++)) != ':') {
+ // Copy the character.
+ // If the character we copy is '\0', then we're done!
+ if (!(*(output++) = c))
+ goto done;
+ }
+ // If we get here, we've consumed a ':' - wash, rinse, repeat.
+ }
+done:
+ NSString *result = [NSString stringWithUTF8String:buffer];
+ free(buffer);
+ return result;
+}
+
+static JSObjectRef makeWrapper(JSContextRef ctx, JSClassRef jsClass, id wrappedObject)
+{
+ JSC::ExecState* exec = toJS(ctx);
+ JSC::APIEntryShim entryShim(exec);
+
+ ASSERT(jsClass);
+ JSC::JSCallbackObject<JSC::JSAPIWrapperObject>* object = JSC::JSCallbackObject<JSC::JSAPIWrapperObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->objcWrapperObjectStructure(), jsClass, 0);
+ object->setWrappedObject(wrappedObject);
+ if (JSC::JSObject* prototype = jsClass->prototype(exec))
+ object->setPrototype(exec->vm(), prototype);
+
+ return toRef(object);
+}
+
+// Make an object that is in all ways a completely vanilla JavaScript object,
+// other than that it has a native brand set that will be displayed by the default
+// Object.prototype.toString conversion.
+static JSValue *objectWithCustomBrand(JSContext *context, NSString *brand, Class cls = 0)
+{
+ JSClassDefinition definition;
+ definition = kJSClassDefinitionEmpty;
+ definition.className = [brand UTF8String];
+ JSClassRef classRef = JSClassCreate(&definition);
+ JSObjectRef result = makeWrapper([context JSGlobalContextRef], classRef, cls);
+ JSClassRelease(classRef);
+ return [JSValue valueWithJSValueRef:result inContext:context];
+}
+
+// Look for @optional properties in the prototype containing a selector to property
+// name mapping, separated by a __JS_EXPORT_AS__ delimiter.
+static NSMutableDictionary *createRenameMap(Protocol *protocol, BOOL isInstanceMethod)
+{
+ NSMutableDictionary *renameMap = [[NSMutableDictionary alloc] init];
+
+ forEachMethodInProtocol(protocol, NO, isInstanceMethod, ^(SEL sel, const char*){
+ NSString *rename = @(sel_getName(sel));
+ NSRange range = [rename rangeOfString:@"__JS_EXPORT_AS__"];
+ if (range.location == NSNotFound)
+ return;
+ NSString *selector = [rename substringToIndex:range.location];
+ NSUInteger begin = range.location + range.length;
+ NSUInteger length = [rename length] - begin - 1;
+ NSString *name = [rename substringWithRange:(NSRange){ begin, length }];
+ renameMap[selector] = name;
+ });
+
+ return renameMap;
+}
+
+inline void putNonEnumerable(JSValue *base, NSString *propertyName, JSValue *value)
+{
+ [base defineProperty:propertyName descriptor:@{
+ JSPropertyDescriptorValueKey: value,
+ JSPropertyDescriptorWritableKey: @YES,
+ JSPropertyDescriptorEnumerableKey: @NO,
+ JSPropertyDescriptorConfigurableKey: @YES
+ }];
+}
+
+// This method will iterate over the set of required methods in the protocol, and:
+// * Determine a property name (either via a renameMap or default conversion).
+// * If an accessorMap is provided, and contains this name, store the method in the map.
+// * Otherwise, if the object doesn't already contain a property with name, create it.
+static void copyMethodsToObject(JSContext *context, Class objcClass, Protocol *protocol, BOOL isInstanceMethod, JSValue *object, NSMutableDictionary *accessorMethods = nil)
+{
+ NSMutableDictionary *renameMap = createRenameMap(protocol, isInstanceMethod);
+
+ forEachMethodInProtocol(protocol, YES, isInstanceMethod, ^(SEL sel, const char* types){
+ const char* nameCStr = sel_getName(sel);
+ NSString *name = @(nameCStr);
+ if (accessorMethods && accessorMethods[name]) {
+ JSObjectRef method = objCCallbackFunctionForMethod(context, objcClass, protocol, isInstanceMethod, sel, types);
+ if (!method)
+ return;
+ accessorMethods[name] = [JSValue valueWithJSValueRef:method inContext:context];
+ } else {
+ name = renameMap[name];
+ if (!name)
+ name = selectorToPropertyName(nameCStr);
+ if ([object hasProperty:name])
+ return;
+ JSObjectRef method = objCCallbackFunctionForMethod(context, objcClass, protocol, isInstanceMethod, sel, types);
+ if (method)
+ putNonEnumerable(object, name, [JSValue valueWithJSValueRef:method inContext:context]);
+ }
+ });
+
+ [renameMap release];
+}
+
+static bool parsePropertyAttributes(objc_property_t property, char*& getterName, char*& setterName)
+{
+ bool readonly = false;
+ unsigned attributeCount;
+ objc_property_attribute_t* attributes = property_copyAttributeList(property, &attributeCount);
+ if (attributeCount) {
+ for (unsigned i = 0; i < attributeCount; ++i) {
+ switch (*(attributes[i].name)) {
+ case 'G':
+ getterName = strdup(attributes[i].value);
+ break;
+ case 'S':
+ setterName = strdup(attributes[i].value);
+ break;
+ case 'R':
+ readonly = true;
+ break;
+ default:
+ break;
+ }
+ }
+ free(attributes);
+ }
+ return readonly;
+}
+
+static char* makeSetterName(const char* name)
+{
+ size_t nameLength = strlen(name);
+ char* setterName = (char*)malloc(nameLength + 5); // "set" Name ":\0"
+ setterName[0] = 's';
+ setterName[1] = 'e';
+ setterName[2] = 't';
+ setterName[3] = toupper(*name);
+ memcpy(setterName + 4, name + 1, nameLength - 1);
+ setterName[nameLength + 3] = ':';
+ setterName[nameLength + 4] = '\0';
+ return setterName;
+}
+
+static void copyPrototypeProperties(JSContext *context, Class objcClass, Protocol *protocol, JSValue *prototypeValue)
+{
+ // First gather propreties into this list, then handle the methods (capturing the accessor methods).
+ struct Property {
+ const char* name;
+ char* getterName;
+ char* setterName;
+ };
+ __block Vector<Property> propertyList;
+
+ // Map recording the methods used as getters/setters.
+ NSMutableDictionary *accessorMethods = [NSMutableDictionary dictionary];
+
+ // Useful value.
+ JSValue *undefined = [JSValue valueWithUndefinedInContext:context];
+
+ forEachPropertyInProtocol(protocol, ^(objc_property_t property){
+ char* getterName = 0;
+ char* setterName = 0;
+ bool readonly = parsePropertyAttributes(property, getterName, setterName);
+ const char* name = property_getName(property);
+
+ // Add the names of the getter & setter methods to
+ if (!getterName)
+ getterName = strdup(name);
+ accessorMethods[@(getterName)] = undefined;
+ if (!readonly) {
+ if (!setterName)
+ setterName = makeSetterName(name);
+ accessorMethods[@(setterName)] = undefined;
+ }
+
+ // Add the properties to a list.
+ propertyList.append((Property){ name, getterName, setterName });
+ });
+
+ // Copy methods to the prototype, capturing accessors in the accessorMethods map.
+ copyMethodsToObject(context, objcClass, protocol, YES, prototypeValue, accessorMethods);
+
+ // Iterate the propertyList & generate accessor properties.
+ for (size_t i = 0; i < propertyList.size(); ++i) {
+ Property& property = propertyList[i];
+
+ JSValue *getter = accessorMethods[@(property.getterName)];
+ free(property.getterName);
+ ASSERT(![getter isUndefined]);
+
+ JSValue *setter = undefined;
+ if (property.setterName) {
+ setter = accessorMethods[@(property.setterName)];
+ free(property.setterName);
+ ASSERT(![setter isUndefined]);
+ }
+
+ [prototypeValue defineProperty:@(property.name) descriptor:@{
+ JSPropertyDescriptorGetKey: getter,
+ JSPropertyDescriptorSetKey: setter,
+ JSPropertyDescriptorEnumerableKey: @NO,
+ JSPropertyDescriptorConfigurableKey: @YES
+ }];
+ }
+}
+
+@interface JSObjCClassInfo : NSObject {
+ JSContext *m_context;
+ Class m_class;
+ bool m_block;
+ JSClassRef m_classRef;
+ JSC::Weak<JSC::JSObject> m_prototype;
+ JSC::Weak<JSC::JSObject> m_constructor;
+}
+
+- (id)initWithContext:(JSContext *)context forClass:(Class)cls superClassInfo:(JSObjCClassInfo*)superClassInfo;
+- (JSValue *)wrapperForObject:(id)object;
+- (JSValue *)constructor;
+
+@end
+
+@implementation JSObjCClassInfo
+
+- (id)initWithContext:(JSContext *)context forClass:(Class)cls superClassInfo:(JSObjCClassInfo*)superClassInfo
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ const char* className = class_getName(cls);
+ m_context = context;
+ m_class = cls;
+ m_block = [cls isSubclassOfClass:getNSBlockClass()];
+ JSClassDefinition definition;
+ definition = kJSClassDefinitionEmpty;
+ definition.className = className;
+ m_classRef = JSClassCreate(&definition);
+
+ [self allocateConstructorAndPrototypeWithSuperClassInfo:superClassInfo];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ JSClassRelease(m_classRef);
+ [super dealloc];
+}
+
+- (void)allocateConstructorAndPrototypeWithSuperClassInfo:(JSObjCClassInfo*)superClassInfo
+{
+ ASSERT(!m_constructor || !m_prototype);
+ ASSERT((m_class == [NSObject class]) == !superClassInfo);
+ if (!superClassInfo) {
+ JSContextRef cContext = [m_context JSGlobalContextRef];
+ JSValue *constructor = m_context[@"Object"];
+ if (!m_constructor)
+ m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
+
+ if (!m_prototype) {
+ JSValue *prototype = constructor[@"prototype"];
+ m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
+ }
+ } else {
+ const char* className = class_getName(m_class);
+
+ // Create or grab the prototype/constructor pair.
+ JSValue *prototype;
+ JSValue *constructor;
+ if (m_prototype)
+ prototype = [JSValue valueWithJSValueRef:toRef(m_prototype.get()) inContext:m_context];
+ else
+ prototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]);
+
+ if (m_constructor)
+ constructor = [JSValue valueWithJSValueRef:toRef(m_constructor.get()) inContext:m_context];
+ else
+ constructor = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sConstructor", className], m_class);
+
+ JSContextRef cContext = [m_context JSGlobalContextRef];
+ m_prototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0));
+ m_constructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0));
+
+ putNonEnumerable(prototype, @"constructor", constructor);
+ putNonEnumerable(constructor, @"prototype", prototype);
+
+ Protocol *exportProtocol = getJSExportProtocol();
+ forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol){
+ copyPrototypeProperties(m_context, m_class, protocol, prototype);
+ copyMethodsToObject(m_context, m_class, protocol, NO, constructor);
+ });
+
+ // Set [Prototype].
+ JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(m_prototype.get()), toRef(superClassInfo->m_prototype.get()));
+ }
+}
+
+- (void)reallocateConstructorAndOrPrototype
+{
+ [self allocateConstructorAndPrototypeWithSuperClassInfo:[m_context.wrapperMap classInfoForClass:class_getSuperclass(m_class)]];
+}
+
+- (JSValue *)wrapperForObject:(id)object
+{
+ ASSERT([object isKindOfClass:m_class]);
+ ASSERT(m_block == [object isKindOfClass:getNSBlockClass()]);
+ if (m_block) {
+ if (JSObjectRef method = objCCallbackFunctionForBlock(m_context, object))
+ return [JSValue valueWithJSValueRef:method inContext:m_context];
+ }
+
+ if (!m_prototype)
+ [self reallocateConstructorAndOrPrototype];
+ ASSERT(!!m_prototype);
+
+ JSObjectRef wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object);
+ JSObjectSetPrototype([m_context JSGlobalContextRef], wrapper, toRef(m_prototype.get()));
+ return [JSValue valueWithJSValueRef:wrapper inContext:m_context];
+}
+
+- (JSValue *)constructor
+{
+ if (!m_constructor)
+ [self reallocateConstructorAndOrPrototype];
+ ASSERT(!!m_constructor);
+ return [JSValue valueWithJSValueRef:toRef(m_constructor.get()) inContext:m_context];
+}
+
+@end
+
+@implementation JSWrapperMap {
+ JSContext *m_context;
+ NSMutableDictionary *m_classMap;
+ JSC::WeakGCMap<id, JSC::JSObject> m_cachedJSWrappers;
+ NSMapTable *m_cachedObjCWrappers;
+}
+
+- (id)initWithContext:(JSContext *)context
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
+ NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
+ m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
+
+ m_context = context;
+ m_classMap = [[NSMutableDictionary alloc] init];
+ return self;
+}
+
+- (void)dealloc
+{
+ [m_cachedObjCWrappers release];
+ [m_classMap release];
+ [super dealloc];
+}
+
+- (JSObjCClassInfo*)classInfoForClass:(Class)cls
+{
+ if (!cls)
+ return nil;
+
+ // Check if we've already created a JSObjCClassInfo for this Class.
+ if (JSObjCClassInfo* classInfo = (JSObjCClassInfo*)m_classMap[cls])
+ return classInfo;
+
+ // Skip internal classes beginning with '_' - just copy link to the parent class's info.
+ if ('_' == *class_getName(cls))
+ return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)];
+
+ return m_classMap[cls] = [[[JSObjCClassInfo alloc] initWithContext:m_context forClass:cls superClassInfo:[self classInfoForClass:class_getSuperclass(cls)]] autorelease];
+}
+
+- (JSValue *)jsWrapperForObject:(id)object
+{
+ JSC::JSObject* jsWrapper = m_cachedJSWrappers.get(object);
+ if (jsWrapper)
+ return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context];
+
+ JSValue *wrapper;
+ if (class_isMetaClass(object_getClass(object)))
+ wrapper = [[self classInfoForClass:(Class)object] constructor];
+ else {
+ JSObjCClassInfo* classInfo = [self classInfoForClass:[object class]];
+ wrapper = [classInfo wrapperForObject:object];
+ }
+
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105891
+ // This general approach to wrapper caching is pretty effective, but there are a couple of problems:
+ // (1) For immortal objects JSValues will effectively leak and this results in error output being logged - we should avoid adding associated objects to immortal objects.
+ // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects,
+ // but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc.
+ JSC::ExecState* exec = toJS([m_context JSGlobalContextRef]);
+ jsWrapper = toJS(exec, valueInternalValue(wrapper)).toObject(exec);
+ m_cachedJSWrappers.set(object, jsWrapper);
+ return wrapper;
+}
+
+- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value
+{
+ JSValue *wrapper = static_cast<JSValue *>(NSMapGet(m_cachedObjCWrappers, value));
+ if (!wrapper) {
+ wrapper = [[[JSValue alloc] initWithValue:value inContext:m_context] autorelease];
+ NSMapInsert(m_cachedObjCWrappers, value, wrapper);
+ }
+ return wrapper;
+}
+
+@end
+
+id tryUnwrapObjcObject(JSGlobalContextRef context, JSValueRef value)
+{
+ if (!JSValueIsObject(context, value))
+ return nil;
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject(context, value, &exception);
+ ASSERT(!exception);
+ if (toJS(object)->inherits(&JSC::JSCallbackObject<JSC::JSAPIWrapperObject>::s_info))
+ return (id)JSC::jsCast<JSC::JSAPIWrapperObject*>(toJS(object))->wrappedObject();
+ if (id target = tryUnwrapBlock(object))
+ return target;
+ return nil;
+}
+
+Protocol *getJSExportProtocol()
+{
+ static Protocol *protocol = objc_getProtocol("JSExport");
+ return protocol;
+}
+
+Class getNSBlockClass()
+{
+ static Class cls = objc_getClass("NSBlock");
+ return cls;
+}
+
+#endif
diff --git a/Source/JavaScriptCore/API/JavaScriptCore.h b/Source/JavaScriptCore/API/JavaScriptCore.h
index 87d601851..40bea9c3d 100644
--- a/Source/JavaScriptCore/API/JavaScriptCore.h
+++ b/Source/JavaScriptCore/API/JavaScriptCore.h
@@ -29,4 +29,14 @@
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/JSStringRefCF.h>
+#if defined(__OBJC__) && JSC_OBJC_API_ENABLED
+
+#import "JSContext.h"
+#import "JSValue.h"
+#import "JSManagedValue.h"
+#import "JSVirtualMachine.h"
+#import "JSExport.h"
+
+#endif
+
#endif /* JavaScriptCore_h */
diff --git a/Source/JavaScriptCore/API/ObjCCallbackFunction.h b/Source/JavaScriptCore/API/ObjCCallbackFunction.h
new file mode 100644
index 000000000..0218cd8b4
--- /dev/null
+++ b/Source/JavaScriptCore/API/ObjCCallbackFunction.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef ObjCCallbackFunction_h
+#define ObjCCallbackFunction_h
+
+#include <JavaScriptCore/JSBase.h>
+
+#if JSC_OBJC_API_ENABLED
+
+#import <JavaScriptCore/JSCallbackFunction.h>
+
+#if defined(__OBJC__)
+JSObjectRef objCCallbackFunctionForMethod(JSContext *, Class, Protocol *, BOOL isInstanceMethod, SEL, const char* types);
+JSObjectRef objCCallbackFunctionForBlock(JSContext *, id);
+
+id tryUnwrapBlock(JSObjectRef);
+#endif
+
+namespace JSC {
+
+class ObjCCallbackFunctionImpl;
+
+class ObjCCallbackFunction : public JSCallbackFunction {
+public:
+ typedef JSCallbackFunction Base;
+
+ static ObjCCallbackFunction* create(ExecState*, JSGlobalObject*, const String& name, PassOwnPtr<ObjCCallbackFunctionImpl>);
+ static void destroy(JSCell*);
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ ASSERT(globalObject);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ }
+
+ static JS_EXPORTDATA const ClassInfo s_info;
+
+ ObjCCallbackFunctionImpl* impl() { return m_impl.get(); }
+
+protected:
+ ObjCCallbackFunction(JSGlobalObject*, JSObjectCallAsFunctionCallback, PassOwnPtr<ObjCCallbackFunctionImpl>);
+
+private:
+ OwnPtr<ObjCCallbackFunctionImpl> m_impl;
+};
+
+} // namespace JSC
+
+#endif
+
+#endif // ObjCCallbackFunction_h
diff --git a/Source/JavaScriptCore/API/ObjCCallbackFunction.mm b/Source/JavaScriptCore/API/ObjCCallbackFunction.mm
new file mode 100644
index 000000000..cc342f59e
--- /dev/null
+++ b/Source/JavaScriptCore/API/ObjCCallbackFunction.mm
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#import "JavaScriptCore.h"
+
+#if JSC_OBJC_API_ENABLED
+
+#import "APICast.h"
+#import "APIShims.h"
+#import "Error.h"
+#import "JSCJSValueInlines.h"
+#import "JSCell.h"
+#import "JSCellInlines.h"
+#import "JSContextInternal.h"
+#import "JSWrapperMap.h"
+#import "JSValueInternal.h"
+#import "ObjCCallbackFunction.h"
+#import "ObjcRuntimeExtras.h"
+#import <objc/runtime.h>
+#import <wtf/RetainPtr.h>
+
+class CallbackArgument {
+public:
+ virtual ~CallbackArgument();
+ virtual void set(NSInvocation *, NSInteger, JSContext *, JSValueRef, JSValueRef*) = 0;
+
+ OwnPtr<CallbackArgument> m_next;
+};
+
+CallbackArgument::~CallbackArgument()
+{
+}
+
+class CallbackArgumentBoolean : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
+ {
+ bool value = JSValueToBoolean([context JSGlobalContextRef], argument);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+template<typename T>
+class CallbackArgumentInteger : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ T value = (T)JSC::toInt32(JSValueToNumber([context JSGlobalContextRef], argument, exception));
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+template<typename T>
+class CallbackArgumentDouble : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ T value = (T)JSValueToNumber([context JSGlobalContextRef], argument, exception);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentJSValue : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
+ {
+ JSValue *value = [JSValue valueWithJSValueRef:argument inContext:context];
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentId : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
+ {
+ id value = valueToObject(context, argument);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentOfClass : public CallbackArgument {
+public:
+ CallbackArgumentOfClass(Class cls)
+ : CallbackArgument()
+ , m_class(cls)
+ {
+ [m_class retain];
+ }
+
+private:
+ virtual ~CallbackArgumentOfClass()
+ {
+ [m_class release];
+ }
+
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ JSGlobalContextRef contextRef = [context JSGlobalContextRef];
+
+ id object = tryUnwrapObjcObject(contextRef, argument);
+ if (object && [object isKindOfClass:m_class]) {
+ [invocation setArgument:&object atIndex:argumentNumber];
+ return;
+ }
+
+ if (JSValueIsNull(contextRef, argument) || JSValueIsUndefined(contextRef, argument)) {
+ object = nil;
+ [invocation setArgument:&object atIndex:argumentNumber];
+ return;
+ }
+
+ *exception = toRef(JSC::createTypeError(toJS(contextRef), "Argument does not match Objective-C Class"));
+ }
+
+ Class m_class;
+};
+
+class CallbackArgumentNSNumber : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ id value = valueToNumber([context JSGlobalContextRef], argument, exception);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentNSString : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ id value = valueToString([context JSGlobalContextRef], argument, exception);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentNSDate : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ id value = valueToDate([context JSGlobalContextRef], argument, exception);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentNSArray : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ id value = valueToArray([context JSGlobalContextRef], argument, exception);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentNSDictionary : public CallbackArgument {
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef* exception) override
+ {
+ id value = valueToDictionary([context JSGlobalContextRef], argument, exception);
+ [invocation setArgument:&value atIndex:argumentNumber];
+ }
+};
+
+class CallbackArgumentStruct : public CallbackArgument {
+public:
+ CallbackArgumentStruct(NSInvocation *conversionInvocation, const char* encodedType)
+ : m_conversionInvocation(conversionInvocation)
+ , m_buffer(encodedType)
+ {
+ }
+
+private:
+ virtual void set(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef argument, JSValueRef*) override
+ {
+ JSValue *value = [JSValue valueWithJSValueRef:argument inContext:context];
+ [m_conversionInvocation invokeWithTarget:value];
+ [m_conversionInvocation getReturnValue:m_buffer];
+ [invocation setArgument:m_buffer atIndex:argumentNumber];
+ }
+
+ RetainPtr<NSInvocation> m_conversionInvocation;
+ StructBuffer m_buffer;
+};
+
+class ArgumentTypeDelegate {
+public:
+ typedef CallbackArgument* ResultType;
+
+ template<typename T>
+ static ResultType typeInteger()
+ {
+ return new CallbackArgumentInteger<T>;
+ }
+
+ template<typename T>
+ static ResultType typeDouble()
+ {
+ return new CallbackArgumentDouble<T>;
+ }
+
+ static ResultType typeBool()
+ {
+ return new CallbackArgumentBoolean;
+ }
+
+ static ResultType typeVoid()
+ {
+ RELEASE_ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+ static ResultType typeId()
+ {
+ return new CallbackArgumentId;
+ }
+
+ static ResultType typeOfClass(const char* begin, const char* end)
+ {
+ StringRange copy(begin, end);
+ Class cls = objc_getClass(copy);
+ if (!cls)
+ return 0;
+
+ if (cls == [JSValue class])
+ return new CallbackArgumentJSValue;
+ if (cls == [NSString class])
+ return new CallbackArgumentNSString;
+ if (cls == [NSNumber class])
+ return new CallbackArgumentNSNumber;
+ if (cls == [NSDate class])
+ return new CallbackArgumentNSDate;
+ if (cls == [NSArray class])
+ return new CallbackArgumentNSArray;
+ if (cls == [NSDictionary class])
+ return new CallbackArgumentNSDictionary;
+
+ return new CallbackArgumentOfClass(cls);
+ }
+
+ static ResultType typeBlock(const char*, const char*)
+ {
+ return nil;
+ }
+
+ static ResultType typeStruct(const char* begin, const char* end)
+ {
+ StringRange copy(begin, end);
+ if (NSInvocation *invocation = valueToTypeInvocationFor(copy))
+ return new CallbackArgumentStruct(invocation, copy);
+ return 0;
+ }
+};
+
+class CallbackResult {
+public:
+ virtual ~CallbackResult()
+ {
+ }
+
+ virtual JSValueRef get(NSInvocation *, JSContext *, JSValueRef*) = 0;
+};
+
+class CallbackResultVoid : public CallbackResult {
+ virtual JSValueRef get(NSInvocation *, JSContext *context, JSValueRef*) override
+ {
+ return JSValueMakeUndefined([context JSGlobalContextRef]);
+ }
+};
+
+class CallbackResultId : public CallbackResult {
+ virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
+ {
+ id value;
+ [invocation getReturnValue:&value];
+ return objectToValue(context, value);
+ }
+};
+
+template<typename T>
+class CallbackResultNumeric : public CallbackResult {
+ virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
+ {
+ T value;
+ [invocation getReturnValue:&value];
+ return JSValueMakeNumber([context JSGlobalContextRef], value);
+ }
+};
+
+class CallbackResultBoolean : public CallbackResult {
+ virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
+ {
+ bool value;
+ [invocation getReturnValue:&value];
+ return JSValueMakeBoolean([context JSGlobalContextRef], value);
+ }
+};
+
+class CallbackResultStruct : public CallbackResult {
+public:
+ CallbackResultStruct(NSInvocation *conversionInvocation, const char* encodedType)
+ : m_conversionInvocation(conversionInvocation)
+ , m_buffer(encodedType)
+ {
+ }
+
+private:
+ virtual JSValueRef get(NSInvocation *invocation, JSContext *context, JSValueRef*) override
+ {
+ [invocation getReturnValue:m_buffer];
+
+ [m_conversionInvocation setArgument:m_buffer atIndex:2];
+ [m_conversionInvocation setArgument:&context atIndex:3];
+ [m_conversionInvocation invokeWithTarget:[JSValue class]];
+
+ JSValue *value;
+ [m_conversionInvocation getReturnValue:&value];
+ return valueInternalValue(value);
+ }
+
+ RetainPtr<NSInvocation> m_conversionInvocation;
+ StructBuffer m_buffer;
+};
+
+class ResultTypeDelegate {
+public:
+ typedef CallbackResult* ResultType;
+
+ template<typename T>
+ static ResultType typeInteger()
+ {
+ return new CallbackResultNumeric<T>;
+ }
+
+ template<typename T>
+ static ResultType typeDouble()
+ {
+ return new CallbackResultNumeric<T>;
+ }
+
+ static ResultType typeBool()
+ {
+ return new CallbackResultBoolean;
+ }
+
+ static ResultType typeVoid()
+ {
+ return new CallbackResultVoid;
+ }
+
+ static ResultType typeId()
+ {
+ return new CallbackResultId();
+ }
+
+ static ResultType typeOfClass(const char*, const char*)
+ {
+ return new CallbackResultId();
+ }
+
+ static ResultType typeBlock(const char*, const char*)
+ {
+ return new CallbackResultId();
+ }
+
+ static ResultType typeStruct(const char* begin, const char* end)
+ {
+ StringRange copy(begin, end);
+ if (NSInvocation *invocation = typeToValueInvocationFor(copy))
+ return new CallbackResultStruct(invocation, copy);
+ return 0;
+ }
+};
+
+enum CallbackType {
+ CallbackInstanceMethod,
+ CallbackClassMethod,
+ CallbackBlock
+};
+
+namespace JSC {
+
+class ObjCCallbackFunctionImpl {
+public:
+ ObjCCallbackFunctionImpl(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, PassOwnPtr<CallbackArgument> arguments, PassOwnPtr<CallbackResult> result)
+ : m_context(context)
+ , m_type(type)
+ , m_instanceClass([instanceClass retain])
+ , m_invocation(invocation)
+ , m_arguments(arguments)
+ , m_result(result)
+ {
+ ASSERT(type != CallbackInstanceMethod || instanceClass);
+ }
+
+ ~ObjCCallbackFunctionImpl()
+ {
+ if (m_type != CallbackInstanceMethod)
+ [[m_invocation.get() target] release];
+ [m_instanceClass release];
+ }
+
+ JSValueRef call(JSContext *context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+
+ JSContext *context()
+ {
+ return m_context.get();
+ }
+
+ void setContext(JSContext *context)
+ {
+ ASSERT(!m_context.get());
+ m_context.set(context);
+ }
+
+ id wrappedBlock()
+ {
+ return m_type == CallbackBlock ? [m_invocation target] : nil;
+ }
+
+private:
+ WeakContextRef m_context;
+ CallbackType m_type;
+ Class m_instanceClass;
+ RetainPtr<NSInvocation> m_invocation;
+ OwnPtr<CallbackArgument> m_arguments;
+ OwnPtr<CallbackResult> m_result;
+};
+
+static JSValueRef objCCallbackFunctionCallAsFunction(JSContextRef callerContext, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Retake the API lock - we need this for a few reasons:
+ // (1) We don't want to support the C-API's confusing drops-locks-once policy - should only drop locks if we can do so recursively.
+ // (2) We're calling some JSC internals that require us to be on the 'inside' - e.g. createTypeError.
+ // (3) We need to be locked (per context would be fine) against conflicting usage of the ObjCCallbackFunction's NSInvocation.
+ JSC::APIEntryShim entryShim(toJS(callerContext));
+
+ ObjCCallbackFunction* callback = static_cast<ObjCCallbackFunction*>(toJS(function));
+ ObjCCallbackFunctionImpl* impl = callback->impl();
+ JSContext *context = impl->context();
+ if (!context) {
+ context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(toJS(callerContext)->lexicalGlobalObject()->globalExec())];
+ impl->setContext(context);
+ }
+
+ CallbackData callbackData;
+ JSValueRef result;
+ @autoreleasepool {
+ [context beginCallbackWithData:&callbackData thisValue:thisObject argumentCount:argumentCount arguments:arguments];
+ result = impl->call(context, thisObject, argumentCount, arguments, exception);
+ if (context.exception)
+ *exception = valueInternalValue(context.exception);
+ [context endCallbackWithData:&callbackData];
+ }
+ return result;
+}
+
+const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ObjCCallbackFunction) };
+
+ObjCCallbackFunction::ObjCCallbackFunction(JSC::JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
+ : Base(globalObject, globalObject->objcCallbackFunctionStructure(), callback)
+ , m_impl(impl)
+{
+}
+
+ObjCCallbackFunction* ObjCCallbackFunction::create(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject, const String& name, PassOwnPtr<ObjCCallbackFunctionImpl> impl)
+{
+ ObjCCallbackFunction* function = new (NotNull, allocateCell<ObjCCallbackFunction>(*exec->heap())) ObjCCallbackFunction(globalObject, objCCallbackFunctionCallAsFunction, impl);
+ function->finishCreation(exec->vm(), name);
+ return function;
+}
+
+void ObjCCallbackFunction::destroy(JSCell* cell)
+{
+ static_cast<ObjCCallbackFunction*>(cell)->ObjCCallbackFunction::~ObjCCallbackFunction();
+}
+
+JSValueRef ObjCCallbackFunctionImpl::call(JSContext *context, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ JSGlobalContextRef contextRef = [context JSGlobalContextRef];
+
+ size_t firstArgument;
+ switch (m_type) {
+ case CallbackInstanceMethod: {
+ id target = tryUnwrapObjcObject(contextRef, thisObject);
+ if (!target || ![target isKindOfClass:m_instanceClass]) {
+ *exception = toRef(JSC::createTypeError(toJS(contextRef), "self type check failed for Objective-C instance method"));
+ return JSValueMakeUndefined(contextRef);
+ }
+ [m_invocation setTarget:target];
+ }
+ // fallthrough - firstArgument for CallbackInstanceMethod is also 2!
+ case CallbackClassMethod:
+ firstArgument = 2;
+ break;
+ case CallbackBlock:
+ firstArgument = 1;
+ }
+
+ size_t argumentNumber = 0;
+ for (CallbackArgument* argument = m_arguments.get(); argument; argument = argument->m_next.get()) {
+ JSValueRef value = argumentNumber < argumentCount ? arguments[argumentNumber] : JSValueMakeUndefined(contextRef);
+ argument->set(m_invocation.get(), argumentNumber + firstArgument, context, value, exception);
+ if (*exception)
+ return JSValueMakeUndefined(contextRef);
+ ++argumentNumber;
+ }
+
+ [m_invocation invoke];
+
+ return m_result->get(m_invocation.get(), context, exception);
+}
+
+} // namespace JSC
+
+static bool blockSignatureContainsClass()
+{
+ static bool containsClass = ^{
+ id block = ^(NSString *string){ return string; };
+ return _Block_has_signature(block) && strstr(_Block_signature(block), "NSString");
+ }();
+ return containsClass;
+}
+
+inline bool skipNumber(const char*& position)
+{
+ if (!isASCIIDigit(*position))
+ return false;
+ while (isASCIIDigit(*++position)) { }
+ return true;
+}
+
+static JSObjectRef objCCallbackFunctionForInvocation(JSContext *context, NSInvocation *invocation, CallbackType type, Class instanceClass, const char* signatureWithObjcClasses)
+{
+ const char* position = signatureWithObjcClasses;
+
+ OwnPtr<CallbackResult> result = adoptPtr(parseObjCType<ResultTypeDelegate>(position));
+ if (!result || !skipNumber(position))
+ return nil;
+
+ switch (type) {
+ case CallbackInstanceMethod:
+ case CallbackClassMethod:
+ // Methods are passed two implicit arguments - (id)self, and the selector.
+ if ('@' != *position++ || !skipNumber(position) || ':' != *position++ || !skipNumber(position))
+ return nil;
+ break;
+ case CallbackBlock:
+ // Blocks are passed one implicit argument - the block, of type "@?".
+ if (('@' != *position++) || ('?' != *position++) || !skipNumber(position))
+ return nil;
+ // Only allow arguments of type 'id' if the block signature contains the NS type information.
+ if ((!blockSignatureContainsClass() && strchr(position, '@')))
+ return nil;
+ break;
+ }
+
+ OwnPtr<CallbackArgument> arguments = 0;
+ OwnPtr<CallbackArgument>* nextArgument = &arguments;
+ unsigned argumentCount = 0;
+ while (*position) {
+ OwnPtr<CallbackArgument> argument = adoptPtr(parseObjCType<ArgumentTypeDelegate>(position));
+ if (!argument || !skipNumber(position))
+ return nil;
+
+ *nextArgument = argument.release();
+ nextArgument = &(*nextArgument)->m_next;
+ ++argumentCount;
+ }
+
+ JSC::ExecState* exec = toJS([context JSGlobalContextRef]);
+ JSC::APIEntryShim shim(exec);
+ OwnPtr<JSC::ObjCCallbackFunctionImpl> impl = adoptPtr(new JSC::ObjCCallbackFunctionImpl(context, invocation, type, instanceClass, arguments.release(), result.release()));
+ // FIXME: Maybe we could support having the selector as the name of the function to make it a bit more user-friendly from the JS side?
+ return toRef(JSC::ObjCCallbackFunction::create(exec, exec->lexicalGlobalObject(), "", impl.release()));
+}
+
+JSObjectRef objCCallbackFunctionForMethod(JSContext *context, Class cls, Protocol *protocol, BOOL isInstanceMethod, SEL sel, const char* types)
+{
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:types]];
+ [invocation setSelector:sel];
+ if (!isInstanceMethod)
+ [invocation setTarget:cls];
+ return objCCallbackFunctionForInvocation(context, invocation, isInstanceMethod ? CallbackInstanceMethod : CallbackClassMethod, isInstanceMethod ? cls : nil, _protocol_getMethodTypeEncoding(protocol, sel, YES, isInstanceMethod));
+}
+
+JSObjectRef objCCallbackFunctionForBlock(JSContext *context, id target)
+{
+ if (!_Block_has_signature(target))
+ return 0;
+ const char* signature = _Block_signature(target);
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:signature]];
+ [invocation setTarget:[target copy]];
+ return objCCallbackFunctionForInvocation(context, invocation, CallbackBlock, nil, signature);
+}
+
+id tryUnwrapBlock(JSObjectRef object)
+{
+ if (!toJS(object)->inherits(&JSC::ObjCCallbackFunction::s_info))
+ return nil;
+ return static_cast<JSC::ObjCCallbackFunction*>(toJS(object))->impl()->wrappedBlock();
+}
+
+#endif
diff --git a/Source/JavaScriptCore/API/ObjcRuntimeExtras.h b/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
new file mode 100644
index 000000000..48c112093
--- /dev/null
+++ b/Source/JavaScriptCore/API/ObjcRuntimeExtras.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <objc/runtime.h>
+#import <wtf/HashSet.h>
+#import <wtf/Vector.h>
+
+inline bool protocolImplementsProtocol(Protocol *candidate, Protocol *target)
+{
+ unsigned protocolProtocolsCount;
+ Protocol ** protocolProtocols = protocol_copyProtocolList(candidate, &protocolProtocolsCount);
+ for (unsigned i = 0; i < protocolProtocolsCount; ++i) {
+ if (protocol_isEqual(protocolProtocols[i], target)) {
+ free(protocolProtocols);
+ return true;
+ }
+ }
+ free(protocolProtocols);
+ return false;
+}
+
+inline void forEachProtocolImplementingProtocol(Class cls, Protocol *target, void (^callback)(Protocol *))
+{
+ ASSERT(cls);
+ ASSERT(target);
+
+ Vector<Protocol *> worklist;
+ HashSet<void*> visited;
+
+ // Initially fill the worklist with the Class's protocols.
+ unsigned protocolsCount;
+ Protocol ** protocols = class_copyProtocolList(cls, &protocolsCount);
+ worklist.append(protocols, protocolsCount);
+ free(protocols);
+
+ while (!worklist.isEmpty()) {
+ Protocol *protocol = worklist.last();
+ worklist.removeLast();
+
+ // Are we encountering this Protocol for the first time?
+ if (!visited.add(protocol).isNewEntry)
+ continue;
+
+ // If it implements the protocol, make the callback.
+ if (protocolImplementsProtocol(protocol, target))
+ callback(protocol);
+
+ // Add incorporated protocols to the worklist.
+ protocols = protocol_copyProtocolList(protocol, &protocolsCount);
+ worklist.append(protocols, protocolsCount);
+ free(protocols);
+ }
+}
+
+inline void forEachMethodInClass(Class cls, void (^callback)(Method))
+{
+ unsigned count;
+ Method* methods = class_copyMethodList(cls, &count);
+ for (unsigned i = 0; i < count; ++i)
+ callback(methods[i]);
+ free(methods);
+}
+
+inline void forEachMethodInProtocol(Protocol *protocol, BOOL isRequiredMethod, BOOL isInstanceMethod, void (^callback)(SEL, const char*))
+{
+ unsigned count;
+ struct objc_method_description* methods = protocol_copyMethodDescriptionList(protocol, isRequiredMethod, isInstanceMethod, &count);
+ for (unsigned i = 0; i < count; ++i)
+ callback(methods[i].name, methods[i].types);
+ free(methods);
+}
+
+inline void forEachPropertyInProtocol(Protocol *protocol, void (^callback)(objc_property_t))
+{
+ unsigned count;
+ objc_property_t* properties = protocol_copyPropertyList(protocol, &count);
+ for (unsigned i = 0; i < count; ++i)
+ callback(properties[i]);
+ free(properties);
+}
+
+template<char open, char close>
+void skipPair(const char*& position)
+{
+ size_t count = 1;
+ do {
+ char c = *position++;
+ if (!c)
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Malformed type encoding" userInfo:nil];
+ if (c == open)
+ ++count;
+ else if (c == close)
+ --count;
+ } while (count);
+}
+
+class StringRange {
+ WTF_MAKE_NONCOPYABLE(StringRange);
+public:
+ StringRange(const char* begin, const char* end) : m_ptr(strndup(begin, end - begin)) { }
+ ~StringRange() { free(m_ptr); }
+ operator const char*() const { return m_ptr; }
+ const char* get() const { return m_ptr; }
+
+private:
+ char* m_ptr;
+};
+
+class StructBuffer {
+ WTF_MAKE_NONCOPYABLE(StructBuffer);
+public:
+ StructBuffer(const char* encodedType)
+ {
+ NSUInteger size, alignment;
+ NSGetSizeAndAlignment(encodedType, &size, &alignment);
+ --alignment;
+ m_allocation = static_cast<char*>(malloc(size + alignment));
+ m_buffer = reinterpret_cast<char*>((reinterpret_cast<intptr_t>(m_allocation) + alignment) & ~alignment);
+ }
+
+ ~StructBuffer() { free(m_allocation); }
+ operator void*() const { return m_buffer; }
+
+private:
+ void* m_allocation;
+ void* m_buffer;
+};
+
+template<typename DelegateType>
+typename DelegateType::ResultType parseObjCType(const char*& position)
+{
+ ASSERT(*position);
+
+ switch (*position++) {
+ case 'c':
+ return DelegateType::template typeInteger<char>();
+ case 'i':
+ return DelegateType::template typeInteger<int>();
+ case 's':
+ return DelegateType::template typeInteger<short>();
+ case 'l':
+ return DelegateType::template typeInteger<long>();
+ case 'q':
+ return DelegateType::template typeDouble<unsigned long long>();
+ case 'C':
+ return DelegateType::template typeInteger<unsigned char>();
+ case 'I':
+ return DelegateType::template typeInteger<unsigned>();
+ case 'S':
+ return DelegateType::template typeInteger<unsigned short>();
+ case 'L':
+ return DelegateType::template typeInteger<unsigned long>();
+ case 'Q':
+ return DelegateType::template typeDouble<unsigned long long>();
+ case 'f':
+ return DelegateType::template typeDouble<float>();
+ case 'd':
+ return DelegateType::template typeDouble<double>();
+ case 'B':
+ return DelegateType::typeBool();
+ case 'v':
+ return DelegateType::typeVoid();
+
+ case '@': { // An object (whether statically typed or typed id)
+ if (position[0] == '?' && position[1] == '<') {
+ position += 2;
+ const char* begin = position;
+ skipPair<'<','>'>(position);
+ return DelegateType::typeBlock(begin, position - 1);
+ }
+
+ if (*position == '"') {
+ const char* begin = ++position;
+ position = index(position, '"');
+ return DelegateType::typeOfClass(begin, position++);
+ }
+
+ return DelegateType::typeId();
+ }
+
+ case '{': { // {name=type...} A structure
+ const char* begin = position - 1;
+ skipPair<'{','}'>(position);
+ return DelegateType::typeStruct(begin, position);
+ }
+
+ // NOT supporting C strings, arrays, pointers, unions, bitfields, function pointers.
+ case '*': // A character string (char *)
+ case '[': // [array type] An array
+ case '(': // (name=type...) A union
+ case 'b': // bnum A bit field of num bits
+ case '^': // ^type A pointer to type
+ case '?': // An unknown type (among other things, this code is used for function pointers)
+ // NOT supporting Objective-C Class, SEL
+ case '#': // A class object (Class)
+ case ':': // A method selector (SEL)
+ default:
+ return nil;
+ }
+}
+
+extern "C" {
+ // Forward declare some Objective-C runtime internal methods that are not API.
+ const char *_protocol_getMethodTypeEncoding(Protocol *, SEL, BOOL isRequiredMethod, BOOL isInstanceMethod);
+ id objc_initWeak(id *, id);
+ void objc_destroyWeak(id *);
+ bool _Block_has_signature(void *);
+ const char * _Block_signature(void *);
+}
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.cpp b/Source/JavaScriptCore/API/OpaqueJSString.cpp
index 90bc1c095..a7cef8d9a 100644
--- a/Source/JavaScriptCore/API/OpaqueJSString.cpp
+++ b/Source/JavaScriptCore/API/OpaqueJSString.cpp
@@ -48,7 +48,7 @@ String OpaqueJSString::string() const
return m_string.isolatedCopy();
}
-Identifier OpaqueJSString::identifier(JSGlobalData* globalData) const
+Identifier OpaqueJSString::identifier(VM* vm) const
{
if (!this || m_string.isNull())
return Identifier();
@@ -57,7 +57,7 @@ Identifier OpaqueJSString::identifier(JSGlobalData* globalData) const
return Identifier(Identifier::EmptyIdentifier);
if (m_string.is8Bit())
- return Identifier(globalData, m_string.characters8(), m_string.length());
+ return Identifier(vm, m_string.characters8(), m_string.length());
- return Identifier(globalData, m_string.characters16(), m_string.length());
+ return Identifier(vm, m_string.characters16(), m_string.length());
}
diff --git a/Source/JavaScriptCore/API/OpaqueJSString.h b/Source/JavaScriptCore/API/OpaqueJSString.h
index 0464e8813..c374b567a 100644
--- a/Source/JavaScriptCore/API/OpaqueJSString.h
+++ b/Source/JavaScriptCore/API/OpaqueJSString.h
@@ -31,7 +31,7 @@
namespace JSC {
class Identifier;
- class JSGlobalData;
+ class VM;
}
struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
@@ -57,7 +57,10 @@ struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> {
unsigned length() { return !!this ? m_string.length() : 0; }
JS_EXPORT_PRIVATE String string() const;
- JSC::Identifier identifier(JSC::JSGlobalData*) const;
+ JSC::Identifier identifier(JSC::VM*) const;
+#if PLATFORM(QT)
+ QString qString() const { return m_string; }
+#endif
private:
friend class WTF::ThreadSafeRefCounted<OpaqueJSString>;
@@ -67,12 +70,8 @@ private:
}
OpaqueJSString(const String& string)
+ : m_string(string.isolatedCopy())
{
- // Make a copy of the source string.
- if (string.is8Bit())
- m_string = String(string.characters8(), string.length());
- else
- m_string = String(string.characters16(), string.length());
}
OpaqueJSString(const LChar* characters, unsigned length)
diff --git a/Source/JavaScriptCore/API/tests/JSNode.c b/Source/JavaScriptCore/API/tests/JSNode.c
index 052c88a02..d9a40bea6 100644
--- a/Source/JavaScriptCore/API/tests/JSNode.c
+++ b/Source/JavaScriptCore/API/tests/JSNode.c
@@ -30,7 +30,6 @@
#include "JSValueRef.h"
#include "Node.h"
#include "NodeList.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 0d194845e..61d7041a4 100644
--- a/Source/JavaScriptCore/API/tests/JSNodeList.c
+++ b/Source/JavaScriptCore/API/tests/JSNodeList.c
@@ -27,7 +27,6 @@
#include "JSNodeList.h"
#include "JSObjectRef.h"
#include "JSValueRef.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/API/tests/minidom.c b/Source/JavaScriptCore/API/tests/minidom.c
index 43ae2c1a8..8614e51e9 100644
--- a/Source/JavaScriptCore/API/tests/minidom.c
+++ b/Source/JavaScriptCore/API/tests/minidom.c
@@ -31,7 +31,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <wtf/Assertions.h>
-#include <wtf/UnusedParam.h>
static char* createStringWithContentsOfFile(const char* fileName);
static JSValueRef print(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
diff --git a/Source/JavaScriptCore/API/tests/testapi.c b/Source/JavaScriptCore/API/tests/testapi.c
index c2400f7ec..be18b2bf7 100644
--- a/Source/JavaScriptCore/API/tests/testapi.c
+++ b/Source/JavaScriptCore/API/tests/testapi.c
@@ -27,10 +27,17 @@
#include "JSBasePrivate.h"
#include "JSContextRefPrivate.h"
#include "JSObjectRefPrivate.h"
+#include "JSScriptRefPrivate.h"
+#include "JSStringRefPrivate.h"
#include <math.h>
#define ASSERT_DISABLED 0
#include <wtf/Assertions.h>
-#include <wtf/UnusedParam.h>
+
+#if PLATFORM(MAC) || PLATFORM(IOS)
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <sys/time.h>
+#endif
#if OS(WINDOWS)
#include <windows.h>
@@ -45,10 +52,19 @@ static double nan(const char*)
return std::numeric_limits<double>::quiet_NaN();
}
+using std::isinf;
+using std::isnan;
+
#endif
+#if JSC_OBJC_API_ENABLED
+void testObjectiveCAPI(void);
+#endif
+
+extern void JSSynchronousGarbageCollectForDebugging(JSContextRef);
+
static JSGlobalContextRef context;
-static int failed;
+int failed;
static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
{
if (JSValueToBoolean(context, value) != expectedValue) {
@@ -481,6 +497,11 @@ static bool PropertyCatchalls_setProperty(JSContextRef context, JSObjectRef obje
return true;
}
+ if (JSStringIsEqualToUTF8CString(propertyName, "make_throw") || JSStringIsEqualToUTF8CString(propertyName, "0")) {
+ *exception = JSValueMakeNumber(context, 5);
+ return true;
+ }
+
return false;
}
@@ -1030,6 +1051,68 @@ static void checkConstnessInJSObjectNames()
val.name = "something";
}
+#if PLATFORM(MAC) || PLATFORM(IOS)
+static double currentCPUTime()
+{
+ mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
+ thread_basic_info_data_t info;
+
+ /* Get thread information */
+ mach_port_t threadPort = mach_thread_self();
+ thread_info(threadPort, THREAD_BASIC_INFO, (thread_info_t)(&info), &infoCount);
+ mach_port_deallocate(mach_task_self(), threadPort);
+
+ double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
+ time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
+
+ return time;
+}
+
+static JSValueRef currentCPUTime_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ UNUSED_PARAM(functionObject);
+ UNUSED_PARAM(thisObject);
+ UNUSED_PARAM(argumentCount);
+ UNUSED_PARAM(arguments);
+ UNUSED_PARAM(exception);
+
+ ASSERT(JSContextGetGlobalContext(ctx) == context);
+ return JSValueMakeNumber(ctx, currentCPUTime());
+}
+
+bool shouldTerminateCallbackWasCalled = false;
+static bool shouldTerminateCallback(JSContextRef ctx, void* context)
+{
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(context);
+ shouldTerminateCallbackWasCalled = true;
+ return true;
+}
+
+bool cancelTerminateCallbackWasCalled = false;
+static bool cancelTerminateCallback(JSContextRef ctx, void* context)
+{
+ UNUSED_PARAM(ctx);
+ UNUSED_PARAM(context);
+ cancelTerminateCallbackWasCalled = true;
+ return false;
+}
+
+int extendTerminateCallbackCalled = 0;
+static bool extendTerminateCallback(JSContextRef ctx, void* context)
+{
+ UNUSED_PARAM(context);
+ extendTerminateCallbackCalled++;
+ if (extendTerminateCallbackCalled == 1) {
+ JSContextGroupRef contextGroup = JSContextGetGroup(ctx);
+ JSContextGroupSetExecutionTimeLimit(contextGroup, .200f, extendTerminateCallback, 0);
+ return false;
+ }
+ return true;
+}
+#endif /* PLATFORM(MAC) || PLATFORM(IOS) */
+
+
int main(int argc, char* argv[])
{
#if OS(WINDOWS)
@@ -1039,6 +1122,10 @@ int main(int argc, char* argv[])
::SetErrorMode(0);
#endif
+#if JSC_OBJC_API_ENABLED
+ testObjectiveCAPI();
+#endif
+
const char *scriptPath = "testapi.js";
if (argc > 1) {
scriptPath = argv[1];
@@ -1061,6 +1148,8 @@ int main(int argc, char* argv[])
JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
context = JSGlobalContextCreateInGroup(NULL, globalObjectClass);
+ JSContextGroupRef contextGroup = JSContextGetGroup(context);
+
JSGlobalContextRetain(context);
JSGlobalContextRelease(context);
ASSERT(JSContextGetGlobalContext(context) == context);
@@ -1117,6 +1206,12 @@ int main(int argc, char* argv[])
free(buffer);
JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);
+ JSChar constantString[] = { 'H', 'e', 'l', 'l', 'o', };
+ JSStringRef constantStringRef = JSStringCreateWithCharactersNoCopy(constantString, sizeof(constantString) / sizeof(constantString[0]));
+ ASSERT(JSStringGetCharactersPtr(constantStringRef) == constantString);
+ JSStringRelease(constantStringRef);
+
+ ASSERT(JSValueGetType(context, NULL) == kJSTypeNull);
ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean);
@@ -1131,6 +1226,17 @@ int main(int argc, char* argv[])
ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString);
ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);
+ ASSERT(!JSValueIsBoolean(context, NULL));
+ ASSERT(!JSValueIsObject(context, NULL));
+ ASSERT(!JSValueIsString(context, NULL));
+ ASSERT(!JSValueIsNumber(context, NULL));
+ ASSERT(!JSValueIsUndefined(context, NULL));
+ ASSERT(JSValueIsNull(context, NULL));
+ ASSERT(!JSObjectCallAsFunction(context, NULL, NULL, 0, NULL, NULL));
+ ASSERT(!JSObjectCallAsConstructor(context, NULL, 0, NULL, NULL));
+ ASSERT(!JSObjectIsConstructor(context, NULL));
+ ASSERT(!JSObjectIsFunction(context, NULL));
+
JSStringRef nullString = JSStringCreateWithUTF8CString(0);
const JSChar* characters = JSStringGetCharactersPtr(nullString);
if (characters) {
@@ -1139,6 +1245,14 @@ int main(int argc, char* argv[])
} else
printf("PASS: returned null when accessing character pointer of a null String.\n");
+ JSStringRef emptyString = JSStringCreateWithCFString(CFSTR(""));
+ characters = JSStringGetCharactersPtr(emptyString);
+ if (!characters) {
+ printf("FAIL: Returned null when accessing character pointer of an empty String.\n");
+ failed = 1;
+ } else
+ printf("PASS: returned empty when accessing character pointer of an empty String.\n");
+
size_t length = JSStringGetLength(nullString);
if (length) {
printf("FAIL: Didn't return 0 length for null String.\n");
@@ -1147,6 +1261,14 @@ int main(int argc, char* argv[])
printf("PASS: returned 0 length for null String.\n");
JSStringRelease(nullString);
+ length = JSStringGetLength(emptyString);
+ if (length) {
+ printf("FAIL: Didn't return 0 length for empty String.\n");
+ failed = 1;
+ } else
+ printf("PASS: returned 0 length for empty String.\n");
+ JSStringRelease(emptyString);
+
JSObjectRef propertyCatchalls = JSObjectMake(context, PropertyCatchalls_class(context), NULL);
JSStringRef propertyCatchallsString = JSStringCreateWithUTF8CString("PropertyCatchalls");
JSObjectSetProperty(context, globalObject, propertyCatchallsString, propertyCatchalls, kJSPropertyAttributeNone, NULL);
@@ -1399,9 +1521,12 @@ int main(int argc, char* argv[])
JSValueUnprotect(context, jsNumberValue);
JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
- JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;");
+ const char* badSyntaxConstant = "x := 1;";
+ JSStringRef badSyntax = JSStringCreateWithUTF8CString(badSyntaxConstant);
ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL));
ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL));
+ ASSERT(!JSScriptCreateFromString(contextGroup, 0, 0, badSyntax, 0, 0));
+ ASSERT(!JSScriptCreateReferencingImmortalASCIIText(contextGroup, 0, 0, badSyntaxConstant, strlen(badSyntaxConstant), 0, 0));
JSValueRef result;
JSValueRef v;
@@ -1590,13 +1715,21 @@ int main(int argc, char* argv[])
v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
ASSERT(JSValueIsEqual(context, v, o, NULL));
- JSStringRef script = JSStringCreateWithUTF8CString("this;");
+ const char* thisScript = "this;";
+ JSStringRef script = JSStringCreateWithUTF8CString(thisScript);
v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, o, NULL));
JSStringRelease(script);
+ JSScriptRef scriptObject = JSScriptCreateReferencingImmortalASCIIText(contextGroup, 0, 0, thisScript, strlen(thisScript), 0, 0);
+ v = JSScriptEvaluate(context, scriptObject, NULL, NULL);
+ ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
+ v = JSScriptEvaluate(context, scriptObject, o, NULL);
+ ASSERT(JSValueIsEqual(context, v, o, NULL));
+ JSScriptRelease(scriptObject);
+
script = JSStringCreateWithUTF8CString("eval(this);");
v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
@@ -1616,8 +1749,23 @@ int main(int argc, char* argv[])
printf("FAIL: Test script could not be loaded.\n");
failed = 1;
} else {
- script = JSStringCreateWithUTF8CString(scriptUTF8);
- result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+ JSStringRef url = JSStringCreateWithUTF8CString(scriptPath);
+ JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8);
+ JSStringRef errorMessage = 0;
+ int errorLine = 0;
+ JSScriptRef scriptObject = JSScriptCreateFromString(contextGroup, url, 1, script, &errorMessage, &errorLine);
+ ASSERT((!scriptObject) != (!errorMessage));
+ if (!scriptObject) {
+ printf("FAIL: Test script did not parse\n\t%s:%d\n\t", scriptPath, errorLine);
+ CFStringRef errorCF = JSStringCopyCFString(kCFAllocatorDefault, errorMessage);
+ CFShow(errorCF);
+ CFRelease(errorCF);
+ JSStringRelease(errorMessage);
+ failed = 1;
+ }
+
+ JSStringRelease(script);
+ result = scriptObject ? JSScriptEvaluate(context, scriptObject, 0, &exception) : 0;
if (result && JSValueIsUndefined(context, result))
printf("PASS: Test script executed successfully.\n");
else {
@@ -1629,10 +1777,163 @@ int main(int argc, char* argv[])
JSStringRelease(exceptionIString);
failed = 1;
}
- JSStringRelease(script);
+ JSScriptRelease(scriptObject);
free(scriptUTF8);
}
+#if PLATFORM(MAC) || PLATFORM(IOS)
+ JSStringRef currentCPUTimeStr = JSStringCreateWithUTF8CString("currentCPUTime");
+ JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTime_callAsFunction);
+ JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(currentCPUTimeStr);
+
+ /* Test script timeout: */
+ JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, shouldTerminateCallback, 0);
+ {
+ const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
+ JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+ double startTime;
+ double endTime;
+ exception = NULL;
+ shouldTerminateCallbackWasCalled = false;
+ startTime = currentCPUTime();
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+ endTime = currentCPUTime();
+
+ if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
+ printf("PASS: script timed out as expected.\n");
+ else {
+ if (!((endTime - startTime) < .150f))
+ printf("FAIL: script did not timed out as expected.\n");
+ if (!shouldTerminateCallbackWasCalled)
+ printf("FAIL: script timeout callback was not called.\n");
+ failed = true;
+ }
+
+ if (!exception) {
+ printf("FAIL: TerminatedExecutionException was not thrown.\n");
+ failed = true;
+ }
+ }
+
+ /* Test the script timeout's TerminatedExecutionException should NOT be catchable: */
+ JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, shouldTerminateCallback, 0);
+ {
+ const char* loopForeverScript = "var startTime = currentCPUTime(); try { while (true) { if (currentCPUTime() - startTime > .150) break; } } catch(e) { }";
+ JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+ double startTime;
+ double endTime;
+ exception = NULL;
+ shouldTerminateCallbackWasCalled = false;
+ startTime = currentCPUTime();
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+ endTime = currentCPUTime();
+
+ if (((endTime - startTime) >= .150f) || !shouldTerminateCallbackWasCalled) {
+ if (!((endTime - startTime) < .150f))
+ printf("FAIL: script did not timed out as expected.\n");
+ if (!shouldTerminateCallbackWasCalled)
+ printf("FAIL: script timeout callback was not called.\n");
+ failed = true;
+ }
+
+ if (exception)
+ printf("PASS: TerminatedExecutionException was not catchable as expected.\n");
+ else {
+ printf("FAIL: TerminatedExecutionException was caught.\n");
+ failed = true;
+ }
+ }
+
+ /* Test script timeout with no callback: */
+ JSContextGroupSetExecutionTimeLimit(contextGroup, .10f, 0, 0);
+ {
+ const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
+ JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+ double startTime;
+ double endTime;
+ exception = NULL;
+ startTime = currentCPUTime();
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+ endTime = currentCPUTime();
+
+ if (((endTime - startTime) < .150f) && shouldTerminateCallbackWasCalled)
+ printf("PASS: script timed out as expected when no callback is specified.\n");
+ else {
+ if (!((endTime - startTime) < .150f))
+ printf("FAIL: script did not timed out as expected when no callback is specified.\n");
+ failed = true;
+ }
+
+ if (!exception) {
+ printf("FAIL: TerminatedExecutionException was not thrown.\n");
+ failed = true;
+ }
+ }
+
+ /* Test script timeout cancellation: */
+ JSContextGroupSetExecutionTimeLimit(contextGroup, 0.10f, cancelTerminateCallback, 0);
+ {
+ const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .150) break; } ";
+ JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+ double startTime;
+ double endTime;
+ exception = NULL;
+ startTime = currentCPUTime();
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+ endTime = currentCPUTime();
+
+ if (((endTime - startTime) >= .150f) && cancelTerminateCallbackWasCalled && !exception)
+ printf("PASS: script timeout was cancelled as expected.\n");
+ else {
+ if (((endTime - startTime) < .150) || exception)
+ printf("FAIL: script timeout was not cancelled.\n");
+ if (!cancelTerminateCallbackWasCalled)
+ printf("FAIL: script timeout callback was not called.\n");
+ failed = true;
+ }
+
+ if (exception) {
+ printf("FAIL: Unexpected TerminatedExecutionException thrown.\n");
+ failed = true;
+ }
+ }
+
+ /* Test script timeout extension: */
+ JSContextGroupSetExecutionTimeLimit(contextGroup, 0.100f, extendTerminateCallback, 0);
+ {
+ const char* loopForeverScript = "var startTime = currentCPUTime(); while (true) { if (currentCPUTime() - startTime > .500) break; } ";
+ JSStringRef script = JSStringCreateWithUTF8CString(loopForeverScript);
+ double startTime;
+ double endTime;
+ double deltaTime;
+ exception = NULL;
+ startTime = currentCPUTime();
+ v = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
+ endTime = currentCPUTime();
+ deltaTime = endTime - startTime;
+
+ if ((deltaTime >= .300f) && (deltaTime < .500f) && (extendTerminateCallbackCalled == 2) && exception)
+ printf("PASS: script timeout was extended as expected.\n");
+ else {
+ if (deltaTime < .200f)
+ printf("FAIL: script timeout was not extended as expected.\n");
+ else if (deltaTime >= .500f)
+ printf("FAIL: script did not timeout.\n");
+
+ if (extendTerminateCallbackCalled < 1)
+ printf("FAIL: script timeout callback was not called.\n");
+ if (extendTerminateCallbackCalled < 2)
+ printf("FAIL: script timeout callback was not called after timeout extension.\n");
+
+ if (!exception)
+ printf("FAIL: TerminatedExecutionException was not thrown during timeout extension test.\n");
+
+ failed = true;
+ }
+ }
+#endif /* PLATFORM(MAC) || PLATFORM(IOS) */
+
// Clear out local variables pointing at JSObjectRefs to allow their values to be collected
function = NULL;
v = NULL;
diff --git a/Source/JavaScriptCore/API/tests/testapi.js b/Source/JavaScriptCore/API/tests/testapi.js
index 28fa54433..47c20a830 100644
--- a/Source/JavaScriptCore/API/tests/testapi.js
+++ b/Source/JavaScriptCore/API/tests/testapi.js
@@ -262,6 +262,10 @@ shouldBe("PropertyCatchalls.x", 4);
for (var i = 0; i < 6; ++i)
var x = PropertyCatchalls.x;
shouldBe("x", null);
+var make_throw = 'make_throw';
+shouldThrow("PropertyCatchalls[make_throw]=1");
+make_throw = 0;
+shouldThrow("PropertyCatchalls[make_throw]=1");
for (var i = 0; i < 10; ++i) {
for (var p in PropertyCatchalls) {
diff --git a/Source/JavaScriptCore/API/tests/testapi.mm b/Source/JavaScriptCore/API/tests/testapi.mm
new file mode 100644
index 000000000..defb46e70
--- /dev/null
+++ b/Source/JavaScriptCore/API/tests/testapi.mm
@@ -0,0 +1,841 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <JavaScriptCore/JavaScriptCore.h>
+
+extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef);
+
+extern "C" bool _Block_has_signature(id);
+extern "C" const char * _Block_signature(id);
+
+extern int failed;
+extern "C" void testObjectiveCAPI(void);
+
+#if JSC_OBJC_API_ENABLED
+
+@protocol ParentObject <JSExport>
+@end
+
+@interface ParentObject : NSObject<ParentObject>
++ (NSString *)parentTest;
+@end
+
+@implementation ParentObject
++ (NSString *)parentTest
+{
+ return [self description];
+}
+@end
+
+@protocol TestObject <JSExport>
+@property int variable;
+@property (readonly) int six;
+@property CGPoint point;
++ (NSString *)classTest;
++ (NSString *)parentTest;
+- (NSString *)getString;
+JSExportAs(testArgumentTypes,
+- (NSString *)testArgumentTypesWithInt:(int)i double:(double)d boolean:(BOOL)b string:(NSString *)s number:(NSNumber *)n array:(NSArray *)a dictionary:(NSDictionary *)o
+);
+- (void)callback:(JSValue *)function;
+- (void)bogusCallback:(void(^)(int))function;
+@end
+
+@interface TestObject : ParentObject <TestObject>
+@property int six;
++ (id)testObject;
+@end
+
+@implementation TestObject
+@synthesize variable;
+@synthesize six;
+@synthesize point;
++ (id)testObject
+{
+ return [[TestObject alloc] init];
+}
++ (NSString *)classTest
+{
+ return @"classTest - okay";
+}
+- (NSString *)getString
+{
+ return @"42";
+}
+- (NSString *)testArgumentTypesWithInt:(int)i double:(double)d boolean:(BOOL)b string:(NSString *)s number:(NSNumber *)n array:(NSArray *)a dictionary:(NSDictionary *)o
+{
+ return [NSString stringWithFormat:@"%d,%g,%d,%@,%d,%@,%@", i, d, b==YES?true:false,s,[n intValue],a[1],o[@"x"]];
+}
+- (void)callback:(JSValue *)function
+{
+ [function callWithArguments:[NSArray arrayWithObject:[NSNumber numberWithInt:42]]];
+}
+- (void)bogusCallback:(void(^)(int))function
+{
+ function(42);
+}
+@end
+
+bool testXYZTested = false;
+
+@protocol TextXYZ <JSExport>
+@property int x;
+@property (readonly) int y;
+@property (assign) JSValue *onclick;
+@property (assign) JSValue *weakOnclick;
+- (void)test:(NSString *)message;
+@end
+
+@interface TextXYZ : NSObject <TextXYZ>
+@property int x;
+@property int y;
+@property int z;
+- (void)click;
+@end
+
+@implementation TextXYZ {
+ JSManagedValue *m_weakOnclickHandler;
+ JSManagedValue *m_onclickHandler;
+}
+@synthesize x;
+@synthesize y;
+@synthesize z;
+- (void)test:(NSString *)message
+{
+ testXYZTested = [message isEqual:@"test"] && x == 13 & y == 4 && z == 5;
+}
+- (void)setWeakOnclick:(JSValue *)value
+{
+ m_weakOnclickHandler = [JSManagedValue managedValueWithValue:value];
+}
+
+- (void)setOnclick:(JSValue *)value
+{
+ m_onclickHandler = [JSManagedValue managedValueWithValue:value];
+ [value.context.virtualMachine addManagedReference:m_onclickHandler withOwner:self];
+}
+- (JSValue *)weakOnclick
+{
+ return [m_weakOnclickHandler value];
+}
+- (JSValue *)onclick
+{
+ return [m_onclickHandler value];
+}
+- (void)click
+{
+ if (!m_onclickHandler)
+ return;
+
+ JSValue *function = [m_onclickHandler value];
+ [function callWithArguments:[NSArray array]];
+}
+- (void)dealloc
+{
+ [[m_onclickHandler value].context.virtualMachine removeManagedReference:m_onclickHandler withOwner:self];
+}
+@end
+
+@class TinyDOMNode;
+
+@protocol TinyDOMNode <JSExport>
+- (void)appendChild:(TinyDOMNode *)child;
+- (NSUInteger)numberOfChildren;
+- (TinyDOMNode *)childAtIndex:(NSUInteger)index;
+- (void)removeChildAtIndex:(NSUInteger)index;
+@end
+
+@interface TinyDOMNode : NSObject<TinyDOMNode>
++ (JSVirtualMachine *)sharedVirtualMachine;
++ (void)clearSharedVirtualMachine;
+@end
+
+@implementation TinyDOMNode {
+ NSMutableArray *m_children;
+}
+
+static JSVirtualMachine *sharedInstance = nil;
+
++ (JSVirtualMachine *)sharedVirtualMachine
+{
+ if (!sharedInstance)
+ sharedInstance = [[JSVirtualMachine alloc] init];
+ return sharedInstance;
+}
+
++ (void)clearSharedVirtualMachine
+{
+ sharedInstance = nil;
+}
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ m_children = [[NSMutableArray alloc] initWithCapacity:0];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ NSEnumerator *enumerator = [m_children objectEnumerator];
+ id nextChild;
+ while ((nextChild = [enumerator nextObject]))
+ [[TinyDOMNode sharedVirtualMachine] removeManagedReference:nextChild withOwner:self];
+
+#if !__has_feature(objc_arc)
+ [super dealloc];
+#endif
+}
+
+- (void)appendChild:(TinyDOMNode *)child
+{
+ [[TinyDOMNode sharedVirtualMachine] addManagedReference:child withOwner:self];
+ [m_children addObject:child];
+}
+
+- (NSUInteger)numberOfChildren
+{
+ return [m_children count];
+}
+
+- (TinyDOMNode *)childAtIndex:(NSUInteger)index
+{
+ if (index >= [m_children count])
+ return nil;
+ return [m_children objectAtIndex:index];
+}
+
+- (void)removeChildAtIndex:(NSUInteger)index
+{
+ if (index >= [m_children count])
+ return;
+ [[TinyDOMNode sharedVirtualMachine] removeManagedReference:[m_children objectAtIndex:index] withOwner:self];
+ [m_children removeObjectAtIndex:index];
+}
+
+@end
+
+static void checkResult(NSString *description, bool passed)
+{
+ NSLog(@"TEST: \"%@\": %@", description, passed ? @"PASSED" : @"FAILED");
+ if (!passed)
+ failed = 1;
+}
+
+static bool blockSignatureContainsClass()
+{
+ static bool containsClass = ^{
+ id block = ^(NSString *string){ return string; };
+ return _Block_has_signature(block) && strstr(_Block_signature(block), "NSString");
+ }();
+ return containsClass;
+}
+
+void testObjectiveCAPI()
+{
+ NSLog(@"Testing Objective-C API");
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue *result = [context evaluateScript:@"2 + 2"];
+ checkResult(@"2 + 2", [result isNumber] && [result toInt32] == 4);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ NSString *result = [NSString stringWithFormat:@"Two plus two is %@", [context evaluateScript:@"2 + 2"]];
+ checkResult(@"stringWithFormat", [result isEqual:@"Two plus two is 4"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"message"] = @"Hello";
+ JSValue *result = [context evaluateScript:@"message + ', World!'"];
+ checkResult(@"Hello, World!", [result isString] && [result isEqualToObject:@"Hello, World!"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue *result = [context evaluateScript:@"({ x:42 })"];
+ checkResult(@"({ x:42 })", [result isObject] && [result[@"x"] isEqualToObject:@42]);
+ id obj = [result toObject];
+ checkResult(@"Check dictionary literal", [obj isKindOfClass:[NSDictionary class]]);
+ id num = (NSDictionary *)obj[@"x"];
+ checkResult(@"Check numeric literal", [num isKindOfClass:[NSNumber class]]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ __block int result;
+ context[@"blockCallback"] = ^(int value){
+ result = value;
+ };
+ [context evaluateScript:@"blockCallback(42)"];
+ checkResult(@"blockCallback", result == 42);
+ }
+
+ if (blockSignatureContainsClass()) {
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ __block bool result = false;
+ context[@"blockCallback"] = ^(NSString *value){
+ result = [@"42" isEqualToString:value] == YES;
+ };
+ [context evaluateScript:@"blockCallback(42)"];
+ checkResult(@"blockCallback(NSString *)", result);
+ }
+ } else
+ NSLog(@"Skipping 'blockCallback(NSString *)' test case");
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ checkResult(@"!context.exception", !context.exception);
+ [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
+ checkResult(@"context.exception", context.exception);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ __block bool caught = false;
+ context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
+ (void)context;
+ (void)exception;
+ caught = true;
+ };
+ [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
+ checkResult(@"JSContext.exceptionHandler", caught);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"callback"] = ^{
+ JSContext *context = [JSContext currentContext];
+ context.exception = [JSValue valueWithNewErrorFromMessage:@"Something went wrong." inContext:context];
+ };
+ JSValue *result = [context evaluateScript:@"var result; try { callback(); } catch (e) { result = 'Caught exception'; }"];
+ checkResult(@"Explicit throw in callback - was caught by JavaScript", [result isEqualToObject:@"Caught exception"]);
+ checkResult(@"Explicit throw in callback - not thrown to Objective-C", !context.exception);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"callback"] = ^{
+ JSContext *context = [JSContext currentContext];
+ [context evaluateScript:@"!@#$%^&*() THIS IS NOT VALID JAVASCRIPT SYNTAX !@#$%^&*()"];
+ };
+ JSValue *result = [context evaluateScript:@"var result; try { callback(); } catch (e) { result = 'Caught exception'; }"];
+ checkResult(@"Implicit throw in callback - was caught by JavaScript", [result isEqualToObject:@"Caught exception"]);
+ checkResult(@"Implicit throw in callback - not thrown to Objective-C", !context.exception);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ [context evaluateScript:
+ @"function sum(array) { \
+ var result = 0; \
+ for (var i in array) \
+ result += array[i]; \
+ return result; \
+ }"];
+ JSValue *array = [JSValue valueWithObject:@[@13, @2, @7] inContext:context];
+ JSValue *sumFunction = context[@"sum"];
+ JSValue *result = [sumFunction callWithArguments:@[ array ]];
+ checkResult(@"sum([13, 2, 7])", [result toInt32] == 22);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue *mulAddFunction = [context evaluateScript:
+ @"(function(array, object) { \
+ var result = []; \
+ for (var i in array) \
+ result.push(array[i] * object.x + object.y); \
+ return result; \
+ })"];
+ JSValue *result = [mulAddFunction callWithArguments:@[ @[ @2, @4, @8 ], @{ @"x":@0.5, @"y":@42 } ]];
+ checkResult(@"mulAddFunction", [result isObject] && [[result toString] isEqual:@"43,44,46"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue *array = [JSValue valueWithNewArrayInContext:context];
+ checkResult(@"arrayLengthEmpty", [[array[@"length"] toNumber] unsignedIntegerValue] == 0);
+ JSValue *value1 = [JSValue valueWithInt32:42 inContext:context];
+ JSValue *value2 = [JSValue valueWithInt32:24 inContext:context];
+ NSUInteger lowIndex = 5;
+ NSUInteger maxLength = UINT_MAX;
+
+ [array setValue:value1 atIndex:lowIndex];
+ checkResult(@"array.length after put to low index", [[array[@"length"] toNumber] unsignedIntegerValue] == (lowIndex + 1));
+
+ [array setValue:value1 atIndex:(maxLength - 1)];
+ checkResult(@"array.length after put to maxLength - 1", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
+
+ [array setValue:value2 atIndex:maxLength];
+ checkResult(@"array.length after put to maxLength", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
+
+ [array setValue:value2 atIndex:(maxLength + 1)];
+ checkResult(@"array.length after put to maxLength + 1", [[array[@"length"] toNumber] unsignedIntegerValue] == maxLength);
+
+ checkResult(@"valueAtIndex:0 is undefined", [[array valueAtIndex:0] isUndefined]);
+ checkResult(@"valueAtIndex:lowIndex", [[array valueAtIndex:lowIndex] toInt32] == 42);
+ checkResult(@"valueAtIndex:maxLength - 1", [[array valueAtIndex:(maxLength - 1)] toInt32] == 42);
+ checkResult(@"valueAtIndex:maxLength", [[array valueAtIndex:maxLength] toInt32] == 24);
+ checkResult(@"valueAtIndex:maxLength + 1", [[array valueAtIndex:(maxLength + 1)] toInt32] == 24);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue *object = [JSValue valueWithNewObjectInContext:context];
+
+ object[@"point"] = @{ @"x":@1, @"y":@2 };
+ object[@"point"][@"x"] = @3;
+ CGPoint point = [object[@"point"] toPoint];
+ checkResult(@"toPoint", point.x == 3 && point.y == 2);
+
+ object[@{ @"toString":^{ return @"foo"; } }] = @"bar";
+ checkResult(@"toString in object literal used as subscript", [[object[@"foo"] toString] isEqual:@"bar"]);
+
+ object[[@"foobar" substringToIndex:3]] = @"bar";
+ checkResult(@"substring used as subscript", [[object[@"foo"] toString] isEqual:@"bar"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TextXYZ *testXYZ = [[TextXYZ alloc] init];
+ context[@"testXYZ"] = testXYZ;
+ testXYZ.x = 3;
+ testXYZ.y = 4;
+ testXYZ.z = 5;
+ [context evaluateScript:@"testXYZ.x = 13; testXYZ.y = 14;"];
+ [context evaluateScript:@"testXYZ.test('test')"];
+ checkResult(@"TextXYZ - testXYZTested", testXYZTested);
+ JSValue *result = [context evaluateScript:@"testXYZ.x + ',' + testXYZ.y + ',' + testXYZ.z"];
+ checkResult(@"TextXYZ - result", [result isEqualToObject:@"13,4,undefined"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ [context[@"Object"][@"prototype"] defineProperty:@"getterProperty" descriptor:@{
+ JSPropertyDescriptorGetKey:^{
+ return [JSContext currentThis][@"x"];
+ }
+ }];
+ JSValue *object = [JSValue valueWithObject:@{ @"x":@101 } inContext:context];
+ int result = [object [@"getterProperty"] toInt32];
+ checkResult(@"getterProperty", result == 101);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"concatenate"] = ^{
+ NSArray *arguments = [JSContext currentArguments];
+ if (![arguments count])
+ return @"";
+ NSString *message = [arguments[0] description];
+ for (NSUInteger index = 1; index < [arguments count]; ++index)
+ message = [NSString stringWithFormat:@"%@ %@", message, arguments[index]];
+ return message;
+ };
+ JSValue *result = [context evaluateScript:@"concatenate('Hello,', 'World!')"];
+ checkResult(@"concatenate", [result isEqualToObject:@"Hello, World!"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"foo"] = @YES;
+ checkResult(@"@YES is boolean", [context[@"foo"] isBoolean]);
+ JSValue *result = [context evaluateScript:@"typeof foo"];
+ checkResult(@"@YES is boolean", [result isEqualToObject:@"boolean"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"String(testObject)"];
+ checkResult(@"String(testObject)", [result isEqualToObject:@"[object TestObject]"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"String(testObject.__proto__)"];
+ checkResult(@"String(testObject.__proto__)", [result isEqualToObject:@"[object TestObjectPrototype]"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"TestObject"] = [TestObject class];
+ JSValue *result = [context evaluateScript:@"String(TestObject)"];
+ checkResult(@"String(TestObject)", [result isEqualToObject:@"[object TestObjectConstructor]"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue* value = [JSValue valueWithObject:[TestObject class] inContext:context];
+ checkResult(@"[value toObject] == [TestObject class]", [value toObject] == [TestObject class]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"TestObject"] = [TestObject class];
+ JSValue *result = [context evaluateScript:@"TestObject.parentTest()"];
+ checkResult(@"TestObject.parentTest()", [result isEqualToObject:@"TestObject"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObjectA"] = testObject;
+ context[@"testObjectB"] = testObject;
+ JSValue *result = [context evaluateScript:@"testObjectA == testObjectB"];
+ checkResult(@"testObjectA == testObjectB", [result isBoolean] && [result toBool]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ testObject.point = (CGPoint){3,4};
+ JSValue *result = [context evaluateScript:@"var result = JSON.stringify(testObject.point); testObject.point = {x:12,y:14}; result"];
+ checkResult(@"testObject.point - result", [result isEqualToObject:@"{\"x\":3,\"y\":4}"]);
+ checkResult(@"testObject.point - {x:12,y:14}", testObject.point.x == 12 && testObject.point.y == 14);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ testObject.six = 6;
+ context[@"testObject"] = testObject;
+ context[@"mul"] = ^(int x, int y){ return x * y; };
+ JSValue *result = [context evaluateScript:@"mul(testObject.six, 7)"];
+ checkResult(@"mul(testObject.six, 7)", [result isNumber] && [result toInt32] == 42);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ context[@"testObject"][@"variable"] = @4;
+ [context evaluateScript:@"++testObject.variable"];
+ checkResult(@"++testObject.variable", testObject.variable == 5);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"point"] = @{ @"x":@6, @"y":@7 };
+ JSValue *result = [context evaluateScript:@"point.x + ',' + point.y"];
+ checkResult(@"point.x + ',' + point.y", [result isEqualToObject:@"6,7"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"point"] = @{ @"x":@6, @"y":@7 };
+ JSValue *result = [context evaluateScript:@"point.x + ',' + point.y"];
+ checkResult(@"point.x + ',' + point.y", [result isEqualToObject:@"6,7"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"testObject.getString()"];
+ checkResult(@"testObject.getString()", [result isString] && [result toInt32] == 42);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"testObject.testArgumentTypes(101,0.5,true,'foo',666,[false,'bar',false],{x:'baz'})"];
+ checkResult(@"testObject.testArgumentTypes", [result isEqualToObject:@"101,0.5,1,foo,666,bar,baz"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"testObject.getString.call(testObject)"];
+ checkResult(@"testObject.getString.call(testObject)", [result isString] && [result toInt32] == 42);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ checkResult(@"testObject.getString.call({}) pre", !context.exception);
+ [context evaluateScript:@"testObject.getString.call({})"];
+ checkResult(@"testObject.getString.call({}) post", context.exception);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject* testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"var result = 0; testObject.callback(function(x){ result = x; }); result"];
+ checkResult(@"testObject.callback", [result isNumber] && [result toInt32] == 42);
+ result = [context evaluateScript:@"testObject.bogusCallback"];
+ checkResult(@"testObject.bogusCallback == undefined", [result isUndefined]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject *testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ JSValue *result = [context evaluateScript:@"Function.prototype.toString.call(testObject.callback)"];
+ checkResult(@"Function.prototype.toString", !context.exception && ![result isUndefined]);
+ }
+
+ @autoreleasepool {
+ JSContext *context1 = [[JSContext alloc] init];
+ JSContext *context2 = [[JSContext alloc] initWithVirtualMachine:context1.virtualMachine];
+ JSValue *value = [JSValue valueWithDouble:42 inContext:context2];
+ context1[@"passValueBetweenContexts"] = value;
+ JSValue *result = [context1 evaluateScript:@"passValueBetweenContexts"];
+ checkResult(@"[value isEqualToObject:result]", [value isEqualToObject:result]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"handleTheDictionary"] = ^(NSDictionary *dict) {
+ NSDictionary *expectedDict = @{
+ @"foo" : [NSNumber numberWithInt:1],
+ @"bar" : @{
+ @"baz": [NSNumber numberWithInt:2]
+ }
+ };
+ checkResult(@"recursively convert nested dictionaries", [dict isEqualToDictionary:expectedDict]);
+ };
+ [context evaluateScript:@"var myDict = { \
+ 'foo': 1, \
+ 'bar': {'baz': 2} \
+ }; \
+ handleTheDictionary(myDict);"];
+
+ context[@"handleTheArray"] = ^(NSArray *array) {
+ NSArray *expectedArray = @[@"foo", @"bar", @[@"baz"]];
+ checkResult(@"recursively convert nested arrays", [array isEqualToArray:expectedArray]);
+ };
+ [context evaluateScript:@"var myArray = ['foo', 'bar', ['baz']]; handleTheArray(myArray);"];
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject *testObject = [TestObject testObject];
+ @autoreleasepool {
+ context[@"testObject"] = testObject;
+ [context evaluateScript:@"var constructor = Object.getPrototypeOf(testObject).constructor; constructor.prototype = undefined;"];
+ [context evaluateScript:@"testObject = undefined"];
+ }
+
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+
+ @autoreleasepool {
+ context[@"testObject"] = testObject;
+ }
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TextXYZ *testXYZ = [[TextXYZ alloc] init];
+
+ @autoreleasepool {
+ context[@"testXYZ"] = testXYZ;
+
+ [context evaluateScript:@" \
+ didClick = false; \
+ testXYZ.onclick = function() { \
+ didClick = true; \
+ }; \
+ \
+ testXYZ.weakOnclick = function() { \
+ return 'foo'; \
+ }; \
+ "];
+ }
+
+ @autoreleasepool {
+ [testXYZ click];
+ JSValue *result = [context evaluateScript:@"didClick"];
+ checkResult(@"Event handler onclick", [result toBool]);
+ }
+
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+
+ @autoreleasepool {
+ JSValue *result = [context evaluateScript:@"testXYZ.onclick"];
+ checkResult(@"onclick still around after GC", !([result isNull] || [result isUndefined]));
+ }
+
+
+ @autoreleasepool {
+ JSValue *result = [context evaluateScript:@"testXYZ.weakOnclick"];
+ checkResult(@"weakOnclick not around after GC", [result isNull] || [result isUndefined]);
+ }
+
+ @autoreleasepool {
+ [context evaluateScript:@" \
+ didClick = false; \
+ testXYZ = null; \
+ "];
+ }
+
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+
+ @autoreleasepool {
+ [testXYZ click];
+ JSValue *result = [context evaluateScript:@"didClick"];
+ checkResult(@"Event handler onclick doesn't fire", ![result toBool]);
+ }
+ }
+
+ @autoreleasepool {
+ JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
+ TestObject *testObject = [TestObject testObject];
+ JSManagedValue *weakValue;
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+ context[@"testObject"] = testObject;
+ weakValue = [[JSManagedValue alloc] initWithValue:context[@"testObject"]];
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+ context[@"testObject"] = testObject;
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+ checkResult(@"weak value == nil", ![weakValue value]);
+ checkResult(@"root is still alive", ![context[@"testObject"] isUndefined]);
+ }
+ }
+
+ @autoreleasepool {
+ JSVirtualMachine *vm = [TinyDOMNode sharedVirtualMachine];
+ JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+ TinyDOMNode *root = [[TinyDOMNode alloc] init];
+ TinyDOMNode *lastNode = root;
+ for (NSUInteger i = 0; i < 3; i++) {
+ TinyDOMNode *newNode = [[TinyDOMNode alloc] init];
+ [lastNode appendChild:newNode];
+ lastNode = newNode;
+ }
+
+ @autoreleasepool {
+ context[@"root"] = root;
+ context[@"getLastNodeInChain"] = ^(TinyDOMNode *head){
+ TinyDOMNode *lastNode = nil;
+ while (head) {
+ lastNode = head;
+ head = [lastNode childAtIndex:0];
+ }
+ return lastNode;
+ };
+ [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty = 42;"];
+ }
+
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+
+ JSValue *myCustomProperty = [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty"];
+ checkResult(@"My custom property == 42", [myCustomProperty isNumber] && [myCustomProperty toInt32] == 42);
+
+ [TinyDOMNode clearSharedVirtualMachine];
+ }
+
+ @autoreleasepool {
+ JSVirtualMachine *vm = [TinyDOMNode sharedVirtualMachine];
+ JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
+ TinyDOMNode *root = [[TinyDOMNode alloc] init];
+ TinyDOMNode *lastNode = root;
+ for (NSUInteger i = 0; i < 3; i++) {
+ TinyDOMNode *newNode = [[TinyDOMNode alloc] init];
+ [lastNode appendChild:newNode];
+ lastNode = newNode;
+ }
+
+ @autoreleasepool {
+ context[@"root"] = root;
+ context[@"getLastNodeInChain"] = ^(TinyDOMNode *head){
+ TinyDOMNode *lastNode = nil;
+ while (head) {
+ lastNode = head;
+ head = [lastNode childAtIndex:0];
+ }
+ return lastNode;
+ };
+ [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty = 42;"];
+
+ [root appendChild:[root childAtIndex:0]];
+ [root removeChildAtIndex:0];
+ }
+
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+
+ JSValue *myCustomProperty = [context evaluateScript:@"getLastNodeInChain(root).myCustomProperty"];
+ checkResult(@"duplicate calls to addManagedReference don't cause things to die", [myCustomProperty isNumber] && [myCustomProperty toInt32] == 42);
+
+ [TinyDOMNode clearSharedVirtualMachine];
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ JSValue *o = [JSValue valueWithNewObjectInContext:context];
+ o[@"foo"] = @"foo";
+ JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);
+
+ checkResult(@"JSValue correctly protected its internal value", [[o[@"foo"] toString] isEqualToString:@"foo"]);
+ }
+
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ TestObject *testObject = [TestObject testObject];
+ context[@"testObject"] = testObject;
+ [context evaluateScript:@"testObject.__lookupGetter__('variable').call({})"];
+ checkResult(@"Make sure we throw an exception when calling getter on incorrect |this|", context.exception);
+ }
+
+ @autoreleasepool {
+ TestObject *testObject = [TestObject testObject];
+ JSManagedValue *managedTestObject;
+ @autoreleasepool {
+ JSContext *context = [[JSContext alloc] init];
+ context[@"testObject"] = testObject;
+ managedTestObject = [JSManagedValue managedValueWithValue:context[@"testObject"]];
+ [context.virtualMachine addManagedReference:managedTestObject withOwner:testObject];
+ }
+ }
+}
+
+#else
+
+void testObjectiveCAPI()
+{
+}
+
+#endif
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 0a7a8bd3f..73917eb55 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(JavaScriptCore_INCLUDE_DIRECTORIES
+set(JavaScriptCore_INCLUDE_DIRECTORIES
"${CMAKE_BINARY_DIR}"
"${JAVASCRIPTCORE_DIR}"
"${JAVASCRIPTCORE_DIR}/API"
@@ -23,7 +23,7 @@ SET(JavaScriptCore_INCLUDE_DIRECTORIES
"${CMAKE_SOURCE_DIR}/Source"
)
-SET(JavaScriptCore_SOURCES
+set(JavaScriptCore_SOURCES
API/JSBase.cpp
API/JSCallbackConstructor.cpp
API/JSCallbackFunction.cpp
@@ -32,11 +32,12 @@ SET(JavaScriptCore_SOURCES
API/JSContextRef.cpp
API/JSObjectRef.cpp
API/JSProfilerPrivate.cpp
+ API/JSScriptRef.cpp
API/JSStringRef.cpp
API/JSValueRef.cpp
API/JSWeakObjectMapRefPrivate.cpp
API/OpaqueJSString.cpp
-
+
assembler/MacroAssembler.cpp
assembler/LinkBuffer.cpp
@@ -50,14 +51,17 @@ SET(JavaScriptCore_SOURCES
bytecode/CodeType.cpp
bytecode/DFGExitProfile.cpp
bytecode/ExecutionCounter.cpp
+ bytecode/ExitKind.cpp
bytecode/GetByIdStatus.cpp
bytecode/JumpTable.cpp
bytecode/LazyOperandValueProfile.cpp
bytecode/MethodOfGettingAValueProfile.cpp
bytecode/Opcode.cpp
bytecode/PolymorphicPutByIdList.cpp
- bytecode/SpeculatedType.cpp
+ bytecode/PreciseJumpTargets.cpp
bytecode/PutByIdStatus.cpp
+ bytecode/SpeculatedType.cpp
+ bytecode/ReduceWhitespace.cpp
bytecode/ResolveGlobalStatus.cpp
bytecode/SamplingTool.cpp
bytecode/SpecialPointer.cpp
@@ -73,42 +77,52 @@ SET(JavaScriptCore_SOURCES
dfg/DFGArgumentsSimplificationPhase.cpp
dfg/DFGArrayMode.cpp
dfg/DFGAssemblyHelpers.cpp
+ dfg/DFGBackwardsPropagationPhase.cpp
dfg/DFGByteCodeParser.cpp
dfg/DFGCapabilities.cpp
+ dfg/DFGCommon.cpp
dfg/DFGCFAPhase.cpp
dfg/DFGCFGSimplificationPhase.cpp
+ dfg/DFGCPSRethreadingPhase.cpp
dfg/DFGConstantFoldingPhase.cpp
- dfg/DFGCorrectableJumpPoint.cpp
dfg/DFGCSEPhase.cpp
+ dfg/DFGDCEPhase.cpp
dfg/DFGDisassembler.cpp
dfg/DFGDominators.cpp
dfg/DFGDriver.cpp
+ dfg/DFGEdge.cpp
dfg/DFGFixupPhase.cpp
dfg/DFGGraph.cpp
dfg/DFGJITCompiler.cpp
+ dfg/DFGLongLivedState.cpp
dfg/DFGMinifiedNode.cpp
+ dfg/DFGNode.cpp
dfg/DFGNodeFlags.cpp
dfg/DFGOSREntry.cpp
dfg/DFGOSRExit.cpp
dfg/DFGOSRExitCompiler.cpp
dfg/DFGOSRExitCompiler32_64.cpp
dfg/DFGOSRExitCompiler64.cpp
+ dfg/DFGOSRExitJumpPlaceholder.cpp
dfg/DFGOperations.cpp
dfg/DFGPhase.cpp
dfg/DFGPredictionPropagationPhase.cpp
+ dfg/DFGPredictionInjectionPhase.cpp
dfg/DFGRepatch.cpp
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT32_64.cpp
dfg/DFGSpeculativeJIT64.cpp
- dfg/DFGStructureCheckHoistingPhase.cpp
+ dfg/DFGTypeCheckHoistingPhase.cpp
dfg/DFGThunks.cpp
+ dfg/DFGUnificationPhase.cpp
+ dfg/DFGUseKind.cpp
dfg/DFGValueSource.cpp
dfg/DFGVariableAccessDataDump.cpp
dfg/DFGVariableEvent.cpp
dfg/DFGVariableEventStream.cpp
dfg/DFGValidate.cpp
dfg/DFGVirtualRegisterAllocationPhase.cpp
-
+
disassembler/Disassembler.cpp
heap/BlockAllocator.cpp
@@ -126,19 +140,22 @@ SET(JavaScriptCore_SOURCES
heap/IncrementalSweeper.cpp
heap/JITStubRoutineSet.cpp
heap/MachineStackMarker.cpp
+
heap/MarkedAllocator.cpp
heap/MarkedBlock.cpp
heap/MarkedSpace.cpp
heap/MarkStack.cpp
heap/SlotVisitor.cpp
- heap/WeakSet.cpp
- heap/WeakHandleOwner.cpp
+ heap/SuperRegion.cpp
+ heap/Weak.cpp
heap/WeakBlock.cpp
+ heap/WeakHandleOwner.cpp
+ heap/WeakSet.cpp
debugger/Debugger.cpp
debugger/DebuggerActivation.cpp
debugger/DebuggerCallFrame.cpp
-
+
interpreter/AbstractPC.cpp
interpreter/CallFrame.cpp
interpreter/Interpreter.cpp
@@ -147,6 +164,7 @@ SET(JavaScriptCore_SOURCES
jit/ClosureCallStubRoutine.cpp
jit/ExecutableAllocator.cpp
+ jit/ExecutableAllocatorFixedVMPool.cpp
jit/HostCallReturnValue.cpp
jit/GCAwareJITStubRoutine.cpp
jit/JITArithmetic32_64.cpp
@@ -163,6 +181,7 @@ SET(JavaScriptCore_SOURCES
jit/JITPropertyAccess.cpp
jit/JITStubRoutine.cpp
jit/JITStubs.cpp
+ jit/JITThunks.cpp
jit/JumpReplacementWatchpoint.cpp
jit/ThunkGenerators.cpp
@@ -170,12 +189,25 @@ SET(JavaScriptCore_SOURCES
parser/Nodes.cpp
parser/Parser.cpp
parser/ParserArena.cpp
+ parser/SourceProvider.cpp
parser/SourceProviderCache.cpp
+ profiler/ProfilerBytecode.cpp
+ profiler/ProfilerBytecodeSequence.cpp
+ profiler/ProfilerBytecodes.cpp
+ profiler/ProfilerCompilation.cpp
+ profiler/ProfilerCompilationKind.cpp
+ profiler/ProfilerCompiledBytecode.cpp
+ profiler/ProfilerDatabase.cpp
+ profiler/ProfilerOrigin.cpp
+ profiler/ProfilerOriginStack.cpp
+ profiler/ProfilerOSRExit.cpp
+ profiler/ProfilerOSRExitSite.cpp
+ profiler/ProfilerProfiledBytecodes.cpp
profiler/Profile.cpp
profiler/ProfileGenerator.cpp
profiler/ProfileNode.cpp
- profiler/Profiler.cpp
+ profiler/LegacyProfiler.cpp
runtime/ArgList.cpp
runtime/Arguments.cpp
@@ -201,6 +233,7 @@ SET(JavaScriptCore_SOURCES
runtime/ExceptionHelpers.cpp
runtime/Executable.cpp
runtime/FunctionConstructor.cpp
+ runtime/FunctionExecutableDump.cpp
runtime/FunctionPrototype.cpp
runtime/GCActivityCallback.cpp
runtime/GetterSetter.cpp
@@ -215,7 +248,7 @@ SET(JavaScriptCore_SOURCES
runtime/JSDateMath.cpp
runtime/JSFunction.cpp
runtime/JSBoundFunction.cpp
- runtime/JSGlobalData.cpp
+ runtime/VM.cpp
runtime/JSGlobalObject.cpp
runtime/JSGlobalObjectFunctions.cpp
runtime/JSProxy.cpp
@@ -231,18 +264,16 @@ SET(JavaScriptCore_SOURCES
runtime/JSString.cpp
runtime/JSStringJoiner.cpp
runtime/JSSymbolTableObject.cpp
- runtime/JSValue.cpp
+ runtime/JSCJSValue.cpp
runtime/JSVariableObject.cpp
runtime/JSWrapperObject.cpp
runtime/LiteralParser.cpp
runtime/Lookup.cpp
runtime/MathObject.cpp
+ runtime/MemoryStatistics.cpp
runtime/NameConstructor.cpp
- runtime/NameConstructor.h
runtime/NameInstance.cpp
- runtime/NameInstance.h
runtime/NamePrototype.cpp
- runtime/NamePrototype.h
runtime/NativeErrorConstructor.cpp
runtime/NativeErrorPrototype.cpp
runtime/NumberConstructor.cpp
@@ -255,6 +286,8 @@ SET(JavaScriptCore_SOURCES
runtime/PropertyDescriptor.cpp
runtime/PropertyNameArray.cpp
runtime/PropertySlot.cpp
+ runtime/PropertyTable.cpp
+ runtime/PrototypeMap.cpp
runtime/RegExp.cpp
runtime/RegExpCache.cpp
runtime/RegExpConstructor.cpp
@@ -270,9 +303,11 @@ SET(JavaScriptCore_SOURCES
runtime/StringPrototype.cpp
runtime/StringRecursionChecker.cpp
runtime/Structure.cpp
+ runtime/StructureRareData.cpp
runtime/StructureChain.cpp
runtime/SymbolTable.cpp
- runtime/TimeoutChecker.cpp
+ runtime/Watchdog.cpp
+ runtime/WatchdogNone.cpp
tools/CodeProfile.cpp
tools/CodeProfiling.cpp
@@ -284,7 +319,7 @@ SET(JavaScriptCore_SOURCES
yarr/YarrSyntaxChecker.cpp
)
-SET(JavaScriptCore_LUT_FILES
+set(JavaScriptCore_LUT_FILES
runtime/ArrayConstructor.cpp
runtime/ArrayPrototype.cpp
runtime/BooleanPrototype.cpp
@@ -298,34 +333,41 @@ SET(JavaScriptCore_LUT_FILES
runtime/NumberConstructor.cpp
runtime/NumberPrototype.cpp
runtime/ObjectConstructor.cpp
- runtime/ObjectPrototype.cpp
runtime/RegExpConstructor.cpp
runtime/RegExpObject.cpp
runtime/RegExpPrototype.cpp
runtime/StringConstructor.cpp
- runtime/StringPrototype.cpp
)
-SET(JavaScriptCore_LIBRARIES
- ${WTF_LIBRARY_NAME}
+set(JavaScriptCore_LIBRARIES
+ WTF
)
-IF (ENABLE_LLINT)
+if (WTF_USE_ICU_UNICODE)
+ list(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
+ ${ICU_INCLUDE_DIRS}
+ )
+ list(APPEND JavaScriptCore_LIBRARIES
+ ${ICU_I18N_LIBRARIES}
+ )
+endif ()
+
+if (ENABLE_LLINT)
# We cannot check for RUBY_FOUND because it is set only when the full package is installed and
# the only thing we need is the interpreter. Unlike Python, cmake does not provide a macro
# for finding the only Ruby interpreter.
- IF (NOT RUBY_EXECUTABLE)
- MESSAGE(FATAL_ERROR "The Ruby interpreter is needed to generate LLInt files.")
- ENDIF ()
+ if (NOT RUBY_EXECUTABLE)
+ message(FATAL_ERROR "The Ruby interpreter is needed to generate LLInt files.")
+ endif ()
- SET(LLINT_ASM
+ set(LLINT_ASM
llint/LowLevelInterpreter.asm
llint/LowLevelInterpreter32_64.asm
llint/LowLevelInterpreter64.asm
)
- SET(OFFLINE_ASM
- offlineasm/armv7.rb
+ set(OFFLINE_ASM
+ offlineasm/arm.rb
offlineasm/ast.rb
offlineasm/backends.rb
offlineasm/cloop.rb
@@ -342,7 +384,7 @@ IF (ENABLE_LLINT)
offlineasm/x86.rb
)
- ADD_CUSTOM_COMMAND(
+ add_custom_command(
OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntDesiredOffsets.h
MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/offlineasm/generate_offset_extractor.rb
DEPENDS ${LLINT_ASM} ${OFFLINE_ASM}
@@ -358,11 +400,11 @@ IF (ENABLE_LLINT)
# Additionally, setting the OBJECT_DEPENDS property will make LLIntDesiredOffsets.h a Makefile
# dependency of both LLIntOffsetsExtractor and LLIntOffsetsExtractor.cpp, so the command will
# actually be run twice!
- ADD_EXECUTABLE(LLIntOffsetsExtractor
+ add_executable(LLIntOffsetsExtractor
${JAVASCRIPTCORE_DIR}/llint/LLIntOffsetsExtractor.cpp
${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntDesiredOffsets.h
)
- TARGET_LINK_LIBRARIES(LLIntOffsetsExtractor ${WTF_LIBRARY_NAME})
+ target_link_libraries(LLIntOffsetsExtractor WTF)
# The build system will execute asm.rb every time LLIntOffsetsExtractor's mtime is newer than
# LLIntAssembly.h's mtime. The problem we have here is: asm.rb has some built-in optimization
@@ -370,7 +412,7 @@ IF (ENABLE_LLINT)
# LLIntOffsetsExtractor matches, no output is generated. To make this target consistent and avoid
# running this command for every build, we artificially update LLIntAssembly.h's mtime (using touch)
# after every asm.rb run.
- ADD_CUSTOM_COMMAND(
+ add_custom_command(
OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/offlineasm/asm.rb
DEPENDS LLIntOffsetsExtractor ${LLINT_ASM} ${OFFLINE_ASM}
@@ -381,11 +423,11 @@ IF (ENABLE_LLINT)
# The explanation for not making LLIntAssembly.h part of the OBJECT_DEPENDS property of some of
# the .cpp files below is similar to the one in the previous comment. However, since these .cpp
# files are used to build JavaScriptCore itself, we can just add LLIntAssembly.h to JSC_HEADERS
- # since it is used in the ADD_LIBRARY() call at the end of this file.
- LIST(APPEND JavaScriptCore_HEADERS
+ # since it is used in the add_library() call at the end of this file.
+ list(APPEND JavaScriptCore_HEADERS
${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h
)
- LIST(APPEND JavaScriptCore_SOURCES
+ list(APPEND JavaScriptCore_SOURCES
llint/LLIntCLoop.cpp
llint/LLIntData.cpp
llint/LLIntEntrypoints.cpp
@@ -394,16 +436,25 @@ IF (ENABLE_LLINT)
llint/LLIntThunks.cpp
llint/LowLevelInterpreter.cpp
)
-ENDIF ()
+endif ()
+
+set(HASH_LUT_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/create_hash_table)
+macro(GENERATE_HASH_LUT _input _output)
+ add_custom_command(
+ OUTPUT ${_output}
+ DEPENDS ${HASH_LUT_GENERATOR} ${_input}
+ COMMAND ${PERL_EXECUTABLE} ${HASH_LUT_GENERATOR} ${_input} -i > ${_output}
+ VERBATIM)
+ list(APPEND JavaScriptCore_HEADERS ${_output})
+endmacro()
# GENERATOR 1-A: LUT creator
-FOREACH (_file ${JavaScriptCore_LUT_FILES})
- GET_FILENAME_COMPONENT(_name ${_file} NAME_WE)
- GENERATE_HASH_LUT(${JAVASCRIPTCORE_DIR}/${_file} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/${_name}.lut.h)
- LIST(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/${_name}.lut.h)
-ENDFOREACH ()
+foreach (_file ${JavaScriptCore_LUT_FILES})
+ get_filename_component(_name ${_file} NAME_WE)
+ GENERATE_HASH_LUT(${CMAKE_CURRENT_SOURCE_DIR}/${_file} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/${_name}.lut.h)
+endforeach ()
-SET (JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES
+set(JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES
assembler
bytecode
collector/handles
@@ -418,7 +469,7 @@ SET (JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES
yarr
)
-SET (JavaScriptCore_FORWARDING_HEADERS_FILES
+set(JavaScriptCore_FORWARDING_HEADERS_FILES
API/APICast.h
API/APIShims.h
API/JavaScript.h
@@ -427,6 +478,7 @@ SET (JavaScriptCore_FORWARDING_HEADERS_FILES
API/JSContextRefPrivate.h
API/JSObjectRef.h
API/JSObjectRefPrivate.h
+ API/JSScriptRefPrivate.h
API/JSStringRef.h
API/JSStringRefCF.h
API/JSStringRefBSTR.h
@@ -442,38 +494,62 @@ SET (JavaScriptCore_FORWARDING_HEADERS_FILES
# GENERATOR 1-B: particular LUT creator (for 1 file only)
-GENERATE_HASH_LUT(${JAVASCRIPTCORE_DIR}/parser/Keywords.table ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/Lexer.lut.h MAIN_DEPENDENCY)
-LIST(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/Lexer.lut.h)
+GENERATE_HASH_LUT(${CMAKE_CURRENT_SOURCE_DIR}/parser/Keywords.table ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/Lexer.lut.h)
#GENERATOR: "RegExpJitTables.h": tables used by Yarr
-ADD_CUSTOM_COMMAND(
+add_custom_command(
OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h
- MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create_regex_tables
- COMMAND ${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_regex_tables > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h
+ MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/create_regex_tables
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/create_regex_tables > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h
VERBATIM)
-ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/yarr/YarrPattern.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h)
+ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/yarr/YarrPattern.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h)
#GENERATOR: "KeywordLookup.h": keyword decision tree used by the lexer
-ADD_CUSTOM_COMMAND(
+add_custom_command(
OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
- MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/KeywordLookupGenerator.py
- COMMAND ${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/KeywordLookupGenerator.py ${JAVASCRIPTCORE_DIR}/parser/Keywords.table > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
+ MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/KeywordLookupGenerator.py
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/KeywordLookupGenerator.py ${CMAKE_CURRENT_SOURCE_DIR}/parser/Keywords.table > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
VERBATIM)
-ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/parser/Lexer.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h)
+ADD_SOURCE_DEPENDENCIES(${CMAKE_CURRENT_SOURCE_DIR}/parser/Lexer.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h)
-IF (WTF_CPU_ARM)
- LIST(APPEND JavaScriptCore_SOURCES
+if (WTF_CPU_ARM)
+ list(APPEND JavaScriptCore_SOURCES
assembler/ARMAssembler.cpp
assembler/ARMv7Assembler.cpp
assembler/MacroAssemblerARM.cpp
)
-ELSEIF (WTF_CPU_MIPS)
-ELSEIF (WTF_CPU_X86)
-ELSEIF (WTF_CPU_X86_64)
-ELSE ()
- MESSAGE(FATAL_ERROR "Unknown CPU")
-ENDIF ()
+ if (MSVC AND ENABLE_JIT)
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
+ MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create_jit_stubs
+ DEPENDS ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp
+ COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_jit_stubs --prefix=MSVC ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp > ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
+ VERBATIM)
+
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj
+ MAIN_DEPENDENCY ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
+ COMMAND armasm -nologo ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj
+ VERBATIM)
+
+ list(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj)
+ endif ()
+elseif (WTF_CPU_MIPS)
+elseif (WTF_CPU_X86)
+elseif (WTF_CPU_X86_64)
+ if (MSVC AND ENABLE_JIT)
+ add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_DIR}/JITStubsMSVC64.obj
+ MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/jit/JITStubsMSVC64.asm
+ COMMAND ml64 -nologo -c -Fo ${DERIVED_SOURCES_DIR}/JITStubsMSVC64.obj ${JAVASCRIPTCORE_DIR}/jit/JITStubsMSVC64.asm
+ VERBATIM)
+
+ list(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/JITStubsMSVC64.obj)
+ endif ()
+else ()
+ message(FATAL_ERROR "Unknown CPU")
+endif ()
WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
@@ -481,17 +557,21 @@ WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
WEBKIT_CREATE_FORWARDING_HEADERS(JavaScriptCore DIRECTORIES ${JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES} FILES ${JavaScriptCore_FORWARDING_HEADERS_FILES})
-ADD_SUBDIRECTORY(shell)
+add_subdirectory(shell)
WEBKIT_WRAP_SOURCELIST(${JavaScriptCore_SOURCES})
-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 FOLDER "JavaScriptCore")
-SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
-
-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_DIR}")
-ENDIF ()
+include_directories(${JavaScriptCore_INCLUDE_DIRECTORIES})
+add_definitions(-DBUILDING_JavaScriptCore -DSTATICALLY_LINKED_WITH_WTF)
+add_library(JavaScriptCore ${JavaScriptCore_LIBRARY_TYPE} ${JavaScriptCore_HEADERS} ${JavaScriptCore_SOURCES})
+target_link_libraries(JavaScriptCore ${JavaScriptCore_LIBRARIES})
+set_target_properties(JavaScriptCore PROPERTIES FOLDER "JavaScriptCore")
+set_target_properties(JavaScriptCore PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+if (JavaScriptCore_OUTPUT_NAME)
+ set_target_properties(JavaScriptCore PROPERTIES OUTPUT_NAME ${JavaScriptCore_OUTPUT_NAME})
+endif ()
+
+if (SHARED_CORE)
+ set_target_properties(JavaScriptCore PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
+ install(TARGETS JavaScriptCore DESTINATION "${LIB_INSTALL_DIR}")
+endif ()
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
deleted file mode 100644
index df3f15070..000000000
--- a/Source/JavaScriptCore/ChangeLog
+++ /dev/null
@@ -1,9281 +0,0 @@
-2013-04-09 Balazs Kilvady <kilvadyb@homejinni.com>
-
- LLInt conditional branch compilation fault on MIPS.
- https://bugs.webkit.org/show_bug.cgi?id=114264
-
- Reviewed by Filip Pizlo.
-
- Fix conditional branch compilation in LLInt offlineasm.
-
- * offlineasm/mips.rb:
-
-2013-02-18 Balazs Kilvady <kilvadyb@homejinni.com>
-
- MIPS DFG implementation.
- https://bugs.webkit.org/show_bug.cgi?id=101328
-
- Reviewed by Oliver Hunt.
-
- DFG implementation for MIPS.
-
- * assembler/MIPSAssembler.h:
- (JSC::MIPSAssembler::MIPSAssembler):
- (JSC::MIPSAssembler::sllv):
- (JSC::MIPSAssembler::movd):
- (MIPSAssembler):
- (JSC::MIPSAssembler::negd):
- (JSC::MIPSAssembler::labelForWatchpoint):
- (JSC::MIPSAssembler::label):
- (JSC::MIPSAssembler::vmov):
- (JSC::MIPSAssembler::linkDirectJump):
- (JSC::MIPSAssembler::maxJumpReplacementSize):
- (JSC::MIPSAssembler::revertJumpToMove):
- (JSC::MIPSAssembler::replaceWithJump):
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- (JSC::MacroAssembler::poke):
- * assembler/MacroAssemblerMIPS.h:
- (JSC::MacroAssemblerMIPS::add32):
- (MacroAssemblerMIPS):
- (JSC::MacroAssemblerMIPS::and32):
- (JSC::MacroAssemblerMIPS::lshift32):
- (JSC::MacroAssemblerMIPS::mul32):
- (JSC::MacroAssemblerMIPS::or32):
- (JSC::MacroAssemblerMIPS::rshift32):
- (JSC::MacroAssemblerMIPS::urshift32):
- (JSC::MacroAssemblerMIPS::sub32):
- (JSC::MacroAssemblerMIPS::xor32):
- (JSC::MacroAssemblerMIPS::store32):
- (JSC::MacroAssemblerMIPS::jump):
- (JSC::MacroAssemblerMIPS::branchAdd32):
- (JSC::MacroAssemblerMIPS::branchMul32):
- (JSC::MacroAssemblerMIPS::branchSub32):
- (JSC::MacroAssemblerMIPS::branchNeg32):
- (JSC::MacroAssemblerMIPS::call):
- (JSC::MacroAssemblerMIPS::loadDouble):
- (JSC::MacroAssemblerMIPS::moveDouble):
- (JSC::MacroAssemblerMIPS::swapDouble):
- (JSC::MacroAssemblerMIPS::subDouble):
- (JSC::MacroAssemblerMIPS::mulDouble):
- (JSC::MacroAssemblerMIPS::divDouble):
- (JSC::MacroAssemblerMIPS::negateDouble):
- (JSC::MacroAssemblerMIPS::branchEqual):
- (JSC::MacroAssemblerMIPS::branchNotEqual):
- (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
- (JSC::MacroAssemblerMIPS::branchTruncateDoubleToUint32):
- (JSC::MacroAssemblerMIPS::truncateDoubleToInt32):
- (JSC::MacroAssemblerMIPS::truncateDoubleToUint32):
- (JSC::MacroAssemblerMIPS::branchDoubleNonZero):
- (JSC::MacroAssemblerMIPS::branchDoubleZeroOrNaN):
- (JSC::MacroAssemblerMIPS::invert):
- (JSC::MacroAssemblerMIPS::replaceWithJump):
- (JSC::MacroAssemblerMIPS::maxJumpReplacementSize):
- * dfg/DFGAssemblyHelpers.h:
- (AssemblyHelpers):
- (JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
- (JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
- (JSC::DFG::AssemblyHelpers::debugCall):
- * dfg/DFGCCallHelpers.h:
- (CCallHelpers):
- (JSC::DFG::CCallHelpers::setupArguments):
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
- * dfg/DFGFPRInfo.h:
- (DFG):
- (FPRInfo):
- (JSC::DFG::FPRInfo::toRegister):
- (JSC::DFG::FPRInfo::toIndex):
- (JSC::DFG::FPRInfo::debugName):
- * dfg/DFGGPRInfo.h:
- (DFG):
- (GPRInfo):
- (JSC::DFG::GPRInfo::toRegister):
- (JSC::DFG::GPRInfo::toIndex):
- (JSC::DFG::GPRInfo::debugName):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- * jit/JSInterfaceJIT.h:
- (JSInterfaceJIT):
- * runtime/JSGlobalData.h:
- (JSC::ScratchBuffer::allocationSize):
- (ScratchBuffer):
-
-2013-02-01 Balazs Kilvady <kilvadyb@homejinni.com>
-
- offlineasm BaseIndex handling is broken on ARM due to MIPS changes
- https://bugs.webkit.org/show_bug.cgi?id=108261
-
- Reviewed by Filip Pizlo.
-
- offlineasm BaseIndex handling fix on MIPS.
-
- * offlineasm/mips.rb:
- * offlineasm/risc.rb:
-
-2013-01-07 Balazs Kilvady <kilvadyb@homejinni.com>
-
- MIPS LLInt implementation.
- https://bugs.webkit.org/show_bug.cgi?id=99706
-
- Reviewed by Filip Pizlo.
-
- LLInt implementation for MIPS.
-
- * assembler/MacroAssemblerMIPS.h:
- (JSC::MacroAssemblerMIPS::jump):
- * dfg/DFGOperations.cpp:
- (JSC):
- * jit/JITStubs.cpp:
- (JSC):
- * jit/JITStubs.h:
- (JITStackFrame):
- * llint/LLIntOfflineAsmConfig.h:
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * offlineasm/backends.rb:
- * offlineasm/instructions.rb:
- * offlineasm/mips.rb: Added.
-
-2013-02-27 Simon Hausmann <simon.hausmann@digia.com>
-
- [Qt][Mac] Fix massive parallel builds
-
- Reviewed by Tor Arne Vestbø.
-
- There exists a race condition that LLIntDesiredOffsets.h is written to
- by two parllel instances of the ruby script. This patch ensures that similar to the output file,
- the generated file is also prefixed according to the build configuration.
-
- * LLIntOffsetsExtractor.pro:
-
-2012-12-18 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Restrictions on oversize CopiedBlock allocations should be relaxed
- https://bugs.webkit.org/show_bug.cgi?id=105339
-
- Reviewed by Filip Pizlo.
-
- Currently the DFG has a single branch in the inline allocation path for property/array storage where
- it checks to see if the number of bytes requested will fit in the current block. This does not match
- what the C++ allocation path does; it checks if the requested number of bytes is oversize, and then
- if it's not, it tries to fit it in the current block. The garbage collector assumes that ALL allocations
- that are greater than 16KB are in oversize blocks. Therefore, this mismatch can lead to crashes when
- the collector tries to perform some operation on a CopiedBlock.
-
- To avoid adding an extra branch to the inline allocation path in the JIT, we should make it so that
- oversize blocks are allocated on the same alignment boundaries so that there is a single mask to find
- the block header of any CopiedBlock (rather than two, one for normal and one for oversize blocks), and
- we should figure out if a block is oversize by some other method than just whatever the JSObject says
- it is. One way we could record this info Region of the block, since we allocate a one-off Region for
- oversize blocks.
-
- * heap/BlockAllocator.h:
- (JSC::Region::isCustomSize):
- (Region):
- (JSC::Region::createCustomSize):
- (JSC::Region::Region):
- (JSC::BlockAllocator::deallocateCustomSize):
- * heap/CopiedBlock.h:
- (CopiedBlock):
- (JSC::CopiedBlock::isOversize):
- (JSC):
- * heap/CopiedSpace.cpp:
- (JSC::CopiedSpace::tryAllocateOversize):
- (JSC::CopiedSpace::tryReallocate):
- (JSC::CopiedSpace::tryReallocateOversize):
- * heap/CopiedSpace.h:
- (CopiedSpace):
- * heap/CopiedSpaceInlines.h:
- (JSC::CopiedSpace::contains):
- (JSC::CopiedSpace::tryAllocate):
- (JSC):
- * heap/CopyVisitor.h:
- (CopyVisitor):
- * heap/CopyVisitorInlines.h:
- (JSC::CopyVisitor::checkIfShouldCopy):
- (JSC::CopyVisitor::didCopy):
- * heap/SlotVisitorInlines.h:
- (JSC::SlotVisitor::copyLater):
- * runtime/JSObject.cpp:
- (JSC::JSObject::copyButterfly):
-
-2012-12-17 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Butterfly::growArrayRight shouldn't be called on null Butterfly objects
- https://bugs.webkit.org/show_bug.cgi?id=105221
-
- Reviewed by Filip Pizlo.
-
- Currently we depend upon the fact that Butterfly::growArrayRight works with null Butterfly
- objects purely by coincidence. We should add a new static function that null checks the old
- Butterfly object and creates a new one if it's null, or calls growArrayRight if it isn't for
- use in the couple of places in JSObject that expect such behavior to work.
-
- * runtime/Butterfly.h:
- (Butterfly):
- * runtime/ButterflyInlines.h:
- (JSC::Butterfly::createOrGrowArrayRight):
- (JSC):
- * runtime/JSObject.cpp:
- (JSC::JSObject::createInitialIndexedStorage):
- (JSC::JSObject::createArrayStorage):
-
-2013-01-02 Simon Hausmann <simon.hausmann@digia.com>
-
- [MinGW-w64] Centralize workaround for pow() implementation
- https://bugs.webkit.org/show_bug.cgi?id=105925
-
- Reviewed by Sam Weinig.
-
- As suggested by Sam, move the MinGW-w64 workaround into MathExtras.h
- away from the JSC usage.
-
- * runtime/MathObject.cpp:
- (JSC::mathPow):
-
-2012-12-17 Jonathan Liu <net147@gmail.com>
-
- Fix Math.pow implementation with MinGW-w64
- https://bugs.webkit.org/show_bug.cgi?id=105087
-
- Reviewed by Simon Hausmann.
-
- The MinGW-w64 runtime has different behaviour for pow()
- compared to other C runtimes. This results in the following
- test262 tests failing with the latest MinGW-w64 runtime:
- - S15.8.2.13_A14
- - S15.8.2.13_A16
- - S15.8.2.13_A20
- - S15.8.2.13_A22
-
- Handle the special cases that are different with MinGW-w64.
-
- * runtime/MathObject.cpp:
- (JSC::mathPow):
-
-2012-12-07 Jonathan Liu <net147@gmail.com>
-
- Add missing forward declaration for JSC::ArrayAllocationProfile
- https://bugs.webkit.org/show_bug.cgi?id=104425
-
- Reviewed by Kentaro Hara.
-
- The header for the JSC::ArrayConstructor class is missing a forward
- declaration for the JSC::ArrayAllocationProfile class which causes
- compilation to fail when compiling with MinGW-w64.
-
- * runtime/ArrayConstructor.h:
- (JSC):
-
-2012-12-07 Jonathan Liu <net147@gmail.com>
-
- Add missing const qualifier to JSC::CodeBlock::getJITType()
- https://bugs.webkit.org/show_bug.cgi?id=104424
-
- Reviewed by Laszlo Gombos.
-
- JSC::CodeBlock::getJITType() has the const qualifier when JIT is
- enabled but is missing the const qualifier when JIT is disabled.
-
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::getJITType):
-
-2012-11-30 Pierre Rossi <pierre.rossi@gmail.com>
-
- [Qt] Unreviewed speculative Mac build fix after r136232
-
- Update the include path so that LLIntAssembly.h is picked up.
- The bot didn't break until later when a clean build was triggered.
-
- * JavaScriptCore.pri:
-
-2012-11-30 Allan Sandfeld Jensen <allan.jensen@digia.com>
-
- Crash in conversion of empty OpaqueJSString to Identifier
- https://bugs.webkit.org/show_bug.cgi?id=101867
-
- Reviewed by NOBODY (OOPS!).
-
- The constructor call used for both null and empty OpaqueJSStrings results
- in an assertion voilation and crash. This patch instead uses the Identifier
- constructors which are specifically for null and empty Identifier.
-
- * API/OpaqueJSString.cpp:
- (OpaqueJSString::identifier):
-
-2012-11-30 Tor Arne Vestbø <tor.arne.vestbo@digia.com>
-
- [Qt] Place the LLIntOffsetsExtractor binaries in debug/release subdirs on Mac
-
- Otherwise we'll end up using the same LLIntAssembly.h for both build
- configs of JavaScriptCore -- one of them which will be for the wrong
- config.
-
- Reviewed by Simon Hausmann.
-
- * LLIntOffsetsExtractor.pro:
-
-2012-11-30 Julien BRIANCEAU <jbrianceau@nds.com>
-
- [sh4] Fix compilation warnings in JavaScriptCore JIT for sh4 arch
- https://bugs.webkit.org/show_bug.cgi?id=103378
-
- Reviewed by Filip Pizlo.
-
- * assembler/MacroAssemblerSH4.h:
- (JSC::MacroAssemblerSH4::branchTest32):
- (JSC::MacroAssemblerSH4::branchAdd32):
- (JSC::MacroAssemblerSH4::branchMul32):
- (JSC::MacroAssemblerSH4::branchSub32):
- (JSC::MacroAssemblerSH4::branchOr32):
-
-2012-11-29 Rafael Weinstein <rafaelw@chromium.org>
-
- [HTMLTemplateElement] Add feature flag
- https://bugs.webkit.org/show_bug.cgi?id=103694
-
- Reviewed by Adam Barth.
-
- This flag will guard the implementation of the HTMLTemplateElement.
- http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-11-29 Filip Pizlo <fpizlo@apple.com>
-
- It should be easy to find code blocks in debug dumps
- https://bugs.webkit.org/show_bug.cgi?id=103623
-
- Reviewed by Goeffrey Garen.
-
- This gives CodeBlock a relatively strong, but also relatively compact, hash. We compute
- it lazily so that it only impacts run-time when debug support is enabled. We stringify
- it smartly so that it's short and easy to type. We base it on the source code so that
- the optimization level is irrelevant. And, we use SHA1 since it's already in our code
- base. Now, when a piece of code wants to print some debugging to say that it's operating
- on some code block, it can use this CodeBlockHash instead of memory addresses.
-
- This also takes CodeBlock debugging into the new world of print() and dataLog(). In
- particular, CodeBlock::dump() corresponds to the thing you want printed if you do:
-
- dataLog("I heart ", *myCodeBlock);
-
- Probably, you want to just print some identifying information at this point rather than
- the full bytecode dump. So, the existing CodeBlock::dump() has been renamed to
- CodeBlock::dumpBytecode(), and CodeBlock::dump() now prints the CodeBlockHash plus just
- a few little tidbits.
-
- Here's an example of CodeBlock::dump() output:
-
- EkILzr:[0x103883a00, BaselineFunctionCall]
-
- EkILzr is the CodeBlockHash. 0x103883a00 is the CodeBlock's address in memory. The other
- part is self-explanatory.
-
- Finally, this new notion of CodeBlockHash is available for other purposes like bisecting
- breakage. As such CodeBlockHash has all of the comparison operator overloads. When
- bisecting in DFGDriver.cpp, you can now say things like:
-
- if (codeBlock->hash() < CodeBlockHash("CAAAAA"))
- return false;
-
- And yes, CAAAAA is near the median hash, and the largest one is smaller than E99999. Such
- is life when you use base 62 to encode a 32-bit number.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * bytecode/CallLinkInfo.h:
- (CallLinkInfo):
- (JSC::CallLinkInfo::specializationKind):
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::hash):
- (JSC):
- (JSC::CodeBlock::dumpAssumingJITType):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::dumpBytecode):
- (JSC::CodeBlock::CodeBlock):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::resetStubInternal):
- (JSC::CodeBlock::reoptimize):
- (JSC::ProgramCodeBlock::jettison):
- (JSC::EvalCodeBlock::jettison):
- (JSC::FunctionCodeBlock::jettison):
- (JSC::CodeBlock::shouldOptimizeNow):
- (JSC::CodeBlock::tallyFrequentExitSites):
- (JSC::CodeBlock::dumpValueProfiles):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::specializationKind):
- (CodeBlock):
- (JSC::CodeBlock::getJITType):
- * bytecode/CodeBlockHash.cpp: Added.
- (JSC):
- (JSC::CodeBlockHash::CodeBlockHash):
- (JSC::CodeBlockHash::dump):
- * bytecode/CodeBlockHash.h: Added.
- (JSC):
- (CodeBlockHash):
- (JSC::CodeBlockHash::CodeBlockHash):
- (JSC::CodeBlockHash::hash):
- (JSC::CodeBlockHash::operator==):
- (JSC::CodeBlockHash::operator!=):
- (JSC::CodeBlockHash::operator<):
- (JSC::CodeBlockHash::operator>):
- (JSC::CodeBlockHash::operator<=):
- (JSC::CodeBlockHash::operator>=):
- * bytecode/CodeBlockWithJITType.h: Added.
- (JSC):
- (CodeBlockWithJITType):
- (JSC::CodeBlockWithJITType::CodeBlockWithJITType):
- (JSC::CodeBlockWithJITType::dump):
- * bytecode/CodeOrigin.cpp: Added.
- (JSC):
- (JSC::CodeOrigin::inlineDepthForCallFrame):
- (JSC::CodeOrigin::inlineDepth):
- (JSC::CodeOrigin::inlineStack):
- (JSC::InlineCallFrame::hash):
- * bytecode/CodeOrigin.h:
- (InlineCallFrame):
- (JSC::InlineCallFrame::specializationKind):
- (JSC):
- * bytecode/CodeType.cpp: Added.
- (WTF):
- (WTF::printInternal):
- * bytecode/CodeType.h:
- (WTF):
- * bytecode/ExecutionCounter.cpp:
- (JSC::ExecutionCounter::dump):
- * bytecode/ExecutionCounter.h:
- (ExecutionCounter):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseCodeBlock):
- * dfg/DFGDisassembler.cpp:
- (JSC::DFG::Disassembler::dump):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::Graph::dumpCodeOrigin):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOperations.cpp:
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::generateProtoChainAccessStub):
- (JSC::DFG::tryCacheGetByID):
- (JSC::DFG::tryBuildGetByIDList):
- (JSC::DFG::emitPutReplaceStub):
- (JSC::DFG::emitPutTransitionStub):
- (JSC::DFG::dfgLinkClosureCall):
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::dumpCallFrame):
- * jit/JITCode.cpp: Added.
- (WTF):
- (WTF::printInternal):
- * jit/JITCode.h:
- (JSC::JITCode::jitType):
- (WTF):
- * jit/JITDisassembler.cpp:
- (JSC::JITDisassembler::dump):
- (JSC::JITDisassembler::dumpForInstructions):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::privateCompilePutByIdTransition):
- (JSC::JIT::privateCompilePatchGetArrayLength):
- (JSC::JIT::privateCompileGetByIdProto):
- (JSC::JIT::privateCompileGetByIdSelfList):
- (JSC::JIT::privateCompileGetByIdProtoList):
- (JSC::JIT::privateCompileGetByIdChainList):
- (JSC::JIT::privateCompileGetByIdChain):
- (JSC::JIT::privateCompileGetByVal):
- (JSC::JIT::privateCompilePutByVal):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::privateCompilePutByIdTransition):
- (JSC::JIT::privateCompilePatchGetArrayLength):
- (JSC::JIT::privateCompileGetByIdProto):
- (JSC::JIT::privateCompileGetByIdSelfList):
- (JSC::JIT::privateCompileGetByIdProtoList):
- (JSC::JIT::privateCompileGetByIdChainList):
- (JSC::JIT::privateCompileGetByIdChain):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- * runtime/CodeSpecializationKind.cpp: Added.
- (WTF):
- (WTF::printInternal):
- * runtime/CodeSpecializationKind.h:
- (JSC::specializationFromIsCall):
- (JSC):
- (JSC::specializationFromIsConstruct):
- (WTF):
- * runtime/Executable.cpp:
- (JSC::ExecutableBase::hashFor):
- (JSC):
- (JSC::NativeExecutable::hashFor):
- (JSC::ScriptExecutable::hashFor):
- * runtime/Executable.h:
- (ExecutableBase):
- (NativeExecutable):
- (ScriptExecutable):
- (JSC::ScriptExecutable::source):
-
-2012-11-29 Michael Saboff <msaboff@apple.com>
-
- Speculative Windows build fix after r136086.
-
- Unreviewed build fix.
-
- Suspect that ?setDumpsGeneratedCode@BytecodeGenerator@JSC@@SAX_N@Z needs to be removed from Windows
- export list since the symbol was removed in r136086.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-11-28 Filip Pizlo <fpizlo@apple.com>
-
- SpeculatedType dumping should not use the static char buffer[thingy] idiom
- https://bugs.webkit.org/show_bug.cgi?id=103584
-
- Reviewed by Michael Saboff.
-
- Changed SpeculatedType to be "dumpable" by saying things like:
-
- dataLog("thingy = ", SpeculationDump(thingy))
-
- Removed the old stringification functions, and changed all code that referred to them
- to use the new dataLog()/print() style.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * bytecode/SpeculatedType.cpp:
- (JSC::dumpSpeculation):
- (JSC::speculationToAbbreviatedString):
- (JSC::dumpSpeculationAbbreviated):
- * bytecode/SpeculatedType.h:
- * bytecode/ValueProfile.h:
- (JSC::ValueProfileBase::dump):
- * bytecode/VirtualRegister.h:
- (WTF::printInternal):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::dump):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
- (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::Graph::dump):
- (JSC::DFG::Graph::predictArgumentTypes):
- * dfg/DFGGraph.h:
- (Graph):
- * dfg/DFGStructureAbstractValue.h:
- * dfg/DFGVariableAccessDataDump.cpp: Added.
- (JSC::DFG::VariableAccessDataDump::VariableAccessDataDump):
- (JSC::DFG::VariableAccessDataDump::dump):
- * dfg/DFGVariableAccessDataDump.h: Added.
- (VariableAccessDataDump):
-
-2012-11-28 Michael Saboff <msaboff@apple.com>
-
- Change Bytecompiler s_dumpsGeneratedCode to an Options value
- https://bugs.webkit.org/show_bug.cgi?id=103588
-
- Reviewed by Filip Pizlo.
-
- Moved the control of dumping bytecodes to Options::dumpGeneratedBytecodes.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::CodeBlock):
- * bytecompiler/BytecodeGenerator.cpp:
- * bytecompiler/BytecodeGenerator.h:
- * jsc.cpp:
- (runWithScripts):
- * runtime/Options.h:
-
-2012-11-28 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Copying phase should use work lists
- https://bugs.webkit.org/show_bug.cgi?id=101390
-
- Reviewed by Filip Pizlo.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * heap/BlockAllocator.cpp:
- (JSC::BlockAllocator::BlockAllocator):
- * heap/BlockAllocator.h: New RegionSet for CopyWorkListSegments.
- (BlockAllocator):
- (JSC::CopyWorkListSegment):
- * heap/CopiedBlock.h: Added a per-block CopyWorkList to keep track of the JSCells that need to be revisited during the copying
- phase to copy their backing stores.
- (CopiedBlock):
- (JSC::CopiedBlock::CopiedBlock):
- (JSC::CopiedBlock::didSurviveGC):
- (JSC::CopiedBlock::didEvacuateBytes): There is now a one-to-one relationship between GCThreads and the CopiedBlocks they're
- responsible for evacuating, we no longer need any of that fancy compare and swap stuff.
- (JSC::CopiedBlock::pin):
- (JSC::CopiedBlock::hasWorkList):
- (JSC::CopiedBlock::workList):
- * heap/CopiedBlockInlines.h: Added.
- (JSC::CopiedBlock::reportLiveBytes): Since we now have to grab a SpinLock to perform operations on the CopyWorkList during marking,
- we don't need to do any of that fancy compare and swap stuff we were doing for tracking live bytes.
- * heap/CopiedSpace.h:
- (CopiedSpace):
- * heap/CopiedSpaceInlines.h:
- (JSC::CopiedSpace::pin):
- * heap/CopyVisitor.cpp:
- (JSC::CopyVisitor::copyFromShared): We now iterate over a range of CopiedBlocks rather than MarkedBlocks and revisit the cells in those
- blocks' CopyWorkLists.
- * heap/CopyVisitor.h:
- (CopyVisitor):
- * heap/CopyVisitorInlines.h:
- (JSC::CopyVisitor::visitCell): The function responsible for calling the correct copyBackingStore() function for each JSCell from
- a CopiedBlock's CopyWorkList.
- (JSC::CopyVisitor::didCopy): We no longer need to check if the block is empty here because we know exactly when we're done
- evacuating a CopiedBlock, which is when we've gone through all of the CopiedBlock's CopyWorkList.
- * heap/CopyWorkList.h: Added.
- (CopyWorkListSegment): Individual chunk of a CopyWorkList that is allocated from the BlockAllocator.
- (JSC::CopyWorkListSegment::create):
- (JSC::CopyWorkListSegment::size):
- (JSC::CopyWorkListSegment::isFull):
- (JSC::CopyWorkListSegment::get):
- (JSC::CopyWorkListSegment::append):
- (JSC::CopyWorkListSegment::CopyWorkListSegment):
- (JSC::CopyWorkListSegment::data):
- (JSC::CopyWorkListSegment::endOfBlock):
- (CopyWorkListIterator): Responsible for giving CopyVisitors a contiguous notion of access across the separate CopyWorkListSegments
- that make up each CopyWorkList.
- (JSC::CopyWorkListIterator::get):
- (JSC::CopyWorkListIterator::operator*):
- (JSC::CopyWorkListIterator::operator->):
- (JSC::CopyWorkListIterator::operator++):
- (JSC::CopyWorkListIterator::operator==):
- (JSC::CopyWorkListIterator::operator!=):
- (JSC::CopyWorkListIterator::CopyWorkListIterator):
- (CopyWorkList): Data structure that keeps track of the JSCells that need copying in a particular CopiedBlock.
- (JSC::CopyWorkList::CopyWorkList):
- (JSC::CopyWorkList::~CopyWorkList):
- (JSC::CopyWorkList::append):
- (JSC::CopyWorkList::begin):
- (JSC::CopyWorkList::end):
- * heap/GCThreadSharedData.cpp:
- (JSC::GCThreadSharedData::GCThreadSharedData): We no longer use the m_blockSnapshot from the Heap during the copying phase.
- (JSC::GCThreadSharedData::didStartCopying): We now copy the set of all blocks in the CopiedSpace to a separate vector for
- iterating over during the copying phase since the set stored in the CopiedSpace will change as blocks are evacuated and
- recycled throughout the copying phase.
- * heap/GCThreadSharedData.h:
- (GCThreadSharedData):
- * heap/Heap.h:
- (Heap):
- * heap/SlotVisitor.h: We now need to know the object who is being marked that has a backing store so that we can store it
- in a CopyWorkList to revisit later during the copying phase.
- * heap/SlotVisitorInlines.h:
- (JSC::SlotVisitor::copyLater):
- * runtime/JSObject.cpp:
- (JSC::JSObject::visitButterfly):
-
-2012-11-28 Filip Pizlo <fpizlo@apple.com>
-
- Disassembly methods should be able to disassemble to any PrintStream& rather than always using WTF::dataFile()
- https://bugs.webkit.org/show_bug.cgi?id=103492
-
- Reviewed by Mark Hahnenberg.
-
- Switched disassembly code to use PrintStream&, and to use print() rather than printf().
-
- * dfg/DFGDisassembler.cpp:
- (JSC::DFG::Disassembler::dump):
- (DFG):
- (JSC::DFG::Disassembler::dumpDisassembly):
- * dfg/DFGDisassembler.h:
- (Disassembler):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::printWhiteSpace):
- (JSC::DFG::Graph::dumpCodeOrigin):
- (JSC::DFG::Graph::printNodeWhiteSpace):
- (JSC::DFG::Graph::dump):
- (DFG):
- (JSC::DFG::Graph::dumpBlockHeader):
- * dfg/DFGGraph.h:
- (Graph):
- * jit/JITDisassembler.cpp:
- (JSC::JITDisassembler::dump):
- (JSC::JITDisassembler::dumpForInstructions):
- (JSC::JITDisassembler::dumpDisassembly):
- * jit/JITDisassembler.h:
- (JITDisassembler):
-
-2012-11-28 Filip Pizlo <fpizlo@apple.com>
-
- It should be possible to say dataLog("count = ", count, "\n") instead of dataLogF("count = %d\n", count)
- https://bugs.webkit.org/show_bug.cgi?id=103009
-
- Reviewed by Michael Saboff.
-
- Instead of converting all of JSC to use the new dataLog()/print() methods, I just changed
- one place: dumping of abstract values. This is mainly just to ensure that the code I
- added to WTF is actually doing things.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::dump):
- (WTF):
- (WTF::printInternal):
- * dfg/DFGStructureAbstractValue.h:
- (JSC::DFG::StructureAbstractValue::dump):
- (WTF):
- (WTF::printInternal):
-
-2012-11-28 Oliver Hunt <oliver@apple.com>
-
- Make source cache include more information about the function extent.
- https://bugs.webkit.org/show_bug.cgi?id=103552
-
- Reviewed by Gavin Barraclough.
-
- Add a bit more information to the source cache.
-
- * parser/Parser.cpp:
- (JSC::::parseFunctionInfo):
- Store the function start offset
- * parser/SourceProviderCacheItem.h:
- (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
- (SourceProviderCacheItem):
- Add additional field for the start of the real function string, and re-arrange
- fields to avoid growing the struct.
-
-2012-11-27 Filip Pizlo <fpizlo@apple.com>
-
- Convert some remaining uses of FILE* to PrintStream&.
-
- Rubber stamped by Mark Hahnenberg.
-
- * bytecode/ValueProfile.h:
- (JSC::ValueProfileBase::dump):
- * bytecode/ValueRecovery.h:
- (JSC::ValueRecovery::dump):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseCodeBlock):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::dumpChildren):
-
-2012-11-27 Filip Pizlo <fpizlo@apple.com>
-
- Fix indentation in JSValue.h
-
- Rubber stamped by Mark Hahnenberg.
-
- * runtime/JSValue.h:
-
-2012-11-26 Filip Pizlo <fpizlo@apple.com>
-
- DFG SetLocal should use forwardSpeculationCheck instead of its own half-baked version of same
- https://bugs.webkit.org/show_bug.cgi?id=103353
-
- Reviewed by Oliver Hunt and Gavin Barraclough.
-
- Made it possible to use forward speculations for most of the operand classes. Changed the conditional
- direction parameter from being 'bool isForward' to an enum (SpeculationDirection). Changed SetLocal
- to use forward speculations and got rid of its half-baked version of same.
-
- Also added the ability to force the DFG's disassembler to dump all nodes, even ones that are dead.
-
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGDisassembler.cpp:
- (JSC::DFG::Disassembler::dump):
- * dfg/DFGDriver.cpp:
- (JSC::DFG::compile):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::speculationCheck):
- (DFG):
- (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
- (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
- (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
- (JSC::DFG::SpeculativeJIT::fillStorage):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
- (JSC::DFG::SpeculateIntegerOperand::gpr):
- (SpeculateIntegerOperand):
- (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
- (JSC::DFG::SpeculateDoubleOperand::fpr):
- (SpeculateDoubleOperand):
- (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
- (JSC::DFG::SpeculateCellOperand::gpr):
- (SpeculateCellOperand):
- (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
- (JSC::DFG::SpeculateBooleanOperand::gpr):
- (SpeculateBooleanOperand):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
- (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
- (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
- (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
- (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
- (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
- (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
- (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
- (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
- (JSC::DFG::SpeculativeJIT::compile):
- * runtime/Options.h:
- (JSC):
-
-2012-11-26 Daniel Bates <dbates@webkit.org>
-
- Substitute "allSeparators8Bit" for "allSeperators8Bit" in JSC::jsSpliceSubstringsWithSeparators()
- <https://bugs.webkit.org/show_bug.cgi?id=103303>
-
- Reviewed by Simon Fraser.
-
- Fix misspelled word, "Seperators" [sic], in a local variable name in JSC::jsSpliceSubstringsWithSeparators().
-
- * runtime/StringPrototype.cpp:
- (JSC::jsSpliceSubstringsWithSeparators):
-
-2012-11-26 Daniel Bates <dbates@webkit.org>
-
- JavaScript fails to handle String.replace() with large replacement string
- https://bugs.webkit.org/show_bug.cgi?id=102956
- <rdar://problem/12738012>
-
- Reviewed by Oliver Hunt.
-
- Fix an issue where we didn't check for overflow when computing the length
- of the result of String.replace() with a large replacement string.
-
- * runtime/StringPrototype.cpp:
- (JSC::jsSpliceSubstringsWithSeparators):
-
-2012-11-26 Zeno Albisser <zeno@webkit.org>
-
- [Qt] Fix the LLInt build on Mac
- https://bugs.webkit.org/show_bug.cgi?id=97587
-
- Reviewed by Simon Hausmann.
-
- * DerivedSources.pri:
- * JavaScriptCore.pro:
-
-2012-11-26 Oliver Hunt <oliver@apple.com>
-
- 32-bit build fix. Move the method decalration outside of the X86_64 only section.
-
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- (JSC::MacroAssembler::shouldConsiderBlinding):
-
-2012-11-26 Oliver Hunt <oliver@apple.com>
-
- Don't blind all the things.
- https://bugs.webkit.org/show_bug.cgi?id=102572
-
- Reviewed by Gavin Barraclough.
-
- No longer blind all the constants in the instruction stream. We use a
- simple non-deterministic filter to avoid blinding everything. Also modified
- the basic integer blinding logic to avoid blinding small negative values.
-
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- (JSC::MacroAssembler::shouldConsiderBlinding):
- (JSC::MacroAssembler::shouldBlind):
-
-2012-11-26 Mark Hahnenberg <mhahnenberg@apple.com>
-
- JSObject::copyButterfly doesn't handle undecided indexing types correctly
- https://bugs.webkit.org/show_bug.cgi?id=102573
-
- Reviewed by Filip Pizlo.
-
- We don't do any copying into the newly allocated vector and we don't zero-initialize CopiedBlocks
- during the copying phase, so we end up with uninitialized memory in arrays which have undecided indexing
- types. We should just do the actual memcpy from the old block to the new one.
-
- * runtime/JSObject.cpp:
- (JSC::JSObject::copyButterfly): Just do the same thing that we do for other contiguous indexing types.
-
-2012-11-26 Julien BRIANCEAU <jbrianceau@nds.com>
-
- [sh4] JavaScriptCore JIT build is broken since r135330
- Add missing implementation for sh4 arch.
- https://bugs.webkit.org/show_bug.cgi?id=103145
-
- Reviewed by Oliver Hunt.
-
- * assembler/MacroAssemblerSH4.h:
- (JSC::MacroAssemblerSH4::canJumpReplacePatchableBranchPtrWithPatch):
- (MacroAssemblerSH4):
- (JSC::MacroAssemblerSH4::startOfBranchPtrWithPatchOnRegister):
- (JSC::MacroAssemblerSH4::revertJumpReplacementToBranchPtrWithPatch):
- (JSC::MacroAssemblerSH4::startOfPatchableBranchPtrWithPatchOnAddress):
- (JSC::MacroAssemblerSH4::revertJumpReplacementToPatchableBranchPtrWithPatch):
- * assembler/SH4Assembler.h:
- (JSC::SH4Assembler::revertJump):
- (SH4Assembler):
- (JSC::SH4Assembler::printInstr):
-
-2012-11-26 Yuqiang Xian <yuqiang.xian@intel.com>
-
- Use load64 instead of loadPtr to load a JSValue on JSVALUE64 platforms
- https://bugs.webkit.org/show_bug.cgi?id=100909
-
- Reviewed by Brent Fulgham.
-
- This is a (trivial) fix after r132701.
-
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
-
-2012-11-26 Gabor Ballabas <gaborb@inf.u-szeged.hu>
-
- [Qt][ARM] REGRESSION(r130826): It made 33 JSC test and 466 layout tests crash
- https://bugs.webkit.org/show_bug.cgi?id=98857
-
- Reviewed by Zoltan Herczeg.
-
- Implement a new version of patchableBranch32 to fix crashing JSC
- tests.
-
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- * assembler/MacroAssemblerARM.h:
- (JSC::MacroAssemblerARM::patchableBranch32):
- (MacroAssemblerARM):
-
-2012-11-21 Filip Pizlo <fpizlo@apple.com>
-
- Any function that can log things should be able to easily log them to a memory buffer as well
- https://bugs.webkit.org/show_bug.cgi?id=103000
-
- Reviewed by Sam Weinig.
-
- Change all users of WTF::dataFile() to expect a PrintStream& rather than a FILE*.
-
- * bytecode/Operands.h:
- (JSC::OperandValueTraits::dump):
- (JSC::dumpOperands):
- (JSC):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::dump):
- * dfg/DFGAbstractState.h:
- (AbstractState):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::dump):
- * dfg/DFGCommon.h:
- (JSC::DFG::NodeIndexTraits::dump):
- * dfg/DFGStructureAbstractValue.h:
- (JSC::DFG::StructureAbstractValue::dump):
- * dfg/DFGVariableEvent.cpp:
- (JSC::DFG::VariableEvent::dump):
- (JSC::DFG::VariableEvent::dumpFillInfo):
- (JSC::DFG::VariableEvent::dumpSpillInfo):
- * dfg/DFGVariableEvent.h:
- (VariableEvent):
- * disassembler/Disassembler.h:
- (JSC):
- (JSC::tryToDisassemble):
- * disassembler/UDis86Disassembler.cpp:
- (JSC::tryToDisassemble):
-
-2012-11-23 Alexis Menard <alexis@webkit.org>
-
- [CSS3 Backgrounds and Borders] Implement new CSS3 background-position parsing.
- https://bugs.webkit.org/show_bug.cgi?id=102104
-
- Reviewed by Julien Chaffraix.
-
- Protect the new feature behind a feature flag.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-11-23 Gabor Ballabas <gaborb@inf.u-szeged.hu>
-
- Fix the ARM traditional build after r135330
- https://bugs.webkit.org/show_bug.cgi?id=102871
-
- Reviewed by Zoltan Herczeg.
-
- Added missing functionality to traditional ARM architecture.
-
- * assembler/ARMAssembler.h:
- (JSC::ARMAssembler::revertJump):
- (ARMAssembler):
- * assembler/MacroAssemblerARM.h:
- (JSC::MacroAssemblerARM::startOfPatchableBranchPtrWithPatchOnAddress):
- (JSC::MacroAssemblerARM::startOfBranchPtrWithPatchOnRegister):
- (MacroAssemblerARM):
- (JSC::MacroAssemblerARM::revertJumpReplacementToBranchPtrWithPatch):
-
-2012-11-16 Yury Semikhatsky <yurys@chromium.org>
-
- Memory instrumentation: extract MemoryObjectInfo declaration into a separate file
- https://bugs.webkit.org/show_bug.cgi?id=102510
-
- Reviewed by Pavel Feldman.
-
- Added new symbols for the methods that have moved into .../wtf/MemoryInstrumentation.cpp
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-11-23 Julien BRIANCEAU <jbrianceau@nds.com>
-
- [sh4] JavaScriptCore JIT build is broken since r130839
- Add missing implementation for sh4 arch.
- https://bugs.webkit.org/show_bug.cgi?id=101479
-
- Reviewed by Filip Pizlo.
-
- * assembler/MacroAssemblerSH4.h:
- (JSC::MacroAssemblerSH4::load8Signed):
- (MacroAssemblerSH4):
- (JSC::MacroAssemblerSH4::load16Signed):
- (JSC::MacroAssemblerSH4::store8):
- (JSC::MacroAssemblerSH4::store16):
- (JSC::MacroAssemblerSH4::moveDoubleToInts):
- (JSC::MacroAssemblerSH4::moveIntsToDouble):
- (JSC::MacroAssemblerSH4::loadFloat):
- (JSC::MacroAssemblerSH4::loadDouble):
- (JSC::MacroAssemblerSH4::storeFloat):
- (JSC::MacroAssemblerSH4::storeDouble):
- (JSC::MacroAssemblerSH4::addDouble):
- (JSC::MacroAssemblerSH4::convertFloatToDouble):
- (JSC::MacroAssemblerSH4::convertDoubleToFloat):
- (JSC::MacroAssemblerSH4::urshift32):
- * assembler/SH4Assembler.h:
- (JSC::SH4Assembler::sublRegReg):
- (JSC::SH4Assembler::subvlRegReg):
- (JSC::SH4Assembler::floatfpulfrn):
- (JSC::SH4Assembler::fldsfpul):
- (JSC::SH4Assembler::fstsfpul):
- (JSC::SH4Assembler::dcnvsd):
- (SH4Assembler):
- (JSC::SH4Assembler::movbRegMem):
- (JSC::SH4Assembler::sizeOfConstantPool):
- (JSC::SH4Assembler::linkJump):
- (JSC::SH4Assembler::printInstr):
- (JSC::SH4Assembler::printBlockInstr):
-
-2012-11-22 Balazs Kilvady <kilvadyb@homejinni.com>
-
- Fix the MIPS build after r135330
- https://bugs.webkit.org/show_bug.cgi?id=102872
-
- Reviewed by Gavin Barraclough.
-
- Revert/replace functions added to MIPS port.
-
- * assembler/MIPSAssembler.h:
- (JSC::MIPSAssembler::revertJumpToMove):
- (MIPSAssembler):
- (JSC::MIPSAssembler::replaceWithJump):
- * assembler/MacroAssemblerMIPS.h:
- (MacroAssemblerMIPS):
- (JSC::MacroAssemblerMIPS::startOfBranchPtrWithPatchOnRegister):
- (JSC::MacroAssemblerMIPS::revertJumpReplacementToBranchPtrWithPatch):
- (JSC::MacroAssemblerMIPS::startOfPatchableBranchPtrWithPatchOnAddress):
-
-2012-11-21 Filip Pizlo <fpizlo@apple.com>
-
- Rename dataLog() and dataLogV() to dataLogF() and dataLogFV()
- https://bugs.webkit.org/show_bug.cgi?id=103001
-
- Rubber stamped by Dan Bernstein.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
- * assembler/LinkBuffer.cpp:
- (JSC::LinkBuffer::finalizeCodeWithDisassembly):
- (JSC::LinkBuffer::dumpLinkStatistics):
- (JSC::LinkBuffer::dumpCode):
- * assembler/LinkBuffer.h:
- (JSC):
- * assembler/SH4Assembler.h:
- (JSC::SH4Assembler::vprintfStdoutInstr):
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dumpBytecodeCommentAndNewLine):
- (JSC::CodeBlock::printUnaryOp):
- (JSC::CodeBlock::printBinaryOp):
- (JSC::CodeBlock::printConditionalJump):
- (JSC::CodeBlock::printGetByIdOp):
- (JSC::dumpStructure):
- (JSC::dumpChain):
- (JSC::CodeBlock::printGetByIdCacheStatus):
- (JSC::CodeBlock::printCallOp):
- (JSC::CodeBlock::printPutByIdOp):
- (JSC::CodeBlock::printStructure):
- (JSC::CodeBlock::printStructures):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::dumpStatistics):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::resetStubInternal):
- (JSC::CodeBlock::reoptimize):
- (JSC::ProgramCodeBlock::jettison):
- (JSC::EvalCodeBlock::jettison):
- (JSC::FunctionCodeBlock::jettison):
- (JSC::CodeBlock::shouldOptimizeNow):
- (JSC::CodeBlock::tallyFrequentExitSites):
- (JSC::CodeBlock::dumpValueProfiles):
- * bytecode/Opcode.cpp:
- (JSC::OpcodeStats::~OpcodeStats):
- * bytecode/SamplingTool.cpp:
- (JSC::SamplingFlags::stop):
- (JSC::SamplingRegion::dumpInternal):
- (JSC::SamplingTool::dump):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::initialize):
- (JSC::DFG::AbstractState::endBasicBlock):
- (JSC::DFG::AbstractState::mergeStateAtTail):
- (JSC::DFG::AbstractState::mergeToSuccessors):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::dump):
- * dfg/DFGArgumentsSimplificationPhase.cpp:
- (JSC::DFG::ArgumentsSimplificationPhase::run):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
- (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
- (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
- (JSC::DFG::ByteCodeParser::makeSafe):
- (JSC::DFG::ByteCodeParser::makeDivSafe):
- (JSC::DFG::ByteCodeParser::handleCall):
- (JSC::DFG::ByteCodeParser::handleInlining):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::processPhiStack):
- (JSC::DFG::ByteCodeParser::linkBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- (JSC::DFG::ByteCodeParser::parseCodeBlock):
- (JSC::DFG::ByteCodeParser::parse):
- * dfg/DFGCFAPhase.cpp:
- (JSC::DFG::CFAPhase::performBlockCFA):
- (JSC::DFG::CFAPhase::performForwardCFA):
- * dfg/DFGCFGSimplificationPhase.cpp:
- (JSC::DFG::CFGSimplificationPhase::run):
- (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal):
- (JSC::DFG::CFGSimplificationPhase::fixPhis):
- (JSC::DFG::CFGSimplificationPhase::fixJettisonedPredecessors):
- (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference):
- (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::endIndexForPureCSE):
- (JSC::DFG::CSEPhase::setReplacement):
- (JSC::DFG::CSEPhase::eliminate):
- (JSC::DFG::CSEPhase::performNodeCSE):
- * dfg/DFGCapabilities.cpp:
- (JSC::DFG::debugFail):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
- * dfg/DFGDisassembler.cpp:
- (JSC::DFG::Disassembler::dump):
- * dfg/DFGDriver.cpp:
- (JSC::DFG::compile):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- (JSC::DFG::FixupPhase::fixDoubleEdge):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::printWhiteSpace):
- (JSC::DFG::Graph::dumpCodeOrigin):
- (JSC::DFG::Graph::dump):
- (JSC::DFG::Graph::dumpBlockHeader):
- (JSC::DFG::Graph::predictArgumentTypes):
- * dfg/DFGJITCompiler.cpp:
- (JSC::DFG::JITCompiler::link):
- * dfg/DFGOSREntry.cpp:
- (JSC::DFG::prepareOSREntry):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOperations.cpp:
- * dfg/DFGPhase.cpp:
- (JSC::DFG::Phase::beginPhase):
- * dfg/DFGPhase.h:
- (JSC::DFG::runAndLog):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- (JSC::DFG::PredictionPropagationPhase::propagateForward):
- (JSC::DFG::PredictionPropagationPhase::propagateBackward):
- (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
- * dfg/DFGRegisterBank.h:
- (JSC::DFG::RegisterBank::dump):
- * dfg/DFGScoreBoard.h:
- (JSC::DFG::ScoreBoard::use):
- (JSC::DFG::ScoreBoard::dump):
- * dfg/DFGSlowPathGenerator.h:
- (JSC::DFG::SlowPathGenerator::generate):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
- (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection):
- (JSC::DFG::SpeculativeJIT::runSlowPathGenerators):
- (JSC::DFG::SpeculativeJIT::dump):
- (JSC::DFG::SpeculativeJIT::checkConsistency):
- (JSC::DFG::SpeculativeJIT::compile):
- (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
- (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
- (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
- (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
- (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
- (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
- (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- * dfg/DFGValidate.cpp:
- (Validate):
- (JSC::DFG::Validate::reportValidationContext):
- (JSC::DFG::Validate::dumpData):
- (JSC::DFG::Validate::dumpGraphIfAppropriate):
- * dfg/DFGVariableEventStream.cpp:
- (JSC::DFG::VariableEventStream::logEvent):
- (JSC::DFG::VariableEventStream::reconstruct):
- * dfg/DFGVirtualRegisterAllocationPhase.cpp:
- (JSC::DFG::VirtualRegisterAllocationPhase::run):
- * heap/Heap.cpp:
- * heap/HeapStatistics.cpp:
- (JSC::HeapStatistics::logStatistics):
- (JSC::HeapStatistics::showObjectStatistics):
- * heap/MarkStack.h:
- * heap/MarkedBlock.h:
- * heap/SlotVisitor.cpp:
- (JSC::SlotVisitor::validate):
- * interpreter/CallFrame.cpp:
- (JSC::CallFrame::dumpCaller):
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::dumpRegisters):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- (JSC::JIT::privateCompile):
- * jit/JITDisassembler.cpp:
- (JSC::JITDisassembler::dump):
- (JSC::JITDisassembler::dumpForInstructions):
- * jit/JITStubRoutine.h:
- (JSC):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- * jit/JumpReplacementWatchpoint.cpp:
- (JSC::JumpReplacementWatchpoint::fireInternal):
- * llint/LLIntExceptions.cpp:
- (JSC::LLInt::interpreterThrowInCaller):
- (JSC::LLInt::returnToThrow):
- (JSC::LLInt::callToThrow):
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::llint_trace_operand):
- (JSC::LLInt::llint_trace_value):
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- (JSC::LLInt::traceFunctionPrologue):
- (JSC::LLInt::jitCompileAndSetHeuristics):
- (JSC::LLInt::entryOSR):
- (JSC::LLInt::handleHostCall):
- (JSC::LLInt::setUpCall):
- * profiler/Profile.cpp:
- (JSC::Profile::debugPrintData):
- (JSC::Profile::debugPrintDataSampleStyle):
- * profiler/ProfileNode.cpp:
- (JSC::ProfileNode::debugPrintData):
- (JSC::ProfileNode::debugPrintDataSampleStyle):
- * runtime/JSGlobalData.cpp:
- (JSC::JSGlobalData::dumpRegExpTrace):
- * runtime/RegExp.cpp:
- (JSC::RegExp::matchCompareWithInterpreter):
- * runtime/SamplingCounter.cpp:
- (JSC::AbstractSamplingCounter::dump):
- * runtime/Structure.cpp:
- (JSC::Structure::dumpStatistics):
- (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger):
- * tools/CodeProfile.cpp:
- (JSC::CodeProfile::report):
- * tools/ProfileTreeNode.h:
- (JSC::ProfileTreeNode::dumpInternal):
- * yarr/YarrInterpreter.cpp:
- (JSC::Yarr::ByteCompiler::dumpDisjunction):
-
-2012-11-21 Filip Pizlo <fpizlo@apple.com>
-
- It should be possible to say disassemble(stuff) instead of having to say if (!tryToDisassemble(stuff)) dataLog("I failed")
- https://bugs.webkit.org/show_bug.cgi?id=103010
-
- Reviewed by Anders Carlsson.
-
- You can still say tryToDisassemble(), which will tell you if it failed; you can then
- decide what to do instead. But it's better to say disassemble(), which will just print
- the instruction ranges if tryToDisassemble() failed. This is particularly appropriate
- since that's what all previous users of tryToDisassemble() would have done in some
- form or another.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * assembler/LinkBuffer.cpp:
- (JSC::LinkBuffer::finalizeCodeWithDisassembly):
- * dfg/DFGDisassembler.cpp:
- (JSC::DFG::Disassembler::dumpDisassembly):
- * disassembler/Disassembler.cpp: Added.
- (JSC):
- (JSC::disassemble):
- * disassembler/Disassembler.h:
- (JSC):
- * jit/JITDisassembler.cpp:
- (JSC::JITDisassembler::dumpDisassembly):
-
-2012-11-21 Filip Pizlo <fpizlo@apple.com>
-
- dumpOperands() claims that it needs a non-const Operands& when that is completely false
- https://bugs.webkit.org/show_bug.cgi?id=103005
-
- Reviewed by Eric Carlson.
-
- * bytecode/Operands.h:
- (JSC::dumpOperands):
- (JSC):
-
-2012-11-20 Filip Pizlo <fpizlo@apple.com>
-
- Baseline JIT's disassembly should be just as pretty as the DFG's
- https://bugs.webkit.org/show_bug.cgi?id=102873
-
- Reviewed by Sam Weinig.
-
- Integrated the CodeBlock's bytecode dumper with the JIT's disassembler. Also fixed
- some type goof-ups (instructions are not in a Vector<Instruction> so using a Vector
- iterator makes no sense) and stream-lined some things (you don't actually need a
- full-fledged ExecState* to dump bytecode).
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::printUnaryOp):
- (JSC::CodeBlock::printBinaryOp):
- (JSC::CodeBlock::printConditionalJump):
- (JSC::CodeBlock::printGetByIdOp):
- (JSC::CodeBlock::printCallOp):
- (JSC::CodeBlock::printPutByIdOp):
- (JSC::CodeBlock::dump):
- (JSC):
- (JSC::CodeBlock::CodeBlock):
- * bytecode/CodeBlock.h:
- (CodeBlock):
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::dumpCallFrame):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- (JSC::JIT::privateCompile):
- * jit/JIT.h:
- (JIT):
- * jit/JITDisassembler.cpp: Added.
- (JSC):
- (JSC::JITDisassembler::JITDisassembler):
- (JSC::JITDisassembler::~JITDisassembler):
- (JSC::JITDisassembler::dump):
- (JSC::JITDisassembler::dumpForInstructions):
- (JSC::JITDisassembler::dumpDisassembly):
- * jit/JITDisassembler.h: Added.
- (JSC):
- (JITDisassembler):
- (JSC::JITDisassembler::setStartOfCode):
- (JSC::JITDisassembler::setForBytecodeMainPath):
- (JSC::JITDisassembler::setForBytecodeSlowPath):
- (JSC::JITDisassembler::setEndOfSlowPath):
- (JSC::JITDisassembler::setEndOfCode):
-
-2012-11-21 Daniel Bates <dbates@webkit.org>
-
- JavaScript fails to concatenate large strings
- <https://bugs.webkit.org/show_bug.cgi?id=102963>
-
- Reviewed by Michael Saboff.
-
- Fixes an issue where we inadvertently didn't check the length of
- a JavaScript string for overflow.
-
- * runtime/Operations.h:
- (JSC::jsString):
- (JSC::jsStringFromArguments):
-
-2012-11-20 Filip Pizlo <fpizlo@apple.com>
-
- DFG should be able to cache closure calls (part 2/2)
- https://bugs.webkit.org/show_bug.cgi?id=102662
-
- Reviewed by Gavin Barraclough.
-
- Added caching of calls where the JSFunction* varies, but the Structure* and ExecutableBase*
- stay the same. This is accomplished by replacing the branch that compares against a constant
- JSFunction* with a jump to a closure call stub. The closure call stub contains a fast path,
- and jumps slow directly to the virtual call thunk.
-
- Looks like a 1% win on V8v7.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * bytecode/CallLinkInfo.cpp:
- (JSC::CallLinkInfo::unlink):
- * bytecode/CallLinkInfo.h:
- (CallLinkInfo):
- (JSC::CallLinkInfo::isLinked):
- (JSC::getCallLinkInfoBytecodeIndex):
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC):
- (JSC::CodeBlock::findClosureCallForReturnPC):
- (JSC::CodeBlock::bytecodeOffset):
- (JSC::CodeBlock::codeOriginForReturn):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::getCallLinkInfo):
- (CodeBlock):
- (JSC::CodeBlock::isIncomingCallAlreadyLinked):
- * dfg/DFGJITCompiler.cpp:
- (JSC::DFG::JITCompiler::link):
- * dfg/DFGJITCompiler.h:
- (JSC::DFG::JITCompiler::addJSCall):
- (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
- (JSCallRecord):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::linkSlowFor):
- (DFG):
- (JSC::DFG::dfgLinkFor):
- (JSC::DFG::dfgLinkSlowFor):
- (JSC::DFG::dfgLinkClosureCall):
- * dfg/DFGRepatch.h:
- (DFG):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::emitCall):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::emitCall):
- * dfg/DFGThunks.cpp:
- (DFG):
- (JSC::DFG::linkClosureCallThunkGenerator):
- * dfg/DFGThunks.h:
- (DFG):
- * heap/Heap.h:
- (Heap):
- (JSC::Heap::jitStubRoutines):
- * heap/JITStubRoutineSet.h:
- (JSC::JITStubRoutineSet::size):
- (JSC::JITStubRoutineSet::at):
- (JITStubRoutineSet):
- * jit/ClosureCallStubRoutine.cpp: Added.
- (JSC):
- (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
- (JSC::ClosureCallStubRoutine::~ClosureCallStubRoutine):
- (JSC::ClosureCallStubRoutine::markRequiredObjectsInternal):
- * jit/ClosureCallStubRoutine.h: Added.
- (JSC):
- (ClosureCallStubRoutine):
- (JSC::ClosureCallStubRoutine::structure):
- (JSC::ClosureCallStubRoutine::executable):
- (JSC::ClosureCallStubRoutine::codeOrigin):
- * jit/GCAwareJITStubRoutine.cpp:
- (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine):
- * jit/GCAwareJITStubRoutine.h:
- (GCAwareJITStubRoutine):
- (JSC::GCAwareJITStubRoutine::isClosureCall):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompile):
-
-2012-11-20 Filip Pizlo <fpizlo@apple.com>
-
- DFG should be able to cache closure calls (part 1/2)
- https://bugs.webkit.org/show_bug.cgi?id=102662
-
- Reviewed by Gavin Barraclough.
-
- Add ability to revert a jump replacement back to
- branchPtrWithPatch(Condition, RegisterID, TrustedImmPtr). This is meant to be
- a mandatory piece of functionality for all assemblers. I also renamed some of
- the functions for reverting jump replacements back to
- patchableBranchPtrWithPatch(Condition, Address, TrustedImmPtr), so as to avoid
- confusion.
-
- * assembler/ARMv7Assembler.h:
- (JSC::ARMv7Assembler::BadReg):
- (ARMv7Assembler):
- (JSC::ARMv7Assembler::revertJumpTo_movT3):
- * assembler/LinkBuffer.h:
- (JSC):
- * assembler/MacroAssemblerARMv7.h:
- (JSC::MacroAssemblerARMv7::startOfBranchPtrWithPatchOnRegister):
- (MacroAssemblerARMv7):
- (JSC::MacroAssemblerARMv7::revertJumpReplacementToBranchPtrWithPatch):
- (JSC::MacroAssemblerARMv7::startOfPatchableBranchPtrWithPatchOnAddress):
- * assembler/MacroAssemblerX86.h:
- (JSC::MacroAssemblerX86::startOfBranchPtrWithPatchOnRegister):
- (MacroAssemblerX86):
- (JSC::MacroAssemblerX86::startOfPatchableBranchPtrWithPatchOnAddress):
- (JSC::MacroAssemblerX86::revertJumpReplacementToBranchPtrWithPatch):
- * assembler/MacroAssemblerX86_64.h:
- (JSC::MacroAssemblerX86_64::startOfBranchPtrWithPatchOnRegister):
- (JSC::MacroAssemblerX86_64::startOfPatchableBranchPtrWithPatchOnAddress):
- (MacroAssemblerX86_64):
- (JSC::MacroAssemblerX86_64::revertJumpReplacementToBranchPtrWithPatch):
- * assembler/RepatchBuffer.h:
- (JSC::RepatchBuffer::startOfBranchPtrWithPatchOnRegister):
- (RepatchBuffer):
- (JSC::RepatchBuffer::startOfPatchableBranchPtrWithPatchOnAddress):
- (JSC::RepatchBuffer::revertJumpReplacementToBranchPtrWithPatch):
- * assembler/X86Assembler.h:
- (JSC::X86Assembler::revertJumpTo_cmpl_ir_force32):
- (X86Assembler):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::replaceWithJump):
- (JSC::DFG::dfgResetGetByID):
- (JSC::DFG::dfgResetPutByID):
-
-2012-11-20 Yong Li <yoli@rim.com>
-
- [ARMv7] Neither linkCall() nor linkPointer() should flush code.
- https://bugs.webkit.org/show_bug.cgi?id=99213
-
- Reviewed by George Staikos.
-
- LinkBuffer doesn't need to flush code during linking. It will
- eventually flush the whole executable. Fixing this gives >%5
- sunspider boost (on QNX).
-
- Also make replaceWithLoad() and replaceWithAddressComputation() flush
- only when necessary.
-
- * assembler/ARMv7Assembler.h:
- (JSC::ARMv7Assembler::linkCall):
- (JSC::ARMv7Assembler::linkPointer):
- (JSC::ARMv7Assembler::relinkCall):
- (JSC::ARMv7Assembler::repatchInt32):
- (JSC::ARMv7Assembler::repatchPointer):
- (JSC::ARMv7Assembler::replaceWithLoad): Flush only after it did write.
- (JSC::ARMv7Assembler::replaceWithAddressComputation): Flush only after it did write.
- (JSC::ARMv7Assembler::setInt32):
- (JSC::ARMv7Assembler::setPointer):
-
-2012-11-19 Filip Pizlo <fpizlo@apple.com>
-
- Remove support for ARMv7 errata from the jump code
- https://bugs.webkit.org/show_bug.cgi?id=102759
-
- Reviewed by Oliver Hunt.
-
- The jump replacement code was wrong to begin with since it wasn't doing
- a cache flush on the inserted padding. And, to my knowledge, we don't need
- this anymore, so this patch removes all errata code from the ARMv7 port.
-
- * assembler/ARMv7Assembler.h:
- (JSC::ARMv7Assembler::computeJumpType):
- (JSC::ARMv7Assembler::replaceWithJump):
- (JSC::ARMv7Assembler::maxJumpReplacementSize):
- (JSC::ARMv7Assembler::canBeJumpT3):
- (JSC::ARMv7Assembler::canBeJumpT4):
-
-2012-11-19 Patrick Gansterer <paroga@webkit.org>
-
- [CMake] Create JavaScriptCore ForwardingHeaders
- https://bugs.webkit.org/show_bug.cgi?id=92665
-
- Reviewed by Brent Fulgham.
-
- When using CMake to build the Windows port, we need
- to generate the forwarding headers with it too.
-
- * CMakeLists.txt:
-
-2012-11-19 Kihong Kwon <kihong.kwon@samsung.com>
-
- Add PROXIMITY_EVENTS feature
- https://bugs.webkit.org/show_bug.cgi?id=102658
-
- Reviewed by Kentaro Hara.
-
- Add PROXIMITY_EVENTS feature to xcode project for JavaScriptCore.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-11-18 Dan Bernstein <mitz@apple.com>
-
- Try to fix the DFG build after r135099.
-
- * dfg/DFGCommon.h:
- (JSC::DFG::shouldShowDisassembly):
-
-2012-11-18 Filip Pizlo <fpizlo@apple.com>
-
- Unreviewed, build fix for !ENABLE(DFG_JIT).
-
- * dfg/DFGCommon.h:
- (JSC::DFG::shouldShowDisassembly):
- (DFG):
-
-2012-11-18 Filip Pizlo <fpizlo@apple.com>
-
- JSC should have more logging in structure-related code
- https://bugs.webkit.org/show_bug.cgi?id=102630
-
- Reviewed by Simon Fraser.
-
- - JSValue::description() now tells you if something is a structure, and if so,
- what kind of structure it is.
-
- - Jettisoning logic now tells you why things are being jettisoned.
-
- - It's now possible to turn off GC-triggered jettisoning entirely.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::reoptimize):
- (JSC::ProgramCodeBlock::jettison):
- (JSC::EvalCodeBlock::jettison):
- (JSC::FunctionCodeBlock::jettison):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
- * runtime/JSValue.cpp:
- (JSC::JSValue::description):
- * runtime/Options.h:
- (JSC):
-
-2012-11-18 Filip Pizlo <fpizlo@apple.com>
-
- DFG constant folding phase should say 'changed = true' whenever it changes the graph
- https://bugs.webkit.org/show_bug.cgi?id=102550
-
- Rubber stamped by Mark Hahnenberg.
-
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
-
-2012-11-17 Elliott Sprehn <esprehn@chromium.org>
-
- Expose JSObject removeDirect and PrivateName to WebCore
- https://bugs.webkit.org/show_bug.cgi?id=102546
-
- Reviewed by Geoffrey Garen.
-
- Export removeDirect for use in WebCore so JSDependentRetained works.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-11-16 Filip Pizlo <fpizlo@apple.com>
-
- Given a PutById or GetById with a proven structure, the DFG should be able to emit a PutByOffset or GetByOffset instead
- https://bugs.webkit.org/show_bug.cgi?id=102327
-
- Reviewed by Mark Hahnenberg.
-
- If the profiler tells us that a GetById or PutById may be polymorphic but our
- control flow analysis proves that it isn't, we should trust the control flow
- analysis over the profiler. This arises in cases where GetById or PutById were
- inlined: the inlined function may have been called from other places that led
- to polymorphism, but in the current inlined context, there is no polymorphism.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- * bytecode/GetByIdStatus.cpp:
- (JSC::GetByIdStatus::computeFor):
- (JSC):
- * bytecode/GetByIdStatus.h:
- (JSC::GetByIdStatus::GetByIdStatus):
- (GetByIdStatus):
- * bytecode/PutByIdStatus.cpp:
- (JSC::PutByIdStatus::computeFor):
- (JSC):
- * bytecode/PutByIdStatus.h:
- (JSC):
- (JSC::PutByIdStatus::PutByIdStatus):
- (PutByIdStatus):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::bestProvenStructure):
- (AbstractValue):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
- (ConstantFoldingPhase):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::convertToGetByOffset):
- (Node):
- (JSC::DFG::Node::convertToPutByOffset):
- (JSC::DFG::Node::hasStorageResult):
- * runtime/JSGlobalObject.h:
- (JSC::Structure::prototypeChain):
- (JSC):
- (JSC::Structure::isValid):
- * runtime/Operations.h:
- (JSC::isPrototypeChainNormalized):
- (JSC):
- * runtime/Structure.h:
- (Structure):
- (JSC::Structure::transitionDidInvolveSpecificValue):
-
-2012-11-16 Tony Chang <tony@chromium.org>
-
- Remove ENABLE_CSS_HIERARCHIES since it's no longer in use
- https://bugs.webkit.org/show_bug.cgi?id=102554
-
- Reviewed by Andreas Kling.
-
- As mentioned in https://bugs.webkit.org/show_bug.cgi?id=79939#c41 ,
- we're going to revist this feature once additional vendor support is
- achieved.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-11-16 Patrick Gansterer <paroga@webkit.org>
-
- Build fix for WinCE after r133688.
-
- Use numeric_limits<uint32_t>::max() instead of UINT32_MAX.
-
- * runtime/CodeCache.h:
- (JSC::CacheMap::CacheMap):
-
-2012-11-15 Filip Pizlo <fpizlo@apple.com>
-
- ClassInfo.h should have correct indentation.
-
- Rubber stamped by Mark Hahnenberg.
-
- ClassInfo.h had some true creativity in its use of whitespace. Some things within
- the namespace were indented four spaces and others where not. One #define had its
- contents indented four spaces, while another didn't. I applied the following rule:
-
- - Non-macro things in the namespace should not be indented (that's our current
- accepted practice).
-
- - Macros should never be indented but if they are multi-line then their subsequent
- bodies should be indented four spaces. I believe that is consistent with what we
- do elsewhere.
-
- * runtime/ClassInfo.h:
- (JSC):
- (MethodTable):
- (ClassInfo):
- (JSC::ClassInfo::propHashTable):
- (JSC::ClassInfo::isSubClassOf):
- (JSC::ClassInfo::hasStaticProperties):
-
-2012-11-15 Filip Pizlo <fpizlo@apple.com>
-
- DFG should copy propagate trivially no-op ConvertThis
- https://bugs.webkit.org/show_bug.cgi?id=102445
-
- Reviewed by Oliver Hunt.
-
- Copy propagation is always a good thing, since it reveals must-alias relationships
- to the CFA and CSE. This accomplishes copy propagation for ConvertThis by first
- converting it to an Identity node (which is done by the constant folder since it
- has access to CFA results) and then performing substitution of references to
- Identity with references to Identity's child in the CSE.
-
- I'm not aiming for a big speed-up here; I just think that this will be useful for
- the work on https://bugs.webkit.org/show_bug.cgi?id=102327.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::performNodeCSE):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-11-15 Filip Pizlo <fpizlo@apple.com>
-
- CallData.h should have correct indentation.
-
- Rubber stamped by Mark Hahneberg.
-
- * runtime/CallData.h:
- (JSC):
-
-2012-11-15 Filip Pizlo <fpizlo@apple.com>
-
- Remove methodCallDummy since it is not used anymore.
-
- Rubber stamped by Mark Hahnenberg.
-
- * runtime/JSGlobalObject.cpp:
- (JSC::JSGlobalObject::reset):
- (JSC):
- (JSC::JSGlobalObject::visitChildren):
- * runtime/JSGlobalObject.h:
- (JSGlobalObject):
-
-2012-11-14 Filip Pizlo <fpizlo@apple.com>
-
- Structure should be able to easily tell if the prototype chain might intercept a store
- https://bugs.webkit.org/show_bug.cgi?id=102326
-
- Reviewed by Geoffrey Garen.
-
- This improves our ability to reason about the correctness of the more optimized
- prototype chain walk in JSObject::put(), while also making it straight forward to
- check if the prototype chain will do strange things to a property store by just
- looking at the structure.
-
- * runtime/JSObject.cpp:
- (JSC::JSObject::put):
- * runtime/Structure.cpp:
- (JSC::Structure::prototypeChainMayInterceptStoreTo):
- (JSC):
- * runtime/Structure.h:
- (Structure):
-
-2012-11-15 Thiago Marcos P. Santos <thiago.santos@intel.com>
-
- [CMake] Do not regenerate LLIntAssembly.h on every incremental build
- https://bugs.webkit.org/show_bug.cgi?id=102248
-
- Reviewed by Kenneth Rohde Christiansen.
-
- Update LLIntAssembly.h's mtime after running asm.rb to make the build
- system dependency tracking consistent.
-
- * CMakeLists.txt:
-
-2012-11-15 Thiago Marcos P. Santos <thiago.santos@intel.com>
-
- Fix compiler warnings about signed/unsigned comparison on i386
- https://bugs.webkit.org/show_bug.cgi?id=102249
-
- Reviewed by Kenneth Rohde Christiansen.
-
- Add casting to unsigned to shut up gcc warnings. Build was broken on
- JSVALUE32_64 ports compiling with -Werror.
-
- * llint/LLIntData.cpp:
- (JSC::LLInt::Data::performAssertions):
-
-2012-11-14 Brent Fulgham <bfulgham@webkit.org>
-
- [Windows, WinCairo] Unreviewed build fix.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
- Missed one of the exports that was part of the WebKit2.def.
-
-2012-11-14 Brent Fulgham <bfulgham@webkit.org>
-
- [Windows, WinCairo] Correct build failure.
- https://bugs.webkit.org/show_bug.cgi?id=102302
-
- WebCore symbols were mistakenly added to the JavaScriptCore
- library definition file.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Remove
- WebCore symbols that were incorrectly added to the export file.
-
-2012-11-14 Mark Lam <mark.lam@apple.com>
-
- Change JSEventListener::m_jsFunction to be a weak ref.
- https://bugs.webkit.org/show_bug.cgi?id=101989.
-
- Reviewed by Geoffrey Garen.
-
- Added infrastructure for scanning weak ref slots.
-
- * heap/SlotVisitor.cpp: Added #include "SlotVisitorInlines.h".
- * heap/SlotVisitor.h:
- (SlotVisitor): Added SlotVisitor::appendUnbarrieredWeak().
- * heap/SlotVisitorInlines.h: Added #include "Weak.h".
- (JSC::SlotVisitor::appendUnbarrieredWeak): Added.
- * heap/Weak.h:
- (JSC::operator==): Added operator==() for Weak.
- * runtime/JSCell.h: Removed #include "SlotVisitorInlines.h".
- * runtime/JSObject.h: Added #include "SlotVisitorInlines.h".
-
-2012-11-14 Filip Pizlo <fpizlo@apple.com>
-
- Read-only properties created with putDirect() should tell the structure that there are read-only properties
- https://bugs.webkit.org/show_bug.cgi?id=102292
-
- Reviewed by Gavin Barraclough.
-
- This mostly affects things like function.length.
-
- * runtime/JSObject.h:
- (JSC::JSObject::putDirectInternal):
-
-2012-11-13 Filip Pizlo <fpizlo@apple.com>
-
- Don't access Node& after adding nodes to the graph.
- https://bugs.webkit.org/show_bug.cgi?id=102005
-
- Reviewed by Oliver Hunt.
-
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
-
-2012-11-14 Valery Ignatyev <valery.ignatyev@ispras.ru>
-
- Replace (typeof(x) != <"object", "undefined", ...>) with
- !(typeof(x) == <"object",..>). Later is_object, is_<...> bytecode operation
- will be used.
-
- https://bugs.webkit.org/show_bug.cgi?id=98893
-
- Reviewed by Filip Pizlo.
-
- This eliminates expensive typeof implementation and
- allows to use DFG optimizations, which doesn't support 'typeof'.
-
- * bytecompiler/NodesCodegen.cpp:
- (JSC::BinaryOpNode::emitBytecode):
-
-2012-11-14 Peter Gal <galpeter@inf.u-szeged.hu>
-
- [Qt][ARM]REGRESSION(r133985): It broke the build
- https://bugs.webkit.org/show_bug.cgi?id=101740
-
- Reviewed by Csaba Osztrogonác.
-
- Changed the emitGenericContiguousPutByVal to accept the additional IndexingType argument.
- This information was passed as a template parameter.
-
- * jit/JIT.h:
- (JSC::JIT::emitInt32PutByVal):
- (JSC::JIT::emitDoublePutByVal):
- (JSC::JIT::emitContiguousPutByVal):
- (JIT):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emitGenericContiguousPutByVal):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emitGenericContiguousPutByVal):
-
-2012-11-14 Peter Gal <galpeter@inf.u-szeged.hu>
-
- Fix the MIPS build after r134332
- https://bugs.webkit.org/show_bug.cgi?id=102227
-
- Reviewed by Csaba Osztrogonác.
-
- Added missing methods for the MacroAssemblerMIPS, based on the MacroAssemblerARMv7.
-
- * assembler/MacroAssemblerMIPS.h:
- (JSC::MacroAssemblerMIPS::canJumpReplacePatchableBranchPtrWithPatch):
- (MacroAssemblerMIPS):
- (JSC::MacroAssemblerMIPS::startOfPatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerMIPS::revertJumpReplacementToPatchableBranchPtrWithPatch):
-
-2012-11-14 Peter Gal <galpeter@inf.u-szeged.hu>
-
- Fix the [-Wreturn-type] warning in JavaScriptCore/assembler/MacroAssemblerARM.h
- https://bugs.webkit.org/show_bug.cgi?id=102206
-
- Reviewed by Csaba Osztrogonác.
-
- Add a return value for the function to suppress the warning.
-
- * assembler/MacroAssemblerARM.h:
- (JSC::MacroAssemblerARM::startOfPatchableBranchPtrWithPatch):
-
-2012-11-14 Sheriff Bot <webkit.review.bot@gmail.com>
-
- Unreviewed, rolling out r134599.
- http://trac.webkit.org/changeset/134599
- https://bugs.webkit.org/show_bug.cgi?id=102225
-
- It broke the 32 bit EFL build (Requested by Ossy on #webkit).
-
- * jit/JITPropertyAccess.cpp:
- * jit/JITPropertyAccess32_64.cpp:
- (JSC):
- (JSC::JIT::emitGenericContiguousPutByVal):
-
-2012-11-14 Balazs Kilvady <kilvadyb@homejinni.com>
-
- [Qt][ARM]REGRESSION(r133985): It broke the build
- https://bugs.webkit.org/show_bug.cgi?id=101740
-
- Reviewed by Csaba Osztrogonác.
-
- Template function body moved to fix VALUE_PROFILER disabled case.
-
- * jit/JITPropertyAccess.cpp:
- (JSC):
- (JSC::JIT::emitGenericContiguousPutByVal):
- * jit/JITPropertyAccess32_64.cpp:
-
-2012-11-13 Filip Pizlo <fpizlo@apple.com>
-
- DFG CreateThis should be able to statically account for the structure of the object it creates, if profiling indicates that this structure is always the same
- https://bugs.webkit.org/show_bug.cgi?id=102017
-
- Reviewed by Geoffrey Garen.
-
- This adds a watchpoint in JSFunction on the cached inheritor ID. It also changes
- NewObject to take a structure as an operand (previously it implicitly used the owning
- global object's empty object structure). Any GetCallee where the callee is predictable
- is turned into a CheckFunction + WeakJSConstant, and any CreateThis on a WeakJSConstant
- where the inheritor ID watchpoint is still valid is turned into an InheritorIDWatchpoint
- followed by a NewObject. NewObject already accounts for the structure it uses for object
- creation in the CFA.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::checkFunctionElimination):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::Graph::dump):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::hasFunction):
- (JSC::DFG::Node::function):
- (JSC::DFG::Node::hasStructure):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * runtime/Executable.h:
- (JSC::JSFunction::JSFunction):
- * runtime/JSBoundFunction.cpp:
- (JSC):
- * runtime/JSFunction.cpp:
- (JSC::JSFunction::JSFunction):
- (JSC::JSFunction::put):
- (JSC::JSFunction::defineOwnProperty):
- * runtime/JSFunction.h:
- (JSC::JSFunction::tryGetKnownInheritorID):
- (JSFunction):
- (JSC::JSFunction::addInheritorIDWatchpoint):
-
-2012-11-13 Filip Pizlo <fpizlo@apple.com>
-
- JSFunction and its descendants should be destructible
- https://bugs.webkit.org/show_bug.cgi?id=102062
-
- Reviewed by Mark Hahnenberg.
-
- This will make it easy to place an InlineWatchpointSet inside JSFunction. In the
- future, we could make JSFunction non-destructible again by making a version of
- WatchpointSet that is entirely GC'd, but this seems like overkill for now.
-
- This is performance-neutral.
-
- * runtime/JSBoundFunction.cpp:
- (JSC::JSBoundFunction::destroy):
- (JSC):
- * runtime/JSBoundFunction.h:
- (JSBoundFunction):
- * runtime/JSFunction.cpp:
- (JSC):
- (JSC::JSFunction::destroy):
- * runtime/JSFunction.h:
- (JSFunction):
-
-2012-11-13 Cosmin Truta <ctruta@rim.com>
-
- Uninitialized fields in class JSLock
- https://bugs.webkit.org/show_bug.cgi?id=101695
-
- Reviewed by Mark Hahnenberg.
-
- Initialize JSLock::m_ownerThread and JSLock::m_lockDropDepth.
-
- * runtime/JSLock.cpp:
- (JSC::JSLock::JSLock):
-
-2012-11-13 Peter Gal <galpeter@inf.u-szeged.hu>
-
- Fix the ARM traditional build after r134332
- https://bugs.webkit.org/show_bug.cgi?id=102044
-
- Reviewed by Zoltan Herczeg.
-
- Added missing methods for the MacroAssemblerARM, based on the MacroAssemblerARMv7.
-
- * assembler/MacroAssemblerARM.h:
- (JSC::MacroAssemblerARM::canJumpReplacePatchableBranchPtrWithPatch):
- (MacroAssemblerARM):
- (JSC::MacroAssemblerARM::startOfPatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerARM::revertJumpReplacementToPatchableBranchPtrWithPatch):
-
-2012-11-12 Filip Pizlo <fpizlo@apple.com>
-
- op_get_callee should have value profiling
- https://bugs.webkit.org/show_bug.cgi?id=102047
-
- Reviewed by Sam Weinig.
-
- This will allow us to detect if the callee is always the same, which is probably
- the common case for a lot of constructors.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::CodeBlock):
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::BytecodeGenerator):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_get_callee):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emit_op_get_callee):
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
-
-2012-11-12 Filip Pizlo <fpizlo@apple.com>
-
- The act of getting the callee during 'this' construction should be explicit in bytecode
- https://bugs.webkit.org/show_bug.cgi?id=102016
-
- Reviewed by Michael Saboff.
-
- This is mostly a rollout of http://trac.webkit.org/changeset/116673, but also includes
- changes to have create_this use the result of get_callee.
-
- No performance or behavioral impact. This is just meant to allow us to profile
- get_callee in the future.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::BytecodeGenerator):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canCompileOpcode):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- * jit/JIT.h:
- (JIT):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_get_callee):
- (JSC):
- (JSC::JIT::emit_op_create_this):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emit_op_get_callee):
- (JSC):
- (JSC::JIT::emit_op_create_this):
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
-
-2012-11-12 Filip Pizlo <fpizlo@apple.com>
-
- Unreviewed, fix ARMv7 build.
-
- * assembler/MacroAssemblerARMv7.h:
- (JSC::MacroAssemblerARMv7::startOfPatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerARMv7::revertJumpReplacementToPatchableBranchPtrWithPatch):
-
-2012-11-12 Filip Pizlo <fpizlo@apple.com>
-
- Patching of jumps to stubs should use jump replacement rather than branch destination overwrite
- https://bugs.webkit.org/show_bug.cgi?id=101909
-
- Reviewed by Geoffrey Garen.
-
- This saves a few instructions in inline cases, on those architectures where it is
- easy to figure out where to put the jump replacement. Sub-1% speed-up across the
- board.
-
- * assembler/MacroAssemblerARMv7.h:
- (MacroAssemblerARMv7):
- (JSC::MacroAssemblerARMv7::canJumpReplacePatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerARMv7::startOfPatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerARMv7::revertJumpReplacementToPatchableBranchPtrWithPatch):
- * assembler/MacroAssemblerX86.h:
- (JSC::MacroAssemblerX86::canJumpReplacePatchableBranchPtrWithPatch):
- (MacroAssemblerX86):
- (JSC::MacroAssemblerX86::startOfPatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerX86::revertJumpReplacementToPatchableBranchPtrWithPatch):
- * assembler/MacroAssemblerX86_64.h:
- (JSC::MacroAssemblerX86_64::canJumpReplacePatchableBranchPtrWithPatch):
- (MacroAssemblerX86_64):
- (JSC::MacroAssemblerX86_64::startOfPatchableBranchPtrWithPatch):
- (JSC::MacroAssemblerX86_64::revertJumpReplacementToPatchableBranchPtrWithPatch):
- * assembler/RepatchBuffer.h:
- (JSC::RepatchBuffer::startOfPatchableBranchPtrWithPatch):
- (RepatchBuffer):
- (JSC::RepatchBuffer::replaceWithJump):
- (JSC::RepatchBuffer::revertJumpReplacementToPatchableBranchPtrWithPatch):
- * assembler/X86Assembler.h:
- (X86Assembler):
- (JSC::X86Assembler::revertJumpTo_movq_i64r):
- (JSC::X86Assembler::revertJumpTo_cmpl_im_force32):
- (X86InstructionFormatter):
- * bytecode/StructureStubInfo.h:
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::replaceWithJump):
- (DFG):
- (JSC::DFG::tryCacheGetByID):
- (JSC::DFG::tryBuildGetByIDList):
- (JSC::DFG::tryBuildGetByIDProtoList):
- (JSC::DFG::tryCachePutByID):
- (JSC::DFG::dfgResetGetByID):
- (JSC::DFG::dfgResetPutByID):
-
-2012-11-11 Filip Pizlo <fpizlo@apple.com>
-
- DFG ArithMul overflow check elimination is too aggressive
- https://bugs.webkit.org/show_bug.cgi?id=101871
-
- Reviewed by Oliver Hunt.
-
- The code was ignoring the fact that ((a * b) | 0) == (((a | 0) * (b | 0)) | 0)
- only holds if a * b < 2^53. So, I changed it to only enable the optimization
- when a < 2^22 and b is an int32 (and vice versa), using a super trivial peephole
- analysis to prove the inequality. I considered writing an epic forward flow
- formulation that tracks the ranges of integer values but then I thought better
- of it.
-
- This also rewires the ArithMul integer speculation logic. Previously, we would
- assume that an ArithMul was only UsedAsNumber if it escaped, and separately we
- would decide whether to speculate integer based on a proof of the <2^22
- inequality. Now, we treat the double rounding behavior of ArithMul as if the
- result was UsedAsNumber even if it did not escape. Then we try to prove that
- double rounding cannot happen by attemping to prove that a < 2^22. This then
- feeds back into the decision of whether or not to speculate integer (if we fail
- to prove a < 2^22 then we're UsedAsNumber, and if we're also MayOverflow then
- that forces double speculation).
-
- No performance impact. It just fixes a bug.
-
- * dfg/DFGGraph.h:
- (JSC::DFG::Graph::mulShouldSpeculateInteger):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (PredictionPropagationPhase):
- (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoForConstant):
- (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoNonRecursive):
- (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwo):
- (JSC::DFG::PredictionPropagationPhase::propagate):
-
-2012-11-11 Filip Pizlo <fpizlo@apple.com>
-
- DFG should not emit function checks if we've already proved that the operand is that exact function
- https://bugs.webkit.org/show_bug.cgi?id=101885
-
- Reviewed by Oliver Hunt.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::filterByValue):
- (AbstractValue):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
-
-2012-11-12 Kentaro Hara <haraken@chromium.org>
-
- [V8][JSC] ScriptProfileNode::callUID needs not to be [Custom]
- https://bugs.webkit.org/show_bug.cgi?id=101892
-
- Reviewed by Adam Barth.
-
- Added callUID(), which enables us to kill custom bindings for ScriptProfileNode::callUID.
-
- * profiler/ProfileNode.h:
- (JSC::ProfileNode::callUID):
-
-2012-11-12 Carlos Garcia Campos <cgarcia@igalia.com>
-
- Unreviewed. Fix make distcheck.
-
- * GNUmakefile.list.am: Add missing header.
-
-2012-11-11 Michael Pruett <michael@68k.org>
-
- Fix assertion failure in JSObject::tryGetIndexQuickly()
- https://bugs.webkit.org/show_bug.cgi?id=101869
-
- Reviewed by Filip Pizlo.
-
- Currently JSObject::tryGetIndexQuickly() triggers an assertion
- failure when the object has an undecided indexing type. This
- case should be treated the same as a blank indexing type.
-
- * runtime/JSObject.h:
- (JSC::JSObject::tryGetIndexQuickly):
-
-2012-11-11 Filip Pizlo <fpizlo@apple.com>
-
- DFG register allocation should be greedy rather than round-robin
- https://bugs.webkit.org/show_bug.cgi?id=101870
-
- Reviewed by Geoffrey Garen.
-
- This simplifies the code, reduces some code duplication, and shows some slight
- performance improvements in a few places, likely due to the fact that lower-numered
- registers also typically have smaller encodings.
-
- * dfg/DFGRegisterBank.h:
- (JSC::DFG::RegisterBank::RegisterBank):
- (JSC::DFG::RegisterBank::tryAllocate):
- (JSC::DFG::RegisterBank::allocate):
- (JSC::DFG::RegisterBank::allocateInternal):
- (RegisterBank):
-
-2012-11-11 Kenichi Ishibashi <bashi@chromium.org>
-
- WTFString::utf8() should have a mode of conversion to use replacement character
- https://bugs.webkit.org/show_bug.cgi?id=101678
-
- Reviewed by Alexey Proskuryakov.
-
- Follow the change on String::utf8()
-
- * runtime/JSGlobalObjectFunctions.cpp:
- (JSC::encode): Pass String::StrictConversion instead of true to String::utf8().
-
-2012-11-10 Filip Pizlo <fpizlo@apple.com>
-
- DFG should optimize out the NaN check on loads from double arrays if the array prototype chain is having a great time
- https://bugs.webkit.org/show_bug.cgi?id=101718
-
- Reviewed by Geoffrey Garen.
-
- If we're reading from a JSArray in double mode, where the array's structure is
- primordial (all aspects of the structure are unchanged except for indexing type),
- and the result of the load is used in arithmetic that is known to not distinguish
- between NaN and undefined, then we should not emit a NaN check. Looks like a 5%
- win on navier-stokes.
-
- Also fixed an OpInfo initialization goof for String ops that was revealed by this
- change.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::arraySpeculationToString):
- * dfg/DFGArrayMode.h:
- (JSC::DFG::ArrayMode::isSaneChain):
- (ArrayMode):
- (JSC::DFG::ArrayMode::isInBounds):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::handleIntrinsic):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- * dfg/DFGNodeFlags.cpp:
- (JSC::DFG::nodeFlagsAsString):
- * dfg/DFGNodeFlags.h:
- (DFG):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * runtime/JSGlobalObject.cpp:
- (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
- (JSC):
- * runtime/JSGlobalObject.h:
- (JSGlobalObject):
-
-2012-11-10 Filip Pizlo <fpizlo@apple.com>
-
- DFG constant folding and CFG simplification should be smart enough to know that if a logical op's operand is proven to have a non-masquerading structure then it always evaluates to true
- https://bugs.webkit.org/show_bug.cgi?id=101511
-
- Reviewed by Geoffrey Garen.
-
- This is the second attempt at this patch, which fixes the !"" case.
-
- To make life easier, this moves BranchDirection into BasicBlock so that after
- running the CFA, we always know, for each block, what direction the CFA
- proved. CFG simplification now both uses and preserves cfaBranchDirection in
- its transformations.
-
- Also made both LogicalNot and Branch check whether the operand is a known cell
- with a known structure, and if so, made them do the appropriate folding.
-
- 5% speed-up on V8/raytrace because it makes raytrace's own null checks
- evaporate (i.e. idioms like 'if (!x) throw "unhappiness"') thanks to the fact
- that we were already doing structure check hoisting.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::endBasicBlock):
- (JSC::DFG::AbstractState::execute):
- (JSC::DFG::AbstractState::mergeToSuccessors):
- * dfg/DFGAbstractState.h:
- (AbstractState):
- * dfg/DFGBasicBlock.h:
- (JSC::DFG::BasicBlock::BasicBlock):
- (BasicBlock):
- * dfg/DFGBranchDirection.h: Added.
- (DFG):
- (JSC::DFG::branchDirectionToString):
- (JSC::DFG::isKnownDirection):
- (JSC::DFG::branchCondition):
- * dfg/DFGCFGSimplificationPhase.cpp:
- (JSC::DFG::CFGSimplificationPhase::run):
- (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
-
-2012-11-10 Sheriff Bot <webkit.review.bot@gmail.com>
-
- Unreviewed, rolling out r133971.
- http://trac.webkit.org/changeset/133971
- https://bugs.webkit.org/show_bug.cgi?id=101839
-
- Causes WebProcess to hang at 100% on www.apple.com (Requested
- by kling on #webkit).
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::endBasicBlock):
- (JSC::DFG::AbstractState::execute):
- (JSC::DFG::AbstractState::mergeToSuccessors):
- * dfg/DFGAbstractState.h:
- (JSC::DFG::AbstractState::branchDirectionToString):
- (AbstractState):
- * dfg/DFGBasicBlock.h:
- (JSC::DFG::BasicBlock::BasicBlock):
- (BasicBlock):
- * dfg/DFGBranchDirection.h: Removed.
- * dfg/DFGCFGSimplificationPhase.cpp:
- (JSC::DFG::CFGSimplificationPhase::run):
- (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
-
-2012-11-09 Filip Pizlo <fpizlo@apple.com>
-
- If the DFG ArrayMode says that an access is on an OriginalArray, then the checks should always enforce this
- https://bugs.webkit.org/show_bug.cgi?id=101720
-
- Reviewed by Mark Hahnenberg.
-
- Previously, "original" arrays was just a hint that we could find the structure
- of the array if we needed to even if the array profile didn't have it due to
- polymorphism. Now, "original" arrays are a property that is actually checked:
- if an array access has ArrayMode::arrayClass() == Array::OriginalArray, then we
- can be sure that the code performing the access is dealing with not just a
- JSArray, but a JSArray that has no named properties, no indexed accessors, and
- the ArrayPrototype as its prototype. This will be useful for optimizations that
- are being done as part of https://bugs.webkit.org/show_bug.cgi?id=101720.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::ArrayMode::originalArrayStructure):
- (DFG):
- (JSC::DFG::ArrayMode::alreadyChecked):
- * dfg/DFGArrayMode.h:
- (JSC):
- (DFG):
- (JSC::DFG::ArrayMode::withProfile):
- (ArrayMode):
- (JSC::DFG::ArrayMode::benefitsFromOriginalArray):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::checkArray):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
- (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
- (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
-
-2012-11-09 Filip Pizlo <fpizlo@apple.com>
-
- Fix indentation of BooleanPrototype.h
-
- Rubber stamped by Mark Hahnenberg.
-
- * runtime/BooleanPrototype.h:
-
-2012-11-09 Filip Pizlo <fpizlo@apple.com>
-
- Fix indentation of BooleanObject.h
-
- Rubber stamped by Mark Hahnenberg.
-
- * runtime/BooleanObject.h:
-
-2012-11-09 Filip Pizlo <fpizlo@apple.com>
-
- Fix indentation of BooleanConstructor.h
-
- Rubber stamped by Mark Hahnenberg.
-
- * runtime/BooleanConstructor.h:
-
-2012-11-09 Filip Pizlo <fpizlo@apple.com>
-
- Fix indentation of BatchedTransitionOptimizer.h
-
- Rubber stamped by Mark Hahnenberg.
-
- * runtime/BatchedTransitionOptimizer.h:
-
-2012-11-09 Oliver Hunt <oliver@apple.com>
-
- So Thingy probably isn't the best name for a class, so
- renamed to CacheMap.
-
- RS=Geoff
-
- * runtime/CodeCache.h:
- (JSC::CacheMap::CacheMap):
-
-2012-11-09 Filip Pizlo <fpizlo@apple.com>
-
- ArrayPrototype should start out with a blank indexing type
- https://bugs.webkit.org/show_bug.cgi?id=101719
-
- Reviewed by Mark Hahnenberg.
-
- This allows us to track if the array prototype ever ends up with indexed
- properties.
-
- * runtime/ArrayPrototype.cpp:
- (JSC::ArrayPrototype::create):
- (JSC::ArrayPrototype::ArrayPrototype):
- * runtime/ArrayPrototype.h:
- (ArrayPrototype):
- (JSC::ArrayPrototype::createStructure):
-
-2012-11-08 Mark Hahnenberg <mhahnenberg@apple.com>
-
- MarkStackArray should use the BlockAllocator instead of the MarkStackSegmentAllocator
- https://bugs.webkit.org/show_bug.cgi?id=101642
-
- Reviewed by Filip Pizlo.
-
- MarkStackSegmentAllocator is like a miniature version of the BlockAllocator. Now that the BlockAllocator has support
- for a variety of block sizes, we should get rid of the MarkStackSegmentAllocator in favor of the BlockAllocator.
-
- * heap/BlockAllocator.h: Add new specializations of regionSetFor for the new MarkStackSegments.
- (JSC):
- (JSC::MarkStackSegment):
- * heap/GCThreadSharedData.cpp:
- (JSC::GCThreadSharedData::GCThreadSharedData):
- (JSC::GCThreadSharedData::reset):
- * heap/GCThreadSharedData.h:
- (GCThreadSharedData):
- * heap/MarkStack.cpp:
- (JSC::MarkStackArray::MarkStackArray): We now have a doubly linked list of MarkStackSegments, so we need to refactor
- all the places that used the old custom tail/previous logic.
- (JSC::MarkStackArray::~MarkStackArray):
- (JSC::MarkStackArray::expand):
- (JSC::MarkStackArray::refill):
- (JSC::MarkStackArray::donateSomeCellsTo): Refactor to use the new linked list.
- (JSC::MarkStackArray::stealSomeCellsFrom): Ditto.
- * heap/MarkStack.h:
- (JSC):
- (MarkStackSegment):
- (JSC::MarkStackSegment::MarkStackSegment):
- (JSC::MarkStackSegment::sizeFromCapacity):
- (MarkStackArray):
- * heap/MarkStackInlines.h:
- (JSC::MarkStackSegment::create):
- (JSC):
- (JSC::MarkStackArray::postIncTop):
- (JSC::MarkStackArray::preDecTop):
- (JSC::MarkStackArray::setTopForFullSegment):
- (JSC::MarkStackArray::setTopForEmptySegment):
- (JSC::MarkStackArray::top):
- (JSC::MarkStackArray::validatePrevious):
- (JSC::MarkStackArray::append):
- (JSC::MarkStackArray::removeLast):
- (JSC::MarkStackArray::isEmpty):
- (JSC::MarkStackArray::size):
- * heap/SlotVisitor.cpp:
- (JSC::SlotVisitor::SlotVisitor):
-
-2012-11-09 Gabor Ballabas <gaborb@inf.u-szeged.hu>
-
- [Qt] r133953 broke the ARM_TRADITIONAL build
- https://bugs.webkit.org/show_bug.cgi?id=101706
-
- Reviewed by Csaba Osztrogonác.
-
- Fix for both hardfp and softfp.
-
- * dfg/DFGCCallHelpers.h:
- (CCallHelpers):
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
-
-2012-11-09 Sheriff Bot <webkit.review.bot@gmail.com>
-
- Unreviewed, rolling out r134051.
- http://trac.webkit.org/changeset/134051
- https://bugs.webkit.org/show_bug.cgi?id=101757
-
- It didn't fix the build (Requested by Ossy on #webkit).
-
- * dfg/DFGCCallHelpers.h:
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
-
-2012-11-09 Gabor Ballabas <gaborb@inf.u-szeged.hu>
-
- [Qt] r133953 broke the ARM_TRADITIONAL build
- https://bugs.webkit.org/show_bug.cgi?id=101706
-
- Reviewed by Csaba Osztrogonác.
-
- Fix the ARM_TRADITIONAL build after r133953
-
- * dfg/DFGCCallHelpers.h:
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
- (CCallHelpers):
-
-2012-11-09 Csaba Osztrogonác <ossy@webkit.org>
-
- [Qt] Fix the LLINT build from ARMv7 platform
- https://bugs.webkit.org/show_bug.cgi?id=101712
-
- Reviewed by Simon Hausmann.
-
- Enable generating of LLIntAssembly.h on ARM platforms.
-
- * DerivedSources.pri:
- * JavaScriptCore.pro:
-
-2012-11-08 Filip Pizlo <fpizlo@apple.com>
-
- ArrayPrototype.h should have correct indentation
-
- Rubber stamped by Sam Weinig.
-
- * runtime/ArrayPrototype.h:
-
-2012-11-08 Mark Lam <mark.lam@apple.com>
-
- Renamed ...InlineMethods.h files to ...Inlines.h.
- https://bugs.webkit.org/show_bug.cgi?id=101145.
-
- Reviewed by Geoffrey Garen.
-
- This is only a refactoring effort to rename the files. There are no
- functionality changes.
-
- * API/JSObjectRef.cpp:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * bytecode/CodeBlock.cpp:
- * dfg/DFGOperations.cpp:
- * heap/ConservativeRoots.cpp:
- * heap/CopiedBlock.h:
- * heap/CopiedSpace.cpp:
- * heap/CopiedSpaceInlineMethods.h: Removed.
- * heap/CopiedSpaceInlines.h: Copied from Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h.
- * heap/CopyVisitor.cpp:
- * heap/CopyVisitorInlineMethods.h: Removed.
- * heap/CopyVisitorInlines.h: Copied from Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h.
- * heap/GCThread.cpp:
- * heap/GCThreadSharedData.cpp:
- * heap/HandleStack.cpp:
- * heap/Heap.cpp:
- * heap/HeapRootVisitor.h:
- * heap/MarkStack.cpp:
- * heap/MarkStackInlineMethods.h: Removed.
- * heap/MarkStackInlines.h: Copied from Source/JavaScriptCore/heap/MarkStackInlineMethods.h.
- * heap/SlotVisitor.cpp:
- * heap/SlotVisitor.h:
- * heap/SlotVisitorInlineMethods.h: Removed.
- * heap/SlotVisitorInlines.h: Copied from Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h.
- * jit/HostCallReturnValue.cpp:
- * jit/JIT.cpp:
- * jit/JITArithmetic.cpp:
- * jit/JITArithmetic32_64.cpp:
- * jit/JITCall.cpp:
- * jit/JITCall32_64.cpp:
- * jit/JITInlineMethods.h: Removed.
- * jit/JITInlines.h: Copied from Source/JavaScriptCore/jit/JITInlineMethods.h.
- * jit/JITOpcodes.cpp:
- * jit/JITOpcodes32_64.cpp:
- * jit/JITPropertyAccess.cpp:
- * jit/JITPropertyAccess32_64.cpp:
- * jsc.cpp:
- * runtime/ArrayConstructor.cpp:
- * runtime/ArrayPrototype.cpp:
- * runtime/ButterflyInlineMethods.h: Removed.
- * runtime/ButterflyInlines.h: Copied from Source/JavaScriptCore/runtime/ButterflyInlineMethods.h.
- * runtime/IndexingHeaderInlineMethods.h: Removed.
- * runtime/IndexingHeaderInlines.h: Copied from Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h.
- * runtime/JSActivation.h:
- * runtime/JSArray.cpp:
- * runtime/JSArray.h:
- * runtime/JSCell.h:
- * runtime/JSObject.cpp:
- * runtime/JSValueInlineMethods.h: Removed.
- * runtime/JSValueInlines.h: Copied from Source/JavaScriptCore/runtime/JSValueInlineMethods.h.
- * runtime/LiteralParser.cpp:
- * runtime/ObjectConstructor.cpp:
- * runtime/Operations.h:
- * runtime/RegExpMatchesArray.cpp:
- * runtime/RegExpObject.cpp:
- * runtime/StringPrototype.cpp:
-
-2012-11-08 Filip Pizlo <fpizlo@apple.com>
-
- ArrayConstructor.h should have correct indentation
-
- Rubber stamped by Sam Weinig.
-
- * runtime/ArrayConstructor.h:
-
-2012-11-08 Filip Pizlo <fpizlo@apple.com>
-
- DFG should know that int == null is always false
- https://bugs.webkit.org/show_bug.cgi?id=101665
-
- Reviewed by Oliver Hunt.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
-
-2012-11-08 Filip Pizlo <fpizlo@apple.com>
-
- Arguments.h should have correct indentation
-
- Rubber stamped by Sam Weinig.
-
- * runtime/Arguments.h:
-
-2012-11-08 Filip Pizlo <fpizlo@apple.com>
-
- It should be possible to JIT compile get_by_vals and put_by_vals even if the DFG is disabled.
-
- Reviewed by Oliver Hunt.
-
- * jit/JITInlineMethods.h:
- (JSC::JIT::chooseArrayMode):
-
-2012-11-08 Filip Pizlo <fpizlo@apple.com>
-
- op_call should have LLInt call link info even if the DFG is disabled
- https://bugs.webkit.org/show_bug.cgi?id=101672
-
- Reviewed by Oliver Hunt.
-
- Get rid of the evil uses of fall-through.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::CodeBlock):
-
-2012-11-08 Oliver Hunt <oliver@apple.com>
-
- Improve effectiveness of function-level caching
- https://bugs.webkit.org/show_bug.cgi?id=101667
-
- Reviewed by Filip Pizlo.
-
- Added a random-eviction based cache for unlinked functions, and switch
- UnlinkedFunctionExecutable's code references to Weak<>, thereby letting
- us remove the explicit UnlinkedFunctionExecutable::clearCode() calls that
- were being triggered by GC.
-
- Refactored the random eviction part of the CodeCache into a separate data
- structure so that I didn't have to duplicate the code again, and then used
- that for the new function cache.
-
- * bytecode/UnlinkedCodeBlock.cpp:
- (JSC::UnlinkedFunctionExecutable::visitChildren):
- (JSC::UnlinkedFunctionExecutable::codeBlockFor):
- * bytecode/UnlinkedCodeBlock.h:
- (JSC::UnlinkedFunctionExecutable::clearCodeForRecompilation):
- (UnlinkedFunctionExecutable):
- * debugger/Debugger.cpp:
- * runtime/CodeCache.cpp:
- (JSC::CodeCache::getCodeBlock):
- (JSC::CodeCache::generateFunctionCodeBlock):
- (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
- (JSC::CodeCache::usedFunctionCode):
- (JSC):
- * runtime/Executable.cpp:
- (JSC::FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling):
- (JSC::FunctionExecutable::clearCode):
- * runtime/Executable.h:
- (FunctionExecutable):
-
-2012-11-07 Filip Pizlo <fpizlo@apple.com>
-
- DFG constant folding and CFG simplification should be smart enough to know that if a logical op's operand is proven to have a non-masquerading structure then it always evaluates to true
- https://bugs.webkit.org/show_bug.cgi?id=101511
-
- Reviewed by Oliver Hunt.
-
- To make life easier, this moves BranchDirection into BasicBlock so that after
- running the CFA, we always know, for each block, what direction the CFA
- proved. CFG simplification now both uses and preserves cfaBranchDirection in
- its transformations.
-
- Also made both LogicalNot and Branch check whether the operand is a known cell
- with a known structure, and if so, made them do the appropriate folding.
-
- 5% speed-up on V8/raytrace because it makes raytrace's own null checks
- evaporate (i.e. idioms like 'if (!x) throw "unhappiness"') thanks to the fact
- that we were already doing structure check hoisting.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::endBasicBlock):
- (JSC::DFG::AbstractState::execute):
- (JSC::DFG::AbstractState::mergeToSuccessors):
- * dfg/DFGAbstractState.h:
- (AbstractState):
- * dfg/DFGBasicBlock.h:
- (JSC::DFG::BasicBlock::BasicBlock):
- (BasicBlock):
- * dfg/DFGBranchDirection.h: Added.
- (DFG):
- (JSC::DFG::branchDirectionToString):
- (JSC::DFG::isKnownDirection):
- (JSC::DFG::branchCondition):
- * dfg/DFGCFGSimplificationPhase.cpp:
- (JSC::DFG::CFGSimplificationPhase::run):
- (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
-
-2012-11-08 Christophe Dumez <christophe.dumez@intel.com>
-
- [JSC] HTML extensions to String.prototype should escape " as &quot; in argument values
- https://bugs.webkit.org/show_bug.cgi?id=90667
-
- Reviewed by Benjamin Poulain.
-
- Escape quotation mark as &quot; in argument values to:
- - String.prototype.anchor(name)
- - String.prototype.fontcolor(color)
- - String.prototype.fontsize(size)
- - String.prototype.link(href)
-
- This behavior matches Chromium/V8 and Firefox/Spidermonkey
- implementations and is requited by:
- http://mathias.html5.org/specs/javascript/#escapeattributevalue
-
- This also fixes a potential security risk (XSS vector).
-
- * runtime/StringPrototype.cpp:
- (JSC::stringProtoFuncFontcolor):
- (JSC::stringProtoFuncFontsize):
- (JSC::stringProtoFuncAnchor):
- (JSC::stringProtoFuncLink):
-
-2012-11-08 Anders Carlsson <andersca@apple.com>
-
- HeapStatistics::s_pauseTimeStarts and s_pauseTimeEnds should be Vectors
- https://bugs.webkit.org/show_bug.cgi?id=101651
-
- Reviewed by Andreas Kling.
-
- HeapStatistics uses Deques when Vectors would work just as good.
-
- * heap/HeapStatistics.cpp:
- * heap/HeapStatistics.h:
- (HeapStatistics):
-
-2012-11-07 Filip Pizlo <fpizlo@apple.com>
-
- DFG should not assume that something is a double just because it might be undefined
- https://bugs.webkit.org/show_bug.cgi?id=101438
-
- Reviewed by Oliver Hunt.
-
- This changes all non-bitop arithmetic to (a) statically expect that variables are
- defined prior to use in arithmetic and (b) not fall off into double paths just
- because a value may not be a number. This is accomplished with two new notions of
- speculation:
-
- shouldSpeculateIntegerExpectingDefined: Should we speculate that the value is an
- integer if we ignore undefined (i.e. SpecOther) predictions?
-
- shouldSpeculateIntegerForArithmetic: Should we speculate that the value is an
- integer if we ignore non-numeric predictions?
-
- This is a ~2x speed-up on programs that seem to our prediction propagator to have
- paths in which otherwise numeric variables are undefined.
-
- * bytecode/SpeculatedType.h:
- (JSC::isInt32SpeculationForArithmetic):
- (JSC):
- (JSC::isInt32SpeculationExpectingDefined):
- (JSC::isDoubleSpeculationForArithmetic):
- (JSC::isNumberSpeculationExpectingDefined):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- * dfg/DFGGraph.h:
- (JSC::DFG::Graph::addShouldSpeculateInteger):
- (JSC::DFG::Graph::mulShouldSpeculateInteger):
- (JSC::DFG::Graph::negateShouldSpeculateInteger):
- (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
- (JSC::DFG::Graph::mulImmediateShouldSpeculateInteger):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::shouldSpeculateIntegerForArithmetic):
- (Node):
- (JSC::DFG::Node::shouldSpeculateIntegerExpectingDefined):
- (JSC::DFG::Node::shouldSpeculateDoubleForArithmetic):
- (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::compileAdd):
- (JSC::DFG::SpeculativeJIT::compileArithMod):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * jit/JITArithmetic.cpp:
- (JSC::JIT::emit_op_div):
-
-2012-11-06 Filip Pizlo <fpizlo@apple.com>
-
- JSC should infer when indexed storage contains only integers or doubles
- https://bugs.webkit.org/show_bug.cgi?id=98606
-
- Reviewed by Oliver Hunt.
-
- This adds two new indexing types: int32 and double. It also adds array allocation profiling,
- which allows array allocations to converge to allocating arrays using those types to which
- those arrays would have been converted.
-
- 20% speed-up on navier-stokes. 40% speed-up on various Kraken DSP tests. Some slow-downs too,
- but a performance win overall on all benchmarks we track.
-
- * API/JSObjectRef.cpp:
- (JSObjectMakeArray):
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * assembler/AbstractMacroAssembler.h:
- (JumpList):
- (JSC::AbstractMacroAssembler::JumpList::JumpList):
- * assembler/MacroAssemblerX86Common.h:
- (JSC::MacroAssemblerX86Common::branchDouble):
- * assembler/X86Assembler.h:
- (JSC::X86Assembler::jnp):
- (X86Assembler):
- (JSC::X86Assembler::X86InstructionFormatter::emitRex):
- * bytecode/ArrayAllocationProfile.cpp: Added.
- (JSC):
- (JSC::ArrayAllocationProfile::updateIndexingType):
- * bytecode/ArrayAllocationProfile.h: Added.
- (JSC):
- (ArrayAllocationProfile):
- (JSC::ArrayAllocationProfile::ArrayAllocationProfile):
- (JSC::ArrayAllocationProfile::selectIndexingType):
- (JSC::ArrayAllocationProfile::updateLastAllocation):
- (JSC::ArrayAllocationProfile::selectIndexingTypeFor):
- (JSC::ArrayAllocationProfile::updateLastAllocationFor):
- * bytecode/ArrayProfile.cpp:
- (JSC::ArrayProfile::updatedObservedArrayModes):
- (JSC):
- * bytecode/ArrayProfile.h:
- (JSC):
- (JSC::arrayModesInclude):
- (JSC::shouldUseSlowPutArrayStorage):
- (JSC::shouldUseFastArrayStorage):
- (JSC::shouldUseContiguous):
- (JSC::shouldUseDouble):
- (JSC::shouldUseInt32):
- (ArrayProfile):
- * bytecode/ByValInfo.h:
- (JSC::isOptimizableIndexingType):
- (JSC::jitArrayModeForIndexingType):
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::CodeBlock):
- (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
- (JSC):
- (JSC::CodeBlock::updateAllValueProfilePredictions):
- (JSC::CodeBlock::updateAllArrayPredictions):
- (JSC::CodeBlock::updateAllPredictions):
- (JSC::CodeBlock::shouldOptimizeNow):
- * bytecode/CodeBlock.h:
- (CodeBlock):
- (JSC::CodeBlock::numberOfArrayAllocationProfiles):
- (JSC::CodeBlock::addArrayAllocationProfile):
- (JSC::CodeBlock::updateAllValueProfilePredictions):
- (JSC::CodeBlock::updateAllArrayPredictions):
- * bytecode/DFGExitProfile.h:
- (JSC::DFG::exitKindToString):
- * bytecode/Instruction.h:
- (JSC):
- (JSC::Instruction::Instruction):
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecode/SpeculatedType.h:
- (JSC):
- (JSC::isRealNumberSpeculation):
- * bytecode/UnlinkedCodeBlock.cpp:
- (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
- * bytecode/UnlinkedCodeBlock.h:
- (JSC):
- (JSC::UnlinkedCodeBlock::addArrayAllocationProfile):
- (JSC::UnlinkedCodeBlock::numberOfArrayAllocationProfiles):
- (UnlinkedCodeBlock):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::newArrayAllocationProfile):
- (JSC):
- (JSC::BytecodeGenerator::emitNewArray):
- (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
- * bytecompiler/BytecodeGenerator.h:
- (BytecodeGenerator):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::ArrayMode::fromObserved):
- (JSC::DFG::ArrayMode::refine):
- (DFG):
- (JSC::DFG::ArrayMode::alreadyChecked):
- (JSC::DFG::arrayTypeToString):
- * dfg/DFGArrayMode.h:
- (JSC::DFG::ArrayMode::withType):
- (ArrayMode):
- (JSC::DFG::ArrayMode::withTypeAndConversion):
- (JSC::DFG::ArrayMode::usesButterfly):
- (JSC::DFG::ArrayMode::isSpecific):
- (JSC::DFG::ArrayMode::supportsLength):
- (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::getArrayMode):
- (ByteCodeParser):
- (JSC::DFG::ByteCodeParser::handleIntrinsic):
- (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGCCallHelpers.h:
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
- (CCallHelpers):
- * dfg/DFGCallArrayAllocatorSlowPathGenerator.h:
- (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal):
- (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- (JSC::DFG::FixupPhase::checkArray):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::Graph::dump):
- * dfg/DFGGraph.h:
- (JSC::DFG::Graph::byValIsPure):
- * dfg/DFGNode.h:
- (NewArrayBufferData):
- (JSC::DFG::Node::hasIndexingType):
- (Node):
- (JSC::DFG::Node::indexingType):
- (JSC::DFG::Node::setIndexingType):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
- (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
- (DFG):
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::arrayify):
- (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
- (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::callOperation):
- (SpeculativeJIT):
- (SpeculateIntegerOperand):
- (JSC::DFG::SpeculateIntegerOperand::use):
- (SpeculateDoubleOperand):
- (JSC::DFG::SpeculateDoubleOperand::use):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (DFG):
- (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * jit/JIT.h:
- (JSC::JIT::emitInt32GetByVal):
- (JIT):
- (JSC::JIT::emitInt32PutByVal):
- (JSC::JIT::emitDoublePutByVal):
- (JSC::JIT::emitContiguousPutByVal):
- * jit/JITExceptions.cpp:
- (JSC::genericThrow):
- * jit/JITInlineMethods.h:
- (JSC::arrayProfileSaw):
- (JSC::JIT::chooseArrayMode):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_new_array):
- (JSC::JIT::emit_op_new_array_with_size):
- (JSC::JIT::emit_op_new_array_buffer):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emitDoubleGetByVal):
- (JSC):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::emitGenericContiguousPutByVal):
- (JSC::JIT::emitSlow_op_put_by_val):
- (JSC::JIT::privateCompileGetByVal):
- (JSC::JIT::privateCompilePutByVal):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emitDoubleGetByVal):
- (JSC):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::emitGenericContiguousPutByVal):
- (JSC::JIT::emitSlow_op_put_by_val):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- * jit/JITStubs.h:
- (JSC):
- * jsc.cpp:
- (GlobalObject::finishCreation):
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::jitCompileAndSetHeuristics):
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * offlineasm/x86.rb:
- * runtime/ArrayConstructor.cpp:
- (JSC::constructArrayWithSizeQuirk):
- * runtime/ArrayConstructor.h:
- (JSC):
- * runtime/ArrayPrototype.cpp:
- (JSC::arrayProtoFuncConcat):
- (JSC::arrayProtoFuncSlice):
- (JSC::arrayProtoFuncSplice):
- (JSC::arrayProtoFuncFilter):
- (JSC::arrayProtoFuncMap):
- * runtime/Butterfly.h:
- (JSC::Butterfly::contiguousInt32):
- (JSC::Butterfly::contiguousDouble):
- (JSC::Butterfly::fromContiguous):
- * runtime/ButterflyInlineMethods.h:
- (JSC::Butterfly::createUninitializedDuringCollection):
- * runtime/FunctionPrototype.cpp:
- (JSC::functionProtoFuncBind):
- * runtime/IndexingHeaderInlineMethods.h:
- (JSC::IndexingHeader::indexingPayloadSizeInBytes):
- * runtime/IndexingType.cpp:
- (JSC::leastUpperBoundOfIndexingTypes):
- (JSC):
- (JSC::leastUpperBoundOfIndexingTypeAndType):
- (JSC::leastUpperBoundOfIndexingTypeAndValue):
- (JSC::indexingTypeToString):
- * runtime/IndexingType.h:
- (JSC):
- (JSC::hasUndecided):
- (JSC::hasInt32):
- (JSC::hasDouble):
- * runtime/JSArray.cpp:
- (JSC::JSArray::setLength):
- (JSC::JSArray::pop):
- (JSC::JSArray::push):
- (JSC::JSArray::shiftCountWithAnyIndexingType):
- (JSC::JSArray::unshiftCountWithAnyIndexingType):
- (JSC::compareNumbersForQSortWithInt32):
- (JSC):
- (JSC::compareNumbersForQSortWithDouble):
- (JSC::JSArray::sortNumericVector):
- (JSC::JSArray::sortNumeric):
- (JSC::JSArray::sortCompactedVector):
- (JSC::JSArray::sort):
- (JSC::JSArray::sortVector):
- (JSC::JSArray::fillArgList):
- (JSC::JSArray::copyToArguments):
- (JSC::JSArray::compactForSorting):
- * runtime/JSArray.h:
- (JSArray):
- (JSC::createContiguousArrayButterfly):
- (JSC::JSArray::create):
- (JSC::JSArray::tryCreateUninitialized):
- * runtime/JSGlobalObject.cpp:
- (JSC::JSGlobalObject::reset):
- (JSC):
- (JSC::JSGlobalObject::haveABadTime):
- (JSC::JSGlobalObject::visitChildren):
- * runtime/JSGlobalObject.h:
- (JSGlobalObject):
- (JSC::JSGlobalObject::originalArrayStructureForIndexingType):
- (JSC::JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation):
- (JSC::JSGlobalObject::arrayStructureForProfileDuringAllocation):
- (JSC::JSGlobalObject::isOriginalArrayStructure):
- (JSC::constructEmptyArray):
- (JSC::constructArray):
- * runtime/JSObject.cpp:
- (JSC::JSObject::copyButterfly):
- (JSC::JSObject::getOwnPropertySlotByIndex):
- (JSC::JSObject::putByIndex):
- (JSC::JSObject::enterDictionaryIndexingMode):
- (JSC::JSObject::createInitialIndexedStorage):
- (JSC):
- (JSC::JSObject::createInitialUndecided):
- (JSC::JSObject::createInitialInt32):
- (JSC::JSObject::createInitialDouble):
- (JSC::JSObject::createInitialContiguous):
- (JSC::JSObject::convertUndecidedToInt32):
- (JSC::JSObject::convertUndecidedToDouble):
- (JSC::JSObject::convertUndecidedToContiguous):
- (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
- (JSC::JSObject::convertUndecidedToArrayStorage):
- (JSC::JSObject::convertInt32ToDouble):
- (JSC::JSObject::convertInt32ToContiguous):
- (JSC::JSObject::convertInt32ToArrayStorage):
- (JSC::JSObject::convertDoubleToContiguous):
- (JSC::JSObject::convertDoubleToArrayStorage):
- (JSC::JSObject::convertContiguousToArrayStorage):
- (JSC::JSObject::convertUndecidedForValue):
- (JSC::JSObject::convertInt32ForValue):
- (JSC::JSObject::setIndexQuicklyToUndecided):
- (JSC::JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex):
- (JSC::JSObject::convertDoubleToContiguousWhilePerformingSetIndex):
- (JSC::JSObject::ensureInt32Slow):
- (JSC::JSObject::ensureDoubleSlow):
- (JSC::JSObject::ensureContiguousSlow):
- (JSC::JSObject::ensureArrayStorageSlow):
- (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
- (JSC::JSObject::switchToSlowPutArrayStorage):
- (JSC::JSObject::deletePropertyByIndex):
- (JSC::JSObject::getOwnPropertyNames):
- (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
- (JSC::JSObject::putByIndexBeyondVectorLength):
- (JSC::JSObject::putDirectIndexBeyondVectorLength):
- (JSC::JSObject::getNewVectorLength):
- (JSC::JSObject::countElements):
- (JSC::JSObject::ensureLengthSlow):
- (JSC::JSObject::getOwnPropertyDescriptor):
- * runtime/JSObject.h:
- (JSC::JSObject::getArrayLength):
- (JSC::JSObject::getVectorLength):
- (JSC::JSObject::canGetIndexQuickly):
- (JSC::JSObject::getIndexQuickly):
- (JSC::JSObject::tryGetIndexQuickly):
- (JSC::JSObject::canSetIndexQuickly):
- (JSC::JSObject::canSetIndexQuicklyForPutDirect):
- (JSC::JSObject::setIndexQuickly):
- (JSC::JSObject::initializeIndex):
- (JSC::JSObject::hasSparseMap):
- (JSC::JSObject::inSparseIndexingMode):
- (JSObject):
- (JSC::JSObject::ensureInt32):
- (JSC::JSObject::ensureDouble):
- (JSC::JSObject::ensureLength):
- (JSC::JSObject::indexingData):
- (JSC::JSObject::currentIndexingData):
- (JSC::JSObject::getHolyIndexQuickly):
- (JSC::JSObject::relevantLength):
- (JSC::JSObject::currentRelevantLength):
- * runtime/JSValue.cpp:
- (JSC::JSValue::description):
- * runtime/LiteralParser.cpp:
- (JSC::::parse):
- * runtime/ObjectConstructor.cpp:
- (JSC::objectConstructorGetOwnPropertyNames):
- (JSC::objectConstructorKeys):
- * runtime/StringPrototype.cpp:
- (JSC::stringProtoFuncMatch):
- (JSC::stringProtoFuncSplit):
- * runtime/Structure.cpp:
- (JSC::Structure::nonPropertyTransition):
- * runtime/StructureTransitionTable.h:
- (JSC::newIndexingType):
-
-2012-11-08 Balazs Kilvady <kilvadyb@homejinni.com>
-
- ASSERT problem on MIPS
- https://bugs.webkit.org/show_bug.cgi?id=100589
-
- Reviewed by Oliver Hunt.
-
- ASSERT fix for MIPS arch.
-
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_resolve_operations):
-
-2012-11-08 Michael Saboff <msaboff@apple.com>
-
- OpaqueJSClassContextData() should use StringImpl::isolatedCopy() to make string copies
- https://bugs.webkit.org/show_bug.cgi?id=101507
-
- Reviewed by Andreas Kling.
-
- Changed to use isolatedCopy() for key Strings.
-
- * API/JSClassRef.cpp:
- (OpaqueJSClassContextData::OpaqueJSClassContextData):
-
-2012-11-07 Mark Hahnenberg <mhahnenberg@apple.com>
-
- WeakBlocks should be HeapBlocks
- https://bugs.webkit.org/show_bug.cgi?id=101411
-
- Reviewed by Oliver Hunt.
-
- Currently WeakBlocks use fastMalloc memory. They are very similar to the other HeapBlocks, however,
- so we should change them to being allocated with the BlockAllocator.
-
- * heap/BlockAllocator.cpp:
- (JSC::BlockAllocator::BlockAllocator):
- * heap/BlockAllocator.h: Added a new RegionSet for WeakBlocks.
- (JSC):
- (BlockAllocator):
- (JSC::WeakBlock):
- * heap/Heap.h: Friended WeakSet to allow access to the BlockAllocator.
- (Heap):
- * heap/WeakBlock.cpp:
- (JSC::WeakBlock::create): Refactored to use HeapBlocks rather than fastMalloc.
- (JSC::WeakBlock::WeakBlock):
- * heap/WeakBlock.h: Changed the WeakBlock size to 4 KB so that it divides evenly into the Region size.
- (JSC):
- (WeakBlock):
- * heap/WeakSet.cpp:
- (JSC::WeakSet::~WeakSet):
- (JSC::WeakSet::addAllocator):
-
-2012-11-07 Filip Pizlo <fpizlo@apple.com>
-
- Indentation of ArgList.h is wrong
- https://bugs.webkit.org/show_bug.cgi?id=101441
-
- Reviewed by Andreas Kling.
-
- Just unindented by 4 spaces.
-
- * runtime/ArgList.h:
-
-2012-11-07 Gabor Ballabas <gaborb@inf.u-szeged.hu>
-
- [Qt][ARM] REGRESSION(r133688): It made all JSC and layout tests crash on ARM traditional platform
- https://bugs.webkit.org/show_bug.cgi?id=101465
-
- Reviewed by Oliver Hunt.
-
- Fix failing javascriptcore tests on ARM after r133688
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::CodeBlock):
-
-2012-11-06 Oliver Hunt <oliver@apple.com>
-
- Reduce parser overhead in JSC
- https://bugs.webkit.org/show_bug.cgi?id=101127
-
- Reviewed by Filip Pizlo.
-
- An exciting journey into the world of architecture in which our hero
- adds yet another layer to JSC codegeneration.
-
- This patch adds a marginally more compact form of bytecode that is
- free from any data specific to a given execution context, and that
- does store any data structures necessary for execution. To actually
- execute this UnlinkedBytecode we still need to instantiate a real
- CodeBlock, but this is a much faster linear time operation than any
- of the earlier parsing or code generation passes.
-
- As the unlinked code is context free we can then simply use a cache
- from source to unlinked code mapping to completely avoid all of the
- old parser overhead. The cache is currently very simple and memory
- heavy, using the complete source text as a key (rather than SourceCode
- or equivalent), and a random eviction policy.
-
- This seems to produce a substantial win when loading identical content
- in different contexts.
-
- * API/tests/testapi.c:
- (main):
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * bytecode/CodeBlock.cpp:
- * bytecode/CodeBlock.h:
- Moved a number of fields, and a bunch of logic to UnlinkedCodeBlock.h/cpp
- * bytecode/Opcode.h:
- Added a global const init no op instruction needed to get correct
- behaviour without any associated semantics.
- * bytecode/UnlinkedCodeBlock.cpp: Added.
- * bytecode/UnlinkedCodeBlock.h: Added.
- A fairly shallow, GC allocated version of the old CodeBlock
- classes with a 32bit instruction size, and just metadata
- size tracking.
- * bytecompiler/BytecodeGenerator.cpp:
- * bytecompiler/BytecodeGenerator.h:
- Replace direct access to m_symbolTable with access through
- symbolTable(). ProgramCode no longer has a symbol table at
- all so some previously unconditional (and pointless) uses
- of symbolTable get null checks.
- A few other changes to deal with type changes due to us generating
- unlinked code (eg. pointer free, so profile indices rather than
- pointers).
- * dfg/DFGByteCodeParser.cpp:
- * dfg/DFGCapabilities.h:
- Support global_init_nop
- * interpreter/Interpreter.cpp:
- Now get the ProgramExecutable to initialise new global properties
- before starting execution.
- * jit/JIT.cpp:
- * jit/JITDriver.h:
- * jit/JITStubs.cpp:
- * llint/LLIntData.cpp:
- * llint/LLIntSlowPaths.cpp:
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- Adding init_global_const_nop everywhere else
- * parser/Parser.h:
- * parser/ParserModes.h: Added.
- * parser/ParserTokens.h:
- Parser no longer needs a global object or callframe to function
- * runtime/CodeCache.cpp: Added.
- * runtime/CodeCache.h: Added.
- A simple, random eviction, Source->UnlinkedCode cache
- * runtime/Executable.cpp:
- * runtime/Executable.h:
- Executables now reference their unlinked counterparts, and
- request code specifically for the target global object.
- * runtime/JSGlobalData.cpp:
- * runtime/JSGlobalData.h:
- GlobalData now owns a CodeCache and a set of new structures
- for the unlinked code types.
- * runtime/JSGlobalObject.cpp:
- * runtime/JSGlobalObject.h:
- Utility functions used by executables to perform compilation
-
- * runtime/JSType.h:
- Add new JSTypes for unlinked code
-
-2012-11-06 Michael Saboff <msaboff@apple.com>
-
- JSStringCreateWithCFString() Should create an 8 bit String if possible
- https://bugs.webkit.org/show_bug.cgi?id=101104
-
- Reviewed by Darin Adler.
-
- Try converting the CFString to an 8 bit string using CFStringGetBytes(...,
- kCFStringEncodingISOLatin1, ...) and return the 8 bit string if successful.
- If not proceed with 16 bit conversion.
-
- * API/JSStringRefCF.cpp:
- (JSStringCreateWithCFString):
-
-2012-11-06 Oliver Hunt <oliver@apple.com>
-
- Reduce direct m_symbolTable usage in CodeBlock
- https://bugs.webkit.org/show_bug.cgi?id=101391
-
- Reviewed by Sam Weinig.
-
- Simple refactoring.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::dumpStatistics):
- (JSC::CodeBlock::nameForRegister):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::isCaptured):
-
-2012-11-06 Michael Saboff <msaboff@apple.com>
-
- Lexer::scanRegExp, create 8 bit pattern and flag Identifiers from 16 bit source when possible
- https://bugs.webkit.org/show_bug.cgi?id=101013
-
- Reviewed by Darin Adler.
-
- Changed scanRegExp so that it will create 8 bit identifiers from 8 bit sources and from 16 bit sources
- whan all the characters are 8 bit. Using two templated helpers, the "is all 8 bit" check is only performed
- on 16 bit sources. The first helper is orCharacter() that will accumulate the or value of all characters
- only for 16 bit sources. Replaced the helper Lexer::makeIdentifierSameType() with Lexer::makeRightSizedIdentifier().
-
- * parser/Lexer.cpp:
- (JSC::orCharacter<LChar>): Explicit template that serves as a placeholder.
- (JSC::orCharacter<UChar>): Explicit template that actually or accumulates characters.
- (JSC::Lexer::scanRegExp):
- * parser/Lexer.h:
- (Lexer):
- (JSC::Lexer::makeRightSizedIdentifier<LChar>): New template that always creates an 8 bit Identifier.
- (JSC::Lexer::makeRightSizedIdentifier<UChar>): New template that creates an 8 bit Identifier for 8 bit
- data in a 16 bit source.
-
-2012-11-06 Filip Pizlo <fpizlo@apple.com>
-
- Indentation of JSCell.h is wrong
- https://bugs.webkit.org/show_bug.cgi?id=101379
-
- Rubber stamped by Alexey Proskuryakov.
-
- Just removed four spaces on a bunch of lines.
-
- * runtime/JSCell.h:
-
-2012-11-05 Filip Pizlo <fpizlo@apple.com>
-
- Indentation of JSObject.h is wrong
- https://bugs.webkit.org/show_bug.cgi?id=101313
-
- Rubber stamped by Alexey Proskuryakov.
-
- Just unindented code, since namespace bodies shouldn't be indented.
-
- * runtime/JSObject.h:
-
-2012-11-05 Filip Pizlo <fpizlo@apple.com>
-
- Indentation of JSArray.h is wrong
- https://bugs.webkit.org/show_bug.cgi?id=101314
-
- Rubber stamped by Alexey Proskuryakov.
-
- Just removing the indentation inside the namespace body.
-
- * runtime/JSArray.h:
-
-2012-11-05 Filip Pizlo <fpizlo@apple.com>
-
- DFG should not fall down to patchable GetById just because a prototype had things added to it
- https://bugs.webkit.org/show_bug.cgi?id=101299
-
- Reviewed by Geoffrey Garen.
-
- This looks like a slight win on V8v7 and SunSpider.
-
- * bytecode/DFGExitProfile.h:
- (JSC::DFG::exitKindToString):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-11-05 Filip Pizlo <fpizlo@apple.com>
-
- Get rid of method_check
- https://bugs.webkit.org/show_bug.cgi?id=101147
-
- Reviewed by Geoffrey Garen.
-
- op_method_check no longer buys us anything, since get_by_id proto caching
- gives just as much profiling information and the DFG inlines monomorphic
- proto accesses anyway.
-
- This also has the potential for a speed-up since it makes parsing of
- profiling data easier. No longer do we have to deal with the confusion of
- the get_by_id portion of a method_check appearing monomorphic even though
- we're really dealing with a bimorphic access (method_check specializes for
- one case and get_by_id for another).
-
- This looks like a 1% speed-up on both SunSpider and V8v7.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::printGetByIdCacheStatus):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::shrinkToFit):
- (JSC::CodeBlock::unlinkCalls):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::getCallLinkInfo):
- (JSC::CodeBlock::callLinkInfo):
- (CodeBlock):
- * bytecode/GetByIdStatus.cpp:
- (JSC::GetByIdStatus::computeFromLLInt):
- * bytecode/MethodCallLinkInfo.cpp: Removed.
- * bytecode/MethodCallLinkInfo.h: Removed.
- * bytecode/MethodCallLinkStatus.cpp: Removed.
- * bytecode/MethodCallLinkStatus.h: Removed.
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC):
- * bytecompiler/BytecodeGenerator.h:
- (BytecodeGenerator):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::FunctionCallDotNode::emitBytecode):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canCompileOpcode):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- (JSC::PropertyStubCompilationInfo::copyToStubInfo):
- (JSC::JIT::privateCompile):
- * jit/JIT.h:
- (JSC::PropertyStubCompilationInfo::slowCaseInfo):
- (PropertyStubCompilationInfo):
- (JSC):
- (JIT):
- * jit/JITPropertyAccess.cpp:
- (JSC):
- (JSC::JIT::emitSlow_op_get_by_id):
- (JSC::JIT::compileGetByIdSlowCase):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC):
- (JSC::JIT::compileGetByIdSlowCase):
- * jit/JITStubs.cpp:
- (JSC):
- * jit/JITStubs.h:
- * llint/LowLevelInterpreter.asm:
-
-2012-11-05 Yuqiang Xian <yuqiang.xian@intel.com>
-
- Refactor LLInt64 to distinguish the pointer operations from the 64-bit integer operations
- https://bugs.webkit.org/show_bug.cgi?id=100321
-
- Reviewed by Filip Pizlo.
-
- We have refactored the MacroAssembler and JIT compilers to distinguish
- the pointer operations from the 64-bit integer operations (see bug #99154).
- Now we want to do the similar work for LLInt, and the goal is same as
- the one mentioned in 99154.
-
- This is the second part of the modification: in the low level interpreter,
- changing the operations on 64-bit integers to use the "<foo>q" instructions.
- This also removes some unused/meaningless "<foo>p" instructions.
-
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter.cpp:
- (JSC::CLoop::execute):
- * llint/LowLevelInterpreter64.asm:
- * offlineasm/armv7.rb:
- * offlineasm/cloop.rb:
- * offlineasm/instructions.rb:
- * offlineasm/x86.rb:
-
-2012-11-05 Filip Pizlo <fpizlo@apple.com>
-
- Prototype chain caching should check that the path from the base object to the slot base involves prototype hops only
- https://bugs.webkit.org/show_bug.cgi?id=101276
-
- Reviewed by Gavin Barraclough.
-
- Changed normalizePrototypeChain() to report an invalid prototype chain if any object is a proxy.
- This catches cases where our prototype chain checks would have been insufficient to guard against
- newly introduced properties, despecialized properties, or deleted properties in the chain of
- objects involved in the access.
-
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- (JSC::DFG::tryBuildGetByIDProtoList):
- (JSC::DFG::tryCachePutByID):
- (JSC::DFG::tryBuildPutByIdList):
- * jit/JITStubs.cpp:
- (JSC::JITThunks::tryCachePutByID):
- (JSC::JITThunks::tryCacheGetByID):
- (JSC::DEFINE_STUB_FUNCTION):
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * runtime/Operations.h:
- (JSC):
- (JSC::normalizePrototypeChain):
-
-2012-11-05 Dima Gorbik <dgorbik@apple.com>
-
- Back out controversial changes from Bug 98665.
- https://bugs.webkit.org/show_bug.cgi?id=101244
-
- Reviewed by David Kilzer.
-
- Backing out changes from Bug 98665 until further discussions take place on rules for including Platform.h in Assertions.h.
-
- * API/tests/minidom.c:
- * API/tests/testapi.c:
-
-2012-11-04 Filip Pizlo <fpizlo@apple.com>
-
- Reduce the verbosity of referring to QNaN in JavaScriptCore
- https://bugs.webkit.org/show_bug.cgi?id=101174
-
- Reviewed by Geoffrey Garen.
-
- Introduces a #define QNaN in JSValue.h, and replaces all previous uses of
- std::numeric_limits<double>::quiet_NaN() with QNaN.
-
- * API/JSValueRef.cpp:
- (JSValueMakeNumber):
- (JSValueToNumber):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emitFloatTypedArrayGetByVal):
- * runtime/CachedTranscendentalFunction.h:
- (JSC::CachedTranscendentalFunction::initialize):
- * runtime/DateConstructor.cpp:
- (JSC::constructDate):
- * runtime/DateInstanceCache.h:
- (JSC::DateInstanceData::DateInstanceData):
- (JSC::DateInstanceCache::reset):
- * runtime/ExceptionHelpers.cpp:
- (JSC::InterruptedExecutionError::defaultValue):
- (JSC::TerminatedExecutionError::defaultValue):
- * runtime/JSCell.h:
- (JSC::JSValue::getPrimitiveNumber):
- * runtime/JSDateMath.cpp:
- (JSC::parseDateFromNullTerminatedCharacters):
- * runtime/JSGlobalData.cpp:
- (JSC::JSGlobalData::JSGlobalData):
- (JSC::JSGlobalData::resetDateCache):
- * runtime/JSGlobalObjectFunctions.cpp:
- (JSC::parseInt):
- (JSC::jsStrDecimalLiteral):
- (JSC::toDouble):
- (JSC::jsToNumber):
- (JSC::parseFloat):
- * runtime/JSValue.cpp:
- (JSC::JSValue::toNumberSlowCase):
- * runtime/JSValue.h:
- (JSC):
- * runtime/JSValueInlineMethods.h:
- (JSC::jsNaN):
- * runtime/MathObject.cpp:
- (JSC::mathProtoFuncMax):
- (JSC::mathProtoFuncMin):
-
-2012-11-03 Filip Pizlo <fpizlo@apple.com>
-
- Baseline JIT should use structure watchpoints whenever possible
- https://bugs.webkit.org/show_bug.cgi?id=101146
-
- Reviewed by Sam Weinig.
-
- No speed-up yet except on toy programs. I think that it will start to show
- speed-ups with https://bugs.webkit.org/show_bug.cgi?id=101147, which this is
- a step towards.
-
- * jit/JIT.h:
- (JIT):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::privateCompilePutByIdTransition):
- (JSC::JIT::privateCompileGetByIdProto):
- (JSC::JIT::privateCompileGetByIdProtoList):
- (JSC::JIT::privateCompileGetByIdChainList):
- (JSC::JIT::privateCompileGetByIdChain):
- (JSC::JIT::addStructureTransitionCheck):
- (JSC):
- (JSC::JIT::testPrototype):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::privateCompilePutByIdTransition):
- (JSC::JIT::privateCompileGetByIdProto):
- (JSC::JIT::privateCompileGetByIdProtoList):
- (JSC::JIT::privateCompileGetByIdChainList):
- (JSC::JIT::privateCompileGetByIdChain):
-
-2012-11-04 Csaba Osztrogonác <ossy@webkit.org>
-
- [Qt] udis86_itab.c is always regenerated
- https://bugs.webkit.org/show_bug.cgi?id=100756
-
- Reviewed by Simon Hausmann.
-
- * DerivedSources.pri: Generate sources to the generated directory.
- * disassembler/udis86/differences.txt:
- * disassembler/udis86/itab.py: Add --outputDir option.
- (UdItabGenerator.__init__):
- (genItabH):
- (genItabC):
- (main):
-
-2012-11-02 Filip Pizlo <fpizlo@apple.com>
-
- LLInt 32-bit put_by_val ArrayStorage case should use the right register (t3, not t2) for the index in the publicLength updating path
- https://bugs.webkit.org/show_bug.cgi?id=101118
-
- Reviewed by Gavin Barraclough.
-
- * llint/LowLevelInterpreter32_64.asm:
-
-2012-11-02 Filip Pizlo <fpizlo@apple.com>
-
- DFG::Node::converToStructureTransitionWatchpoint should take kindly to ArrayifyToStructure
- https://bugs.webkit.org/show_bug.cgi?id=101117
-
- Reviewed by Gavin Barraclough.
-
- We have logic to convert ArrayifyToStructure to StructureTransitionWatchpoint, which is awesome, except
- that previously convertToStructureTransitionWatchpoint was (a) asserting that it never saw an
- ArrayifyToStructure and (b) would incorrectly create a ForwardStructureTransitionWatchpoint if it did.
-
- * dfg/DFGNode.h:
- (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
-
-2012-11-02 Filip Pizlo <fpizlo@apple.com>
-
- DFG::SpeculativeJIT::typedArrayDescriptor should use the Float64Array descriptor for Float64Arrays
- https://bugs.webkit.org/show_bug.cgi?id=101114
-
- Reviewed by Gavin Barraclough.
-
- As in https://bugs.webkit.org/show_bug.cgi?id=101112, this was only wrong when Float64Array descriptors
- hadn't been initialized yet. That happens rarely, but when it does happen, we would crash.
-
- This would also become much more wrong if we ever put type size info (num bytes, etc) in the descriptor
- and used that directly. So it's good to fix it.
-
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
-
-2012-11-02 Filip Pizlo <fpizlo@apple.com>
-
- JIT::privateCompileGetByVal should use the uint8ClampedArrayDescriptor for compiling accesses to Uint8ClampedArrays
- https://bugs.webkit.org/show_bug.cgi?id=101112
-
- Reviewed by Gavin Barraclough.
-
- The only reason why the code was wrong to use uint8ArrayDescriptor instead is that if we're just using
- Uint8ClampedArrays then the descriptor for Uint8Array may not have been initialized.
-
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::privateCompileGetByVal):
-
-2012-11-02 Mark Hahnenberg <mhahnenberg@apple.com>
-
- MarkedBlocks should use something other than the mark bits to indicate liveness for newly allocated objects
- https://bugs.webkit.org/show_bug.cgi?id=100877
-
- Reviewed by Filip Pizlo.
-
- Currently when we canonicalize cell liveness data in MarkedBlocks, we set the mark bit for every cell in the
- block except for those in the free list. This allows us to consider objects that were allocated since the
- previous collection to be considered live until they have a chance to be properly marked by the collector.
-
- If we want to use the mark bits to signify other types of information, e.g. using sticky mark bits for generational
- collection, we will have to keep track of newly allocated objects in a different fashion when we canonicalize cell liveness.
-
- One method would be to allocate a separate set of bits while canonicalizing liveness data. These bits would
- track the newly allocated objects in the block separately from those objects who had already been marked. We would
- then check these bits, along with the mark bits, when determining liveness.
-
- * heap/Heap.h:
- (Heap):
- (JSC::Heap::isLive): We now check for the presence of the newlyAllocated Bitmap.
- (JSC):
- * heap/MarkedBlock.cpp:
- (JSC::MarkedBlock::specializedSweep): We clear the newlyAllocated Bitmap if we're creating a free list. This
- will happen if we canonicalize liveness data for some other reason than collection (e.g. forEachCell) and
- then start allocating again.
- (JSC::SetNewlyAllocatedFunctor::SetNewlyAllocatedFunctor):
- (SetNewlyAllocatedFunctor):
- (JSC::SetNewlyAllocatedFunctor::operator()): We set the newlyAllocated bits for all the objects
- that aren't already marked. We undo the bits for the objects in the free list later in canonicalizeCellLivenessData.
- (JSC::MarkedBlock::canonicalizeCellLivenessData): We should never have a FreeListed block with a newlyAllocated Bitmap.
- We allocate the new Bitmap, set the bits for all the objects that aren't already marked, and then unset all of the
- bits for the items currently in the FreeList.
- * heap/MarkedBlock.h:
- (JSC::MarkedBlock::clearMarks): We clear the newlyAllocated bitmap if it exists because at this point we don't need it
- any more.
- (JSC::MarkedBlock::isEmpty): If we have some objects that are newlyAllocated, we are not empty.
- (JSC::MarkedBlock::isNewlyAllocated):
- (JSC):
- (JSC::MarkedBlock::setNewlyAllocated):
- (JSC::MarkedBlock::clearNewlyAllocated):
- (JSC::MarkedBlock::isLive): We now check the newlyAllocated Bitmap, if it exists, when determining liveness of a cell in
- a block that is Marked.
- * heap/WeakBlock.cpp:
- (JSC::WeakBlock::visit): We need to make sure we don't finalize objects that are in the newlyAllocated Bitmap.
- (JSC::WeakBlock::reap): Ditto.
-
-2012-11-02 Filip Pizlo <fpizlo@apple.com>
-
- JIT::privateCompileGetByVal should use MacroAssemblerCodePtr::createFromExecutableAddress like JIT::privateCompilePutByVal
- https://bugs.webkit.org/show_bug.cgi?id=101109
-
- Reviewed by Gavin Barraclough.
-
- This fixes crashes on ARMv7 resulting from the return address already being tagged with the THUMB2 bit.
-
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::privateCompileGetByVal):
-
-2012-11-02 Simon Fraser <simon.fraser@apple.com>
-
- Enable SUBPIXEL_LAYOUT on Mac
- https://bugs.webkit.org/show_bug.cgi?id=101076
-
- Reviewed by Dave Hyatt.
-
- Define ENABLE_SUBPIXEL_LAYOUT and include it in FEATURE_DEFINES.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-11-02 Michael Saboff <msaboff@apple.com>
-
- RegExp.prototype.toString Should Produce an 8 bit JSString if possible.
- https://bugs.webkit.org/show_bug.cgi?id=101003
-
- Reviewed by Geoffrey Garen.
-
- Took the logic of regExpObjectSource() and created two templated helpers that uses the
- source character type when appending to the StringBuilder.
-
- * runtime/RegExpObject.cpp:
- (JSC::appendLineTerminatorEscape): Checks line terminate type to come up with escaped version.
- (JSC::regExpObjectSourceInternal): Templated version of original.
- (JSC::regExpObjectSource): Wrapper function.
-
-2012-11-02 Adam Barth <abarth@webkit.org>
-
- ENABLE(UNDO_MANAGER) is disabled everywhere and is not under active development
- https://bugs.webkit.org/show_bug.cgi?id=100711
-
- Reviewed by Eric Seidel.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-11-02 Simon Hausmann <simon.hausmann@digia.com>
-
- [Qt] Fix build on Windows when Qt is configured with -release
- https://bugs.webkit.org/show_bug.cgi?id=101041
-
- Reviewed by Jocelyn Turcotte.
-
- When Qt is configured with -debug or -release, the release/debug build of for example
- QtCore is not available by default. For LLIntExtractor we always need to build debug
- _and_ release versions, but we do not actually need any Qt libraries nor qtmain(d).lib.
- Therefore we can disable all these features but need to keep $$QT.core.includes in the
- INCLUDEPATH for some defines from qglobal.h.
-
- * LLIntOffsetsExtractor.pro:
-
-2012-11-01 Mark Lam <mark.lam@apple.com>
-
- A llint workaround for a toolchain issue.
- https://bugs.webkit.org/show_bug.cgi?id=101012.
-
- Reviewed by Michael Saboff.
-
- * llint/LowLevelInterpreter.asm:
- - use a local label to workaround the toolchain issue with undeclared
- global labels.
-
-2012-11-01 Oliver Hunt <oliver@apple.com>
-
- Remove GlobalObject constant register that is typically unused
- https://bugs.webkit.org/show_bug.cgi?id=101005
-
- Reviewed by Geoffrey Garen.
-
- The GlobalObject constant register is frequently allocated even when it
- is not used, it is also getting in the way of some other optimisations.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::CodeBlock):
- * bytecode/CodeBlock.h:
- (CodeBlock):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::BytecodeGenerator):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseResolveOperations):
-
-2012-10-31 Filip Pizlo <fpizlo@apple.com>
-
- DFG optimized string access code should be enabled
- https://bugs.webkit.org/show_bug.cgi?id=100825
-
- Reviewed by Oliver Hunt.
-
- - Removes prediction checks from the parser.
-
- - Fixes the handling of array mode refinement for strings. I.e. we don't do
- any refinement - we already know it's going to be a string. We could
- revisit this in the future, but for now the DFG lacks the ability to
- handle any array modes other than Array::String for string intrinsics, so
- this is as good as it gets.
-
- - Removes uses of isBlahSpeculation for checking if a mode is already
- checked. isBlahSpeculation implicitly checks if the SpeculatedType is not
- BOTTOM ("empty"), which breaks for checking if a mode is already checked
- since a mode may already be "checked" in the sense that we've proven that
- the code is unreachable.
-
- ~1% speed-up on V8v7, mostly from a speed-up on crypto, which uses string
- intrinsics in one of the hot functions.
-
- * bytecode/SpeculatedType.h:
- (JSC::speculationChecked):
- (JSC):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::ArrayMode::alreadyChecked):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::handleIntrinsic):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
-
-2012-10-31 Filip Pizlo <fpizlo@apple.com>
-
- Sparse array size threshold should be increased to 100000
- https://bugs.webkit.org/show_bug.cgi?id=100827
-
- Reviewed by Oliver Hunt.
-
- This enables the use of contiguous arrays in programs that previously
- couldn't use them. And I so far can't see any examples of this being
- a downside. To the extent that there is a downside, it ought to be
- addressed by GC: https://bugs.webkit.org/show_bug.cgi?id=100828
-
- * runtime/ArrayConventions.h:
- (JSC):
-
-2012-10-31 Mark Lam <mark.lam@apple.com>
-
- C++ llint 64-bit backend needs to zero extend results of int32 operations.
- https://bugs.webkit.org/show_bug.cgi?id=100899.
-
- Reviewed by Filip Pizlo.
-
- llint asm instructions ending in "i" for a 64-bit machine expects the
- high 32-bit of registers to be zero'ed out when a 32-bit instruction
- writes into a register. Fixed the C++ llint to honor this.
-
- Fixed the index register used in BaseIndex addressing to be of size
- intptr_t as expected.
-
- Updated CLoopRegister to handle different endiannesss configurations.
-
- * llint/LowLevelInterpreter.cpp:
- (JSC::CLoopRegister::clearHighWord):
- - new method to clear the high 32-bit of a 64-bit register.
- It's a no-op for the 32-bit build.
- (CLoopRegister):
- - CLoopRegister now takes care of packing and byte endianness order.
- (JSC::CLoop::execute): - Added an assert.
- * offlineasm/cloop.rb:
- - Add calls to clearHighWord() wherever needed.
-
-2012-10-31 Mark Lam <mark.lam@apple.com>
-
- A JSC printf (support for %J+s and %b).
- https://bugs.webkit.org/show_bug.cgi?id=100566.
-
- Reviewed by Michael Saboff.
-
- Added VMInspector::printf(), fprintf(), sprintf(), and snprintf().
- - %b prints ints as boolean TRUE (non-zero) or FALSE (zero).
- - %Js prints a WTF::String* like a %s prints a char*.
- Also works for 16bit WTF::Strings (prints wchar_t* using %S).
- - '+' is a modifier meaning 'use verbose mode', and %J+s is an example
- of its use.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * interpreter/VMInspector.cpp:
- (FormatPrinter):
- (JSC::FormatPrinter::~FormatPrinter):
- (JSC::FormatPrinter::print):
- (JSC::FormatPrinter::printArg):
- (JSC::FormatPrinter::printWTFString):
- (JSC::FileFormatPrinter::FileFormatPrinter):
- (JSC::FileFormatPrinter::printArg):
- (JSC::StringFormatPrinter::StringFormatPrinter):
- (JSC::StringFormatPrinter::printArg):
- (JSC::StringNFormatPrinter::StringNFormatPrinter):
- (JSC::StringNFormatPrinter::printArg):
- (JSC::VMInspector::fprintf):
- (JSC::VMInspector::printf):
- (JSC::VMInspector::sprintf):
- (JSC::VMInspector::snprintf):
- * interpreter/VMInspector.h:
- (VMInspector):
-
-2012-10-31 Mark Lam <mark.lam@apple.com>
-
- 64-bit llint PC offset can be negative: using an unsigned shift is a bug.
- https://bugs.webkit.org/show_bug.cgi?id=100896.
-
- Reviewed by Filip Pizlo.
-
- Fixed the PC offset divisions in the 64-bit llint asm to use rshift instead of urshift.
-
- * llint/LowLevelInterpreter64.asm:
-
-2012-10-30 Yuqiang Xian <yuqiang.xian@intel.com>
-
- glsl-function-atan.html WebGL conformance test fails after https://bugs.webkit.org/show_bug.cgi?id=99154
- https://bugs.webkit.org/show_bug.cgi?id=100789
-
- Reviewed by Filip Pizlo.
-
- We accidently missed a bitwise double to int64 conversion.
-
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::silentFill):
-
-2012-10-30 Joseph Pecoraro <pecoraro@apple.com>
-
- [Mac] Sync up FeatureDefine Configuration Files
- https://bugs.webkit.org/show_bug.cgi?id=100171
-
- Reviewed by David Kilzer.
-
- Follow up to better coordinate with iOS feature defines. Make:
-
- - ENABLE_FILTERS always on
- - ENABLE_INPUT_* iphonesimulator values point to the iphoneos values
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-30 Joseph Pecoraro <pecoraro@apple.com>
-
- [Mac] Sync up FeatureDefine Configuration Files
- https://bugs.webkit.org/show_bug.cgi?id=100171
-
- Reviewed by David Kilzer.
-
- Ensure an identical FeatureDefine files across all projects. Changes:
-
- - ENABLE_CSS_BOX_DECORATION_BREAK should be in all
- - ENABLE_PDFKIT_PLUGIN should be in all
- - ENABLE_RESOLUTION_MEDIA_QUERY should be in all
- - ENABLE_ENCRYPTED_MEDIA should be in all
- - ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING with corrected value
- - Some alphabetical ordering cleanup
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-30 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Arrays can change IndexingType in the middle of sorting
- https://bugs.webkit.org/show_bug.cgi?id=100773
-
- Reviewed by Filip Pizlo.
-
- Instead of giving up, we just fetch the appropriate vector based on the current
- IndexingType of the array.
-
- * runtime/JSArray.cpp:
- (JSC::JSArray::sortVector):
- * runtime/JSObject.h:
- (JSObject):
- (JSC::JSObject::currentIndexingData):
- (JSC::JSObject::currentRelevantLength):
-
-2012-10-29 Anders Carlsson <andersca@apple.com>
-
- Build WebKit as C++11 on Mac
- https://bugs.webkit.org/show_bug.cgi?id=100720
-
- Reviewed by Daniel Bates.
-
- * Configurations/Base.xcconfig:
- Add CLANG_CXX_LANGUAGE_STANDARD=gnu++0x.
-
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::generate):
- (JSC::BytecodeGenerator::pushFinallyContext):
- (JSC::BytecodeGenerator::beginSwitch):
- * llint/LLIntOffsetsExtractor.cpp:
- * runtime/Identifier.cpp:
- (JSC::Identifier::add8):
- * runtime/Identifier.h:
- (JSC::Identifier::add):
- * runtime/JSONObject.cpp:
- (JSC::appendStringToStringBuilder):
- * runtime/StringPrototype.cpp:
- (JSC::replaceUsingStringSearch):
- Add static_casts to prevent implicit type conversions in non-constant initializer lists.
-
-2012-10-28 Mark Rowe <mrowe@apple.com>
-
- Simplify Xcode configuration settings that used to vary between OS versions.
-
- Reviewed by Dan Bernstein.
-
- * Configurations/Base.xcconfig:
- * Configurations/DebugRelease.xcconfig:
- * Configurations/JavaScriptCore.xcconfig:
-
-2012-10-28 Mark Rowe <mrowe@apple.com>
-
- Remove references to unsupported OS and Xcode versions.
-
- Reviewed by Anders Carlsson.
-
- * Configurations/Base.xcconfig:
- * Configurations/CompilerVersion.xcconfig: Removed.
- * Configurations/DebugRelease.xcconfig:
- * Configurations/Version.xcconfig:
- * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2012-10-29 Michael Saboff <msaboff@apple.com>
-
- Non-special escape character sequences cause JSC::Lexer::parseString to create 16 bit strings
- https://bugs.webkit.org/show_bug.cgi?id=100576
-
- Reviewed by Darin Adler.
-
- Changed singleEscape() processing to be based on a lookup of a static table. The table
- covers ASCII characters SPACE through DEL. If a character can be a single character escape,
- then the table provides the non-zero result of that escape. Updated the result of
- singleEscape to be an LChar to make the table as small as possible.
- Added a new test fast/js/normal-character-escapes-in-string-literals.html to validated
- the behavior.
-
- * parser/Lexer.cpp:
- (JSC::singleEscape):
- (JSC::Lexer::parseString):
- (JSC::Lexer::parseStringSlowCase):
-
-2012-10-29 Enrica Casucci <enrica@apple.com>
-
- Add ENABLE_USERSELECT_ALL feature flag.
- https://bugs.webkit.org/show_bug.cgi?id=100559
-
- Reviewed by Eric Seidel.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-28 Filip Pizlo <fpizlo@apple.com>
-
- DFG should be able to emit effectful structure checks
- https://bugs.webkit.org/show_bug.cgi?id=99260
-
- Reviewed by Oliver Hunt.
-
- This change allows us to find out if an array access that has gone polymorphic
- is operating over known structures - i.e. the primordial array structures of the
- global object that the code block containing the array access belongs to. We
- term this state "OriginalArray" for short. The fact that the access has gone
- polymorphic means that the array profile will not be able to report the set of
- structures it had seen - but if it can tell us that all of the structures were
- primordial then it just so happens that we can deduce what the structure set
- would have been by just querying the code block's global object. This allows us
- to emit an ArrayifyToStructure instead of an Arrayify if we find that we need to
- do conversions. The fast path of an ArrayifyToStructure is exactly like the fast
- path of a CheckStructure and is mostly subject to the same optimizations. It
- also burns one fewer registers.
-
- Essentially the notion of OriginalArray is a super cheap way of getting the
- array profile to tell us a structure set instead of a singleton structure.
- Currently, the array profile can only tell us the structure seen at an array
- access if there was exactly one structure. If there were multiple structures, it
- won't tell us anything other than the array modes and other auxiliary profiling
- data (whether there were stores to holes, for example). With OriginalArray, we
- cheaply get a structure set if all of the structures were primordial for the
- code block's global object, since in that case the array mode set (ArrayModes)
- can directly tell us the structure set. In the future, we might consider adding
- complete structure sets to the array profiles, but I suspect that we would hit
- diminishing returns if we did so - it would only help if we have array accesses
- that are both polymorphic and are cross-global-object accesses (rare) or if the
- arrays had named properties or other structure transitions that are unrelated to
- indexing type (also rare).
-
- This also does away with Arrayify (and the new ArrayifyToStructure) returning
- the butterfly pointer. This turns out to be faster and easier to CSE.
-
- And, this also changes constant folding to be able to eliminate CheckStructure,
- ForwardCheckStructure, and ArrayifyToStructure in addition to being able to
- transform them into structure transition watchpoints. This is great for
- ArrayifyToStructure because then CSE and CFA know that there is no side effect.
- Converting CheckStructure and ForwardCheckStructure to also behave this way is
- just a matter of elegance.
-
- This has no performance impact right now. It's intended to alleviate some of the
- regressions seen in the early implementation of
- https://bugs.webkit.org/show_bug.cgi?id=98606.
-
- * bytecode/ArrayProfile.cpp:
- (JSC::ArrayProfile::computeUpdatedPrediction):
- * bytecode/ArrayProfile.h:
- (JSC):
- (JSC::ArrayProfile::ArrayProfile):
- (ArrayProfile):
- (JSC::ArrayProfile::usesOriginalArrayStructures):
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::ArrayMode::fromObserved):
- (JSC::DFG::ArrayMode::alreadyChecked):
- (JSC::DFG::arrayClassToString):
- * dfg/DFGArrayMode.h:
- (JSC::DFG::ArrayMode::withProfile):
- (JSC::DFG::ArrayMode::isJSArray):
- (ArrayMode):
- (JSC::DFG::ArrayMode::isJSArrayWithOriginalStructure):
- (JSC::DFG::ArrayMode::supportsLength):
- (JSC::DFG::ArrayMode::arrayModesWithIndexingShape):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::getArrayMode):
- (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
- (JSC::DFG::ByteCodeParser::handleGetByOffset):
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::checkStructureElimination):
- (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
- (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
- (JSC::DFG::CSEPhase::checkArrayElimination):
- (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- (JSC::DFG::FixupPhase::checkArray):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::hasStructure):
- (JSC::DFG::Node::hasArrayMode):
- (JSC::DFG::Node::arrayMode):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
- (JSC::DFG::SpeculativeJIT::arrayify):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * runtime/JSGlobalObject.h:
- (JSC::JSGlobalObject::isOriginalArrayStructure):
- * runtime/Structure.cpp:
- (JSC::Structure::nonPropertyTransition):
-
-2012-10-28 Filip Pizlo <fpizlo@apple.com>
-
- There should not be blind spots in array length array profiling
- https://bugs.webkit.org/show_bug.cgi?id=100620
-
- Reviewed by Oliver Hunt.
-
- I don't think this has any performance impact. But it's good to not have random
- programs occasionally emit a GetById for array length accesses.
-
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::compileGetByIdHotPath):
- (JSC::JIT::privateCompilePatchGetArrayLength):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::compileGetByIdHotPath):
- (JSC::JIT::privateCompilePatchGetArrayLength):
-
-2012-10-28 Filip Pizlo <fpizlo@apple.com>
-
- Unreviewed, make always-true enum-to-int comparisons use casts.
-
- * dfg/DFGFPRInfo.h:
- (JSC::DFG::FPRInfo::debugName):
- * dfg/DFGGPRInfo.h:
- (JSC::DFG::JSValueSource::tagGPR):
- (JSC::DFG::GPRInfo::toIndex):
- (JSC::DFG::GPRInfo::debugName):
- * runtime/JSTypeInfo.h:
- (JSC::TypeInfo::TypeInfo):
-
-2012-10-27 Filip Pizlo <fpizlo@apple.com>
-
- OSR exit compilation should defend against argument recoveries from code blocks that are no longer on the inline stack
- https://bugs.webkit.org/show_bug.cgi?id=100601
-
- Reviewed by Oliver Hunt.
-
- This happened to me while I was fixing bugs for https://bugs.webkit.org/show_bug.cgi?id=100599.
- I'm not sure how to reproduce this.
-
- * dfg/DFGAssemblyHelpers.h:
- (JSC::DFG::AssemblyHelpers::baselineCodeBlockFor):
- (AssemblyHelpers):
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
-
-2012-10-27 Filip Pizlo <fpizlo@apple.com>
-
- DFG::Array::Mode needs to be cleaned up
- https://bugs.webkit.org/show_bug.cgi?id=100599
-
- Reviewed by Oliver Hunt.
-
- Turn the previous massive Array::Mode enum into a class that contains four
- fields, the type, whether it's a JSArray, the level of speculation, and the
- kind of conversion to perform.
-
- No performance or behavioral change.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArgumentsSimplificationPhase.cpp:
- (JSC::DFG::ArgumentsSimplificationPhase::run):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::ArrayMode::fromObserved):
- (JSC::DFG::ArrayMode::refine):
- (JSC::DFG::ArrayMode::alreadyChecked):
- (JSC::DFG::arrayTypeToString):
- (JSC::DFG::arrayClassToString):
- (DFG):
- (JSC::DFG::arraySpeculationToString):
- (JSC::DFG::arrayConversionToString):
- (JSC::DFG::ArrayMode::toString):
- * dfg/DFGArrayMode.h:
- (DFG):
- (ArrayMode):
- (JSC::DFG::ArrayMode::ArrayMode):
- (JSC::DFG::ArrayMode::type):
- (JSC::DFG::ArrayMode::arrayClass):
- (JSC::DFG::ArrayMode::speculation):
- (JSC::DFG::ArrayMode::conversion):
- (JSC::DFG::ArrayMode::asWord):
- (JSC::DFG::ArrayMode::fromWord):
- (JSC::DFG::ArrayMode::withSpeculation):
- (JSC::DFG::ArrayMode::usesButterfly):
- (JSC::DFG::ArrayMode::isJSArray):
- (JSC::DFG::ArrayMode::isInBounds):
- (JSC::DFG::ArrayMode::mayStoreToHole):
- (JSC::DFG::ArrayMode::isOutOfBounds):
- (JSC::DFG::ArrayMode::isSlowPut):
- (JSC::DFG::ArrayMode::canCSEStorage):
- (JSC::DFG::ArrayMode::lengthNeedsStorage):
- (JSC::DFG::ArrayMode::modeForPut):
- (JSC::DFG::ArrayMode::isSpecific):
- (JSC::DFG::ArrayMode::supportsLength):
- (JSC::DFG::ArrayMode::benefitsFromStructureCheck):
- (JSC::DFG::ArrayMode::doesConversion):
- (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
- (JSC::DFG::ArrayMode::operator==):
- (JSC::DFG::ArrayMode::operator!=):
- (JSC::DFG::ArrayMode::arrayModesWithIndexingShape):
- (JSC::DFG::canCSEStorage):
- (JSC::DFG::lengthNeedsStorage):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::getArrayMode):
- (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
- (JSC::DFG::ByteCodeParser::handleIntrinsic):
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::getArrayLengthElimination):
- (JSC::DFG::CSEPhase::checkArrayElimination):
- (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
- (JSC::DFG::CSEPhase::performNodeCSE):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- (JSC::DFG::FixupPhase::checkArray):
- (JSC::DFG::FixupPhase::blessArrayOperation):
- * dfg/DFGGraph.cpp:
- (JSC::DFG::Graph::dump):
- * dfg/DFGGraph.h:
- (JSC::DFG::Graph::byValIsPure):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::arrayMode):
- (JSC::DFG::Node::setArrayMode):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
- (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::arrayify):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
- (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
- (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
- (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
- (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
- (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
- (SpeculativeJIT):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-27 Dan Bernstein <mitz@apple.com>
-
- REAL_PLATFORM_NAME build setting is no longer needed
- https://bugs.webkit.org/show_bug.cgi?id=100587
-
- Reviewed by Mark Rowe.
-
- Removed the definition of REAL_PLATFORM_NAME and replaced references to it with references
- to PLATFORM_NAME.
-
- * Configurations/Base.xcconfig:
- * Configurations/CompilerVersion.xcconfig:
- * Configurations/DebugRelease.xcconfig:
- * Configurations/FeatureDefines.xcconfig:
- * Configurations/JSC.xcconfig:
- * Configurations/JavaScriptCore.xcconfig:
- * Configurations/ToolExecutable.xcconfig:
-
-2012-10-25 Filip Pizlo <fpizlo@apple.com>
-
- Forward OSR calculation is wrong in the presence of multiple SetLocals, or a mix of SetLocals and Phantoms
- https://bugs.webkit.org/show_bug.cgi?id=100461
-
- Reviewed by Oliver Hunt and Gavin Barraclough.
-
- This does a couple of things. First, it removes the part of the change in r131822 that made the forward
- OSR exit calculator capable of handling multiple SetLocals. That change was wrong, because it would
- blindly assume that all SetLocals had the same ValueRecovery, and would ignore the possibility that if
- there is no value recovery then a ForwardCheckStructure on the first SetLocal would not know how to
- recover the state associated with the second SetLocal. Then, it introduces the invariant that any bytecode
- op that decomposes into multiple SetLocals must first emit dead SetLocals as hints and then emit a second
- set of SetLocals to actually do the setting of the locals. This means that if a ForwardCheckStructure (or
- any other hoisted forward speculation) is inserted, it will always be inserted on the second set of
- SetLocals (since hoisting only touches the live ones), at which point OSR will already know about the
- mov hints implied by the first set of (dead) SetLocals. This gives us the behavior we wanted, namely, that
- a ForwardCheckStructure applied to a variant set by a resolve_with_base-like operation can correctly do a
- forward exit while also ensuring that prior to exiting we set the appropriate locals.
-
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGOSRExit.cpp:
- (JSC::DFG::OSRExit::OSRExit):
- * dfg/DFGOSRExit.h:
- (OSRExit):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
-
-2012-10-26 Simon Hausmann <simon.hausmann@digia.com>
-
- [Qt] Fix the LLInt build on Windows
- https://bugs.webkit.org/show_bug.cgi?id=97648
-
- Reviewed by Tor Arne Vestbø.
-
- The main change for the port on Windows is changing the way offsets are extracted
- and the LLIntAssembly.h is generated to accomodate release and debug configurations.
-
- Firstly the LLIntOffsetsExtractor binary is now built as-is (no DESTDIR set) and
- placed into debug\LLIntOffsetsExtractor.exe and release\LLIntOffsetsExtractor.exe
- on Windows debug_and_release builds. On other patforms it remainds in the regular
- out directory.
-
- Secondly the LLIntAssembly.h files must be different for different build types,
- so the LLIntAssembly.h generator in DerivedSources.pri operates no on the extractor
- binary files as input. Using a simple exists() check we verify the presence of either
- a regular, a debug\LLIntOffsetsExtractor and a release\LLIntOffsetsExtractor binary
- and process all of them. The resulting assembly files consequently end up in
- generated\debug\LLIntAssembly.h and generated\release\LLIntAssembly.h.
-
- In Target.pri we have to also make sure that those directories are in the include
- path according to the release or debug configuration.
-
- Lastly a small tweak - swapping WTF.pri and JSC.pri inclusions - in the
- LLIntOffsetsExtractor build was needed to make sure that we include
- JavaScriptCore/config.h instead of WTF/config.h, required to fix the
- build issues originally pasted in bug #97648.
-
- * DerivedSources.pri:
- * JavaScriptCore.pro:
- * LLIntOffsetsExtractor.pro:
- * Target.pri:
-
-2012-10-26 Gabor Ballabas <gaborb@inf.u-szeged.hu>
-
- [Qt] Enable JSC's disassembler on x86, x86_64 Linux
- https://bugs.webkit.org/show_bug.cgi?id=100386
-
- Reviewed by Simon Hausmann.
-
- It works fine on Linux x86, x86_64 just needs to be enabled in the
- QtWebKit build system.
-
- * DerivedSources.pri:
- * JavaScriptCore.pri:
- * Target.pri:
-
-2012-10-26 Thiago Marcos P. Santos <thiago.santos@intel.com>
-
- Add feature flags for CSS Device Adaptation
- https://bugs.webkit.org/show_bug.cgi?id=95960
-
- Reviewed by Kenneth Rohde Christiansen.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-26 Simon Hausmann <simon.hausmann@digia.com>
-
- [WIN] Make LLInt offsets extractor work on Windows
- https://bugs.webkit.org/show_bug.cgi?id=100369
-
- Reviewed by Kenneth Rohde Christiansen.
-
- Open the input file explicitly in binary mode to prevent ruby/Windows from thinking that
- it's a text mode file that needs even new line conversions. The binary mode parameter is
- ignored on other platforms.
-
- * offlineasm/offsets.rb:
-
-2012-10-25 Michael Saboff <msaboff@apple.com>
-
- SymbolTableIndexHashTraits::needsDestruction should be set to true
- https://bugs.webkit.org/show_bug.cgi?id=100437
-
- Reviewed by Mark Hahnenberg.
-
- For correctness, set SymbolTableIndexHashTraits::needsDestruction to true since SymbolTableEntry's do
- need to have their destructor called due to the possibility of rare data.
-
- * runtime/SymbolTable.h:
- (SymbolTableIndexHashTraits):
-
-2012-10-25 Filip Pizlo <fpizlo@apple.com>
-
- DFG Arrayify elimination should replace it with GetButterfly rather than Phantom
- https://bugs.webkit.org/show_bug.cgi?id=100441
-
- Reviewed by Oliver Hunt and Gavin Barraclough.
-
- Made array profiler's to-string helper behave correctly.
-
- Made Arrayify elimination do the right thing (convert to GetButterfly).
-
- Made CFA's interference analysis track clobbered array modes correctly, mostly by
- simplifying the machinery.
-
- * bytecode/ArrayProfile.cpp:
- (JSC::arrayModesToString):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::clobberArrayModes):
- (AbstractValue):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
-
-2012-10-25 Filip Pizlo <fpizlo@apple.com>
-
- REGRESSION (r131793-r131826): Crash going to wikifonia.org
- https://bugs.webkit.org/show_bug.cgi?id=100281
-
- Reviewed by Oliver Hunt.
-
- Restore something that got lost in the resolve refactoring: the ability to give up on life if
- we see a resolve of 'arguments'.
-
- * runtime/JSScope.cpp:
- (JSC::JSScope::resolveContainingScopeInternal):
-
-2012-10-25 Dominik Röttsches <dominik.rottsches@intel.com>
-
- Conditionalize XHR timeout support
- https://bugs.webkit.org/show_bug.cgi?id=100356
-
- Reviewed by Adam Barth.
-
- Adding XHR_TIMEOUT feature to conditionalize this on ports without network backend support.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-25 Michael Saboff <msaboff@apple.com>
-
- REGRESSION (r131836): failures in list styles tests on EFL, GTK
- https://bugs.webkit.org/show_bug.cgi?id=99824
-
- Reviewed by Oliver Hunt.
-
- Saved start of string since it is modified by call convertUTF8ToUTF16().
-
- * API/JSStringRef.cpp:
- (JSStringCreateWithUTF8CString):
-
-2012-10-24 Filip Pizlo <fpizlo@apple.com>
-
- DFG NewArrayBuffer node should keep its data in a structure on the side to free up one of the opInfos
- https://bugs.webkit.org/show_bug.cgi?id=100328
-
- Reviewed by Oliver Hunt.
-
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGGraph.h:
- (Graph):
- * dfg/DFGNode.h:
- (NewArrayBufferData):
- (DFG):
- (JSC::DFG::Node::newArrayBufferData):
- (Node):
- (JSC::DFG::Node::startConstant):
- (JSC::DFG::Node::numConstants):
-
-2012-10-25 Mark Lam <mark.lam@apple.com>
-
- Update the C++ llint to work with the latest op_resolve... changes.
- https://bugs.webkit.org/show_bug.cgi?id=100345.
-
- Reviewed by Oliver Hunt.
-
- * llint/LowLevelInterpreter.cpp:
- (JSC::CLoop::execute):
- - emit opcode name as label when not using COMPUTED_GOTOs. The new op_resolve
- opcodes have jumps to these labels.
- - declare all opcode labels as UNUSED_LABEL()s to keep the compiler happy
- for opcodes that are not referenced by anyone.
- * offlineasm/asm.rb:
- - strip llint_ prefix from opcode names used as labels.
-
-2012-10-24 Yuqiang Xian <yuqiang.xian@intel.com>
-
- Refactor LLInt64 to distinguish the pointer operations from the 64-bit integer operations
- https://bugs.webkit.org/show_bug.cgi?id=100321
-
- Reviewed by Filip Pizlo.
-
- We have refactored the MacroAssembler and JIT compilers to distinguish
- the pointer operations from the 64-bit integer operations (see bug #99154).
- Now we want to do the similar work for LLInt, and the goal is same as
- the one mentioned in 99154.
-
- This is the first part of the modification: in the offline assembler,
- adding the support of the "<foo>q" instructions which will be used for
- 64-bit integer operations.
-
- * llint/LowLevelInterpreter.cpp:
- (JSC::CLoop::execute):
- * offlineasm/cloop.rb:
- * offlineasm/instructions.rb:
- * offlineasm/x86.rb:
-
-2012-10-24 Filip Pizlo <fpizlo@apple.com>
-
- DFG compileBlahBlahByVal methods for Contiguous and ArrayStorage have only one caller and should be removed
- https://bugs.webkit.org/show_bug.cgi?id=100311
-
- Reviewed by Mark Hahnenberg.
-
- Just trying to simplify things before I make them more complicated again.
-
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (DFG):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (DFG):
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-23 Andreas Kling <kling@webkit.org>
-
- CodeBlock: Give m_putToBaseOperations an inline capacity.
- <http://webkit.org/b/100190>
- <rdar://problem/12562466>
-
- Reviewed by Oliver Hunt.
-
- Since the CodeBlock constructor always inserts a single PutToBaseOperation, but there's no
- guarantee that more will follow, give the m_putToBaseOperations vector an inline capacity of 1.
- There are 4009 of these Vectors on Membuster3, and only 126 of them have more than a single entry.
-
- This change yields a 1.90MB reduction in memory usage.
-
- * bytecode/CodeBlock.h:
- (CodeBlock):
-
-2012-10-23 Christophe Dumez <christophe.dumez@intel.com>
-
- Regression(r132143): Assertion hit in JSC::Interpreter::StackPolicy::StackPolicy(JSC::Interpreter&, const WTF::StackBounds&)
- https://bugs.webkit.org/show_bug.cgi?id=100109
-
- Reviewed by Oliver Hunt.
-
- Fix possible integer overflow in StackPolicy constructor by
- using size_t type instead of int for stack sizes. The value
- returned by StackBounds::size() is of type size_t but was
- assigned to an int, which may overflow.
-
- * interpreter/Interpreter.cpp:
- (JSC):
- (JSC::Interpreter::StackPolicy::StackPolicy):
-
-2012-10-23 Carlos Garcia Campos <cgarcia@igalia.com>
-
- Unreviewed. Fix make distcheck.
-
- * GNUmakefile.list.am: Add missing header file.
-
-2012-10-23 Mark Lam <mark.lam@apple.com>
-
- Make topCallFrame reliable.
- https://bugs.webkit.org/show_bug.cgi?id=98928.
-
- Reviewed by Geoffrey Garen.
-
- - VM entry points and the GC now uses topCallFrame.
- - The callerFrame value in CallFrames are now always the previous
- frame on the stack, except for the first frame which has a
- callerFrame of 0 (not counting the HostCallFrameFlag).
- Hence, we can now traverse every frame on the stack all the way
- back to the first frame.
- - GlobalExec's will no longer be used as the callerFrame values in
- call frames.
- - Added fences and traps for debugging the JSStack in debug builds.
-
- * bytecode/SamplingTool.h:
- (SamplingTool):
- (JSC::SamplingTool::CallRecord::CallRecord):
- * dfg/DFGOperations.cpp:
- - Fixed 2 DFG helper functions to flush topCallFrame as expected.
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::prepareForExternalCall):
- * interpreter/CallFrame.h:
- (JSC::ExecState::callerFrameNoFlags):
- (ExecState):
- (JSC::ExecState::argIndexForRegister):
- (JSC::ExecState::getArgumentUnsafe):
- * interpreter/CallFrameClosure.h:
- (CallFrameClosure):
- * interpreter/Interpreter.cpp:
- (JSC):
- (JSC::eval):
- (JSC::Interpreter::Interpreter):
- (JSC::Interpreter::throwException):
- (JSC::Interpreter::execute):
- (JSC::Interpreter::executeCall):
- (JSC::Interpreter::executeConstruct):
- (JSC::Interpreter::prepareForRepeatCall):
- (JSC::Interpreter::endRepeatCall):
- * interpreter/Interpreter.h:
- (JSC):
- (Interpreter):
- * interpreter/JSStack.cpp:
- (JSC::JSStack::JSStack):
- (JSC::JSStack::gatherConservativeRoots):
- (JSC::JSStack::disableErrorStackReserve):
- * interpreter/JSStack.h:
- (JSC):
- (JSStack):
- (JSC::JSStack::installFence):
- (JSC::JSStack::validateFence):
- (JSC::JSStack::installTrapsAfterFrame):
- * interpreter/JSStackInlines.h: Added.
- (JSC):
- (JSC::JSStack::getTopOfFrame):
- (JSC::JSStack::getTopOfStack):
- (JSC::JSStack::getStartOfFrame):
- (JSC::JSStack::pushFrame):
- (JSC::JSStack::popFrame):
- (JSC::JSStack::generateFenceValue):
- (JSC::JSStack::installFence):
- (JSC::JSStack::validateFence):
- (JSC::JSStack::installTrapsAfterFrame):
- * jit/JITStubs.cpp:
- (JSC::jitCompileFor):
- (JSC::lazyLinkFor):
- - Set frame->codeBlock to 0 for both the above because they are called
- with partially intitialized frames (cb uninitialized), but may
- trigger a GC.
- (JSC::DEFINE_STUB_FUNCTION):
- * runtime/JSGlobalData.cpp:
- (JSC::JSGlobalData::JSGlobalData):
-
-2012-10-22 Filip Pizlo <fpizlo@apple.com>
-
- DFG::Array::Undecided should be called DFG::Array::SelectUsingPredictions
- https://bugs.webkit.org/show_bug.cgi?id=100052
-
- Reviewed by Oliver Hunt.
-
- No functional change, just renaming. It's a clearer name that more accurately
- reflects the meaning, and it eliminates the namespace confusion that will happen
- with the Undecided indexing type in https://bugs.webkit.org/show_bug.cgi?id=98606
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::fromObserved):
- (JSC::DFG::refineArrayMode):
- (JSC::DFG::modeAlreadyChecked):
- (JSC::DFG::modeToString):
- * dfg/DFGArrayMode.h:
- (JSC::DFG::canCSEStorage):
- (JSC::DFG::modeIsSpecific):
- (JSC::DFG::modeSupportsLength):
- (JSC::DFG::benefitsFromStructureCheck):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- (JSC::DFG::FixupPhase::blessArrayOperation):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::arrayify):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-22 Mark Lam <mark.lam@apple.com>
-
- Change stack recursion checks to be based on stack availability.
- https://bugs.webkit.org/show_bug.cgi?id=99872.
-
- Reviewed by Filip Pizlo and Geoffrey Garen.
-
- - Remove m_reentryDepth, ThreadStackType which are now obsolete.
- - Replaced the reentryDepth checks with a StackBounds check.
- - Added the Interpreter::StackPolicy class to compute a reasonable
- stack capacity requirement given the native stack that the
- interpreter is executing on at that time.
- - Reserved an amount of JSStack space for the use of error handling
- and enable its use (using Interpreter::ErrorHandlingMode) when
- we're about to throw or report an exception.
- - Interpreter::StackPolicy also allows more native stack space
- to be used when in ErrorHandlingMode. This is needed in the case
- of native stack overflows.
- - Fixed the parser so that it throws a StackOverflowError instead of
- a SyntaxError when it encounters a stack overflow.
-
- * API/JSContextRef.cpp:
- (JSContextGroupCreate):
- (JSGlobalContextCreateInGroup):
- * JavaScriptCore.order:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::ErrorHandlingMode::ErrorHandlingMode):
- (JSC):
- (JSC::Interpreter::ErrorHandlingMode::~ErrorHandlingMode):
- (JSC::Interpreter::StackPolicy::StackPolicy):
- (JSC::Interpreter::Interpreter):
- (JSC::Interpreter::execute):
- (JSC::Interpreter::executeCall):
- (JSC::Interpreter::executeConstruct):
- (JSC::Interpreter::prepareForRepeatCall):
- * interpreter/Interpreter.h:
- (JSC):
- (Interpreter):
- (ErrorHandlingMode):
- (StackPolicy):
- (JSC::Interpreter::StackPolicy::requiredCapacity):
- * interpreter/JSStack.cpp:
- (JSC):
- (JSC::JSStack::JSStack):
- (JSC::JSStack::growSlowCase):
- (JSC::JSStack::enableErrorStackReserve):
- (JSC::JSStack::disableErrorStackReserve):
- * interpreter/JSStack.h:
- (JSStack):
- (JSC::JSStack::reservationEnd):
- (JSC):
- * jsc.cpp:
- (jscmain):
- * parser/Parser.cpp:
- (JSC::::Parser):
- * parser/Parser.h:
- (Parser):
- (JSC::::parse):
- * runtime/ExceptionHelpers.cpp:
- (JSC::throwStackOverflowError):
- * runtime/JSGlobalData.cpp:
- (JSC::JSGlobalData::JSGlobalData):
- (JSC::JSGlobalData::createContextGroup):
- (JSC::JSGlobalData::create):
- (JSC::JSGlobalData::createLeaked):
- (JSC::JSGlobalData::sharedInstance):
- * runtime/JSGlobalData.h:
- (JSC):
- (JSGlobalData):
- * runtime/StringRecursionChecker.h:
- (JSC::StringRecursionChecker::performCheck):
- * testRegExp.cpp:
- (realMain):
-
-2012-10-20 Martin Robinson <mrobinson@igalia.com>
-
- Fix 'make dist' for the GTK+ port
-
- * GNUmakefile.list.am: Add missing files to the source list.
-
-2012-10-21 Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
-
- [CMake][JSC] Depend on risc.rb to decide when to run the LLInt scripts.
- https://bugs.webkit.org/show_bug.cgi?id=99917
-
- Reviewed by Geoffrey Garen.
-
- Depend on the newly-added risc.rb to make sure we always run the
- LLInt scripts when one of them changes.
-
- * CMakeLists.txt:
-
-2012-10-20 Filip Pizlo <fpizlo@apple.com>
-
- LLInt backends of non-ARM RISC platforms should be able to share code with the existing ARMv7 backend
- https://bugs.webkit.org/show_bug.cgi?id=99745
-
- Reviewed by Geoffrey Garen.
-
- This moves all of the things in armv7.rb that I thought are generally useful out
- into risc.rb. It also separates some phases (branch ops is separated into one
- phase that does sensible things, and another that does things that are painfully
- ARM-specific), and removes ARM assumptions from others by using a callback to
- drive exactly what lowering must happen. The goal here is to minimize the future
- maintenance burden of LLInt by ensuring that the various platforms share as much
- lowering code as possible.
-
- * offlineasm/armv7.rb:
- * offlineasm/risc.rb: Added.
-
-2012-10-19 Filip Pizlo <fpizlo@apple.com>
-
- DFG should have some facility for recognizing redundant CheckArrays and Arrayifies
- https://bugs.webkit.org/show_bug.cgi?id=99287
-
- Reviewed by Mark Hahnenberg.
-
- Adds reasoning about indexing type sets (i.e. ArrayModes) to AbstractValue, which
- then enables us to fold away CheckArray's and Arrayify's that are redundant.
-
- * bytecode/ArrayProfile.cpp:
- (JSC::arrayModesToString):
- (JSC):
- * bytecode/ArrayProfile.h:
- (JSC):
- (JSC::mergeArrayModes):
- (JSC::arrayModesAlreadyChecked):
- * bytecode/StructureSet.h:
- (JSC::StructureSet::arrayModesFromStructures):
- (StructureSet):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGAbstractValue.h:
- (JSC::DFG::AbstractValue::AbstractValue):
- (JSC::DFG::AbstractValue::clear):
- (JSC::DFG::AbstractValue::isClear):
- (JSC::DFG::AbstractValue::makeTop):
- (JSC::DFG::AbstractValue::clobberStructures):
- (AbstractValue):
- (JSC::DFG::AbstractValue::setMostSpecific):
- (JSC::DFG::AbstractValue::set):
- (JSC::DFG::AbstractValue::operator==):
- (JSC::DFG::AbstractValue::merge):
- (JSC::DFG::AbstractValue::filter):
- (JSC::DFG::AbstractValue::filterArrayModes):
- (JSC::DFG::AbstractValue::validate):
- (JSC::DFG::AbstractValue::checkConsistency):
- (JSC::DFG::AbstractValue::dump):
- (JSC::DFG::AbstractValue::clobberArrayModes):
- (JSC::DFG::AbstractValue::clobberArrayModesSlow):
- (JSC::DFG::AbstractValue::setFuturePossibleStructure):
- (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::modeAlreadyChecked):
- * dfg/DFGArrayMode.h:
- (JSC::DFG::arrayModesFor):
- (DFG):
- * dfg/DFGConstantFoldingPhase.cpp:
- (JSC::DFG::ConstantFoldingPhase::foldConstants):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::arrayify):
-
-2012-10-19 Filip Pizlo <fpizlo@apple.com>
-
- Baseline JIT should not inline array allocations, to make them easier to instrument
- https://bugs.webkit.org/show_bug.cgi?id=99905
-
- Reviewed by Mark Hahnenberg.
-
- This will make it easier to instrument array allocations for the purposes of profiling.
- It also allows us to kill off a bunch of code. And, this doesn't appear to hurt
- performance at all. That's expected because these days any hot allocation will end up
- in the DFG JIT, which does inline these allocations.
-
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileSlowCases):
- * jit/JIT.h:
- (JIT):
- * jit/JITInlineMethods.h:
- (JSC):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_new_array):
-
-2012-10-19 Oliver Hunt <oliver@apple.com>
-
- Fix some of the regression cause by the non-local variable reworking
- https://bugs.webkit.org/show_bug.cgi?id=99896
-
- Reviewed by Filip Pizlo.
-
- The non0local variable reworking led to some of the optimisations performed by
- the bytecode generator being dropped. This in turn put more pressure on the DFG
- optimisations. This exposed a short coming in our double speculation propogation.
- Now we try to distinguish between places where we should SpecDoubleReal vs generic
- SpecDouble.
-
- * dfg/DFGPredictionPropagationPhase.cpp:
- (PredictionPropagationPhase):
- (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
- (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPredictions):
- (JSC::DFG::PredictionPropagationPhase::propagate):
-
-2012-10-19 Michael Saboff <msaboff@apple.com>
-
- Lexer should create 8 bit Identifiers for RegularExpressions and ASCII identifiers
- https://bugs.webkit.org/show_bug.cgi?id=99855
-
- Reviewed by Filip Pizlo.
-
- Added makeIdentifier helpers that will always make an 8 bit Identifier or make an
- Identifier that is the same size as the template parameter. Used the first in the fast
- path when looking for a JS identifier and the second when scanning regular expressions.
-
- * parser/Lexer.cpp:
- (JSC::::scanRegExp):
- * parser/Lexer.h:
- (Lexer):
- (JSC::::makeIdentifierSameType):
- (JSC::::makeLCharIdentifier):
- (JSC::::lexExpectIdentifier):
-
-2012-10-19 Mark Lam <mark.lam@apple.com>
-
- Added WTF::StackStats mechanism.
- https://bugs.webkit.org/show_bug.cgi?id=99805.
-
- Reviewed by Geoffrey Garen.
-
- Added StackStats checkpoints and probes.
-
- * bytecompiler/BytecodeGenerator.h:
- (JSC::BytecodeGenerator::emitNode):
- (JSC::BytecodeGenerator::emitNodeInConditionContext):
- * heap/SlotVisitor.cpp:
- (JSC::SlotVisitor::append):
- (JSC::visitChildren):
- (JSC::SlotVisitor::donateKnownParallel):
- (JSC::SlotVisitor::drain):
- (JSC::SlotVisitor::drainFromShared):
- (JSC::SlotVisitor::mergeOpaqueRoots):
- (JSC::SlotVisitor::internalAppend):
- (JSC::SlotVisitor::harvestWeakReferences):
- (JSC::SlotVisitor::finalizeUnconditionalFinalizers):
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::execute):
- (JSC::Interpreter::executeCall):
- (JSC::Interpreter::executeConstruct):
- (JSC::Interpreter::prepareForRepeatCall):
- * parser/Parser.h:
- (JSC::Parser::canRecurse):
- * runtime/StringRecursionChecker.h:
- (StringRecursionChecker):
-
-2012-10-19 Oliver Hunt <oliver@apple.com>
-
- REGRESSION(r131822): It made 500+ tests crash on 32 bit platforms
- https://bugs.webkit.org/show_bug.cgi?id=99814
-
- Reviewed by Filip Pizlo.
-
- Call the correct macro in 32bit.
-
- * llint/LowLevelInterpreter.asm:
-
-2012-10-19 Dongwoo Joshua Im <dw.im@samsung.com>
-
- Rename ENABLE_CSS3_TEXT_DECORATION to ENABLE_CSS3_TEXT
- https://bugs.webkit.org/show_bug.cgi?id=99804
-
- Reviewed by Julien Chaffraix.
-
- CSS3 text related properties will be implemented under this flag,
- including text decoration, text-align-last, and text-justify.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-18 Anders Carlsson <andersca@apple.com>
-
- Clean up RegExpKey
- https://bugs.webkit.org/show_bug.cgi?id=99798
-
- Reviewed by Darin Adler.
-
- RegExpHash doesn't need to be a class template specialization when the class template is specialized
- for JSC::RegExpKey only. Make it a nested class of RegExp instead. Also, make operator== a friend function
- so Hash::equal can see it.
-
- * runtime/RegExpKey.h:
- (JSC::RegExpKey::RegExpKey):
- (JSC::RegExpKey::operator==):
- (RegExpKey):
- (JSC::RegExpKey::Hash::hash):
- (JSC::RegExpKey::Hash::equal):
- (Hash):
-
-2012-10-19 Mark Lam <mark.lam@apple.com>
-
- Bot greening: Follow up to r131877 to fix the Windows build.
- https://bugs.webkit.org/show_bug.cgi?id=99739.
-
- Not reviewed.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-10-19 Mark Lam <mark.lam@apple.com>
-
- Bot greening: Attempt to fix broken Window build after r131836.
- https://bugs.webkit.org/show_bug.cgi?id=99739.
-
- Not reviewed.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-10-19 Yuqiang Xian <yuqiang.xian@intel.com>
-
- Unreviewed fix after r131868.
-
- On JSVALUE64 platforms, JSValue constants can be Imm64 instead of ImmPtr for JIT compilers.
-
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
-
-2012-10-18 Filip Pizlo <fpizlo@apple.com>
-
- Baseline array profiling should be less accurate, and DFG OSR exit should update array profiles on CheckArray and CheckStructure failure
- https://bugs.webkit.org/show_bug.cgi?id=99261
-
- Reviewed by Oliver Hunt.
-
- This makes array profiling stochastic, like value profiling. The point is to avoid
- noticing one-off indexing types that we'll never see again, but instead to:
-
- Notice the big ones: We want the DFG to compile based on the things that happen with
- high probability. So, this change makes array profiling do like value profiling and
- only notice a random subsampling of indexing types that flowed through an array
- access. Prior to this patch array profiles noticed all indexing types and weighted
- them identically.
-
- Bias the recent: Often an array access will see awkward indexing types during the
- first handful of executions because of artifacts of program startup. So, we want to
- bias towards the indexing types that we saw most recently. With this change, array
- profiling does like value profiling and usually tells use a random sampling that
- is biased to what happened recently.
-
- Have a backup plan: The above two things don't work by themselves because our
- randomness is not that random (nor do we care enough to make it more random), and
- because some procedures will have a <1/10 probability event that we must handle
- without bailing because it dominates a hot loop. So, like value profiling, this
- patch makes array profiling use OSR exits to tell us why we are bailing out, so
- that we don't make the same mistake again in the future.
-
- This change also makes the way that the 32-bit OSR exit compiler snatches scratch
- registers more uniform. We don't need a scratch buffer when we can push and pop.
-
- * bytecode/DFGExitProfile.h:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::arrayify):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * jit/JITInlineMethods.h:
- (JSC::JIT::emitArrayProfilingSite):
- * llint/LowLevelInterpreter.asm:
-
-2012-10-18 Yuqiang Xian <yuqiang.xian@intel.com>
-
- [Qt] REGRESSION(r131858): It broke the ARM build
- https://bugs.webkit.org/show_bug.cgi?id=99809
-
- Reviewed by Csaba Osztrogonác.
-
- * dfg/DFGCCallHelpers.h:
- (CCallHelpers):
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
-
-2012-10-18 Yuqiang Xian <yuqiang.xian@intel.com>
-
- Refactor MacroAssembler interfaces to differentiate the pointer operands from the 64-bit integer operands
- https://bugs.webkit.org/show_bug.cgi?id=99154
-
- Reviewed by Gavin Barraclough.
-
- In current JavaScriptCore implementation for JSVALUE64 platform (i.e.,
- the X64 platform), we assume that the JSValue size is same to the
- pointer size, and thus EncodedJSValue is simply type defined as a
- "void*". In the JIT compiler, we also take this assumption and invoke
- the same macro assembler interfaces for both JSValue and pointer
- operands. We need to differentiate the operations on pointers from the
- operations on JSValues, and let them invoking different macro
- assembler interfaces. For example, we now use the interface of
- "loadPtr" to load either a pointer or a JSValue, and we need to switch
- to using "loadPtr" to load a pointer and some new "load64" interface
- to load a JSValue. This would help us supporting other JSVALUE64
- platforms where pointer size is not necessarily 64-bits, for example
- x32 (bug #99153).
-
- The major modification I made is to introduce the "*64" interfaces in
- the MacroAssembler for those operations on JSValues, keep the "*Ptr"
- interfaces for those operations on real pointers, and go through all
- the JIT compiler code to correct the usage.
-
- This is the second part of the work, i.e, to correct the usage of the
- new MacroAssembler interfaces in the JIT compilers, which also means
- that now EncodedJSValue is defined as a 64-bit integer, and the "*64"
- interfaces are used for it.
-
- * assembler/MacroAssembler.h: JSValue immediates should be in Imm64 instead of ImmPtr.
- (MacroAssembler):
- (JSC::MacroAssembler::shouldBlind):
- * dfg/DFGAssemblyHelpers.cpp: Correct the JIT compilers usage of the new interfaces.
- (JSC::DFG::AssemblyHelpers::jitAssertIsInt32):
- (JSC::DFG::AssemblyHelpers::jitAssertIsJSInt32):
- (JSC::DFG::AssemblyHelpers::jitAssertIsJSNumber):
- (JSC::DFG::AssemblyHelpers::jitAssertIsJSDouble):
- (JSC::DFG::AssemblyHelpers::jitAssertIsCell):
- * dfg/DFGAssemblyHelpers.h:
- (JSC::DFG::AssemblyHelpers::emitPutToCallFrameHeader):
- (JSC::DFG::AssemblyHelpers::branchIfNotCell):
- (JSC::DFG::AssemblyHelpers::debugCall):
- (JSC::DFG::AssemblyHelpers::boxDouble):
- (JSC::DFG::AssemblyHelpers::unboxDouble):
- (JSC::DFG::AssemblyHelpers::emitExceptionCheck):
- * dfg/DFGCCallHelpers.h:
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
- (CCallHelpers):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::generateProtoChainAccessStub):
- (JSC::DFG::tryCacheGetByID):
- (JSC::DFG::tryBuildGetByIDList):
- (JSC::DFG::emitPutReplaceStub):
- (JSC::DFG::emitPutTransitionStub):
- * dfg/DFGScratchRegisterAllocator.h:
- (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer):
- (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer):
- * dfg/DFGSilentRegisterSavePlan.h:
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
- (JSC::DFG::SpeculativeJIT::compileValueToInt32):
- (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
- (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
- (JSC::DFG::SpeculativeJIT::compileInstanceOf):
- (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
- (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
- (JSC::DFG::SpeculativeJIT::silentSpill):
- (JSC::DFG::SpeculativeJIT::silentFill):
- (JSC::DFG::SpeculativeJIT::spill):
- (JSC::DFG::SpeculativeJIT::valueOfJSConstantAsImm64):
- (JSC::DFG::SpeculativeJIT::callOperation):
- (JSC::DFG::SpeculativeJIT::branch64):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::fillInteger):
- (JSC::DFG::SpeculativeJIT::fillDouble):
- (JSC::DFG::SpeculativeJIT::fillJSValue):
- (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToNumber):
- (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToInt32):
- (JSC::DFG::SpeculativeJIT::nonSpeculativeUInt32ToNumber):
- (JSC::DFG::SpeculativeJIT::cachedGetById):
- (JSC::DFG::SpeculativeJIT::cachedPutById):
- (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
- (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
- (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
- (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
- (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
- (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
- (JSC::DFG::SpeculativeJIT::emitCall):
- (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
- (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
- (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
- (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
- (JSC::DFG::SpeculativeJIT::convertToDouble):
- (JSC::DFG::SpeculativeJIT::compileObjectEquality):
- (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
- (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
- (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
- (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot):
- (JSC::DFG::SpeculativeJIT::compileLogicalNot):
- (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch):
- (JSC::DFG::SpeculativeJIT::emitBranch):
- (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal):
- (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal):
- (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
- (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGThunks.cpp:
- (JSC::DFG::osrExitGenerationThunkGenerator):
- (JSC::DFG::throwExceptionFromCallSlowPathGenerator):
- (JSC::DFG::slowPathFor):
- (JSC::DFG::virtualForThunkGenerator):
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::dumpRegisters):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompile):
- * jit/JIT.h:
- (JIT):
- * jit/JITArithmetic.cpp:
- (JSC::JIT::emit_op_negate):
- (JSC::JIT::emitSlow_op_negate):
- (JSC::JIT::emit_op_rshift):
- (JSC::JIT::emitSlow_op_urshift):
- (JSC::JIT::emit_compareAndJumpSlow):
- (JSC::JIT::emit_op_bitand):
- (JSC::JIT::compileBinaryArithOpSlowCase):
- (JSC::JIT::emit_op_div):
- * jit/JITCall.cpp:
- (JSC::JIT::compileLoadVarargs):
- (JSC::JIT::compileCallEval):
- (JSC::JIT::compileCallEvalSlowCase):
- (JSC::JIT::compileOpCall):
- * jit/JITInlineMethods.h: Have some clean-up work as well.
- (JSC):
- (JSC::JIT::emitPutCellToCallFrameHeader):
- (JSC::JIT::emitPutIntToCallFrameHeader):
- (JSC::JIT::emitPutToCallFrameHeader):
- (JSC::JIT::emitGetFromCallFrameHeader32):
- (JSC::JIT::emitGetFromCallFrameHeader64):
- (JSC::JIT::emitAllocateJSArray):
- (JSC::JIT::emitValueProfilingSite):
- (JSC::JIT::emitGetJITStubArg):
- (JSC::JIT::emitGetVirtualRegister):
- (JSC::JIT::emitPutVirtualRegister):
- (JSC::JIT::emitInitRegister):
- (JSC::JIT::emitJumpIfJSCell):
- (JSC::JIT::emitJumpIfBothJSCells):
- (JSC::JIT::emitJumpIfNotJSCell):
- (JSC::JIT::emitLoadInt32ToDouble):
- (JSC::JIT::emitJumpIfImmediateInteger):
- (JSC::JIT::emitJumpIfNotImmediateInteger):
- (JSC::JIT::emitJumpIfNotImmediateIntegers):
- (JSC::JIT::emitFastArithReTagImmediate):
- (JSC::JIT::emitFastArithIntToImmNoCheck):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::privateCompileCTINativeCall):
- (JSC::JIT::emit_op_mov):
- (JSC::JIT::emit_op_instanceof):
- (JSC::JIT::emit_op_is_undefined):
- (JSC::JIT::emit_op_is_boolean):
- (JSC::JIT::emit_op_is_number):
- (JSC::JIT::emit_op_tear_off_activation):
- (JSC::JIT::emit_op_not):
- (JSC::JIT::emit_op_jfalse):
- (JSC::JIT::emit_op_jeq_null):
- (JSC::JIT::emit_op_jneq_null):
- (JSC::JIT::emit_op_jtrue):
- (JSC::JIT::emit_op_bitxor):
- (JSC::JIT::emit_op_bitor):
- (JSC::JIT::emit_op_get_pnames):
- (JSC::JIT::emit_op_next_pname):
- (JSC::JIT::compileOpStrictEq):
- (JSC::JIT::emit_op_catch):
- (JSC::JIT::emit_op_throw_static_error):
- (JSC::JIT::emit_op_eq_null):
- (JSC::JIT::emit_op_neq_null):
- (JSC::JIT::emit_op_create_activation):
- (JSC::JIT::emit_op_create_arguments):
- (JSC::JIT::emit_op_init_lazy_reg):
- (JSC::JIT::emitSlow_op_convert_this):
- (JSC::JIT::emitSlow_op_not):
- (JSC::JIT::emit_op_get_argument_by_val):
- (JSC::JIT::emit_op_put_to_base):
- (JSC::JIT::emit_resolve_operations):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emitArrayStorageGetByVal):
- (JSC::JIT::emitSlow_op_get_by_val):
- (JSC::JIT::compileGetDirectOffset):
- (JSC::JIT::emit_op_get_by_pname):
- (JSC::JIT::emitContiguousPutByVal):
- (JSC::JIT::emitArrayStoragePutByVal):
- (JSC::JIT::compileGetByIdHotPath):
- (JSC::JIT::emit_op_put_by_id):
- (JSC::JIT::compilePutDirectOffset):
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitIntTypedArrayGetByVal):
- (JSC::JIT::emitFloatTypedArrayGetByVal):
- (JSC::JIT::emitFloatTypedArrayPutByVal):
- * jit/JITStubCall.h:
- (JITStubCall):
- (JSC::JITStubCall::JITStubCall):
- (JSC::JITStubCall::addArgument):
- (JSC::JITStubCall::call):
- (JSC::JITStubCall::callWithValueProfiling):
- * jit/JSInterfaceJIT.h:
- (JSC::JSInterfaceJIT::emitJumpIfImmediateNumber):
- (JSC::JSInterfaceJIT::emitJumpIfNotImmediateNumber):
- (JSC::JSInterfaceJIT::emitLoadJSCell):
- (JSC::JSInterfaceJIT::emitLoadInt32):
- (JSC::JSInterfaceJIT::emitLoadDouble):
- * jit/SpecializedThunkJIT.h:
- (JSC::SpecializedThunkJIT::returnDouble):
- (JSC::SpecializedThunkJIT::tagReturnAsInt32):
- * runtime/JSValue.cpp:
- (JSC::JSValue::description):
- * runtime/JSValue.h: Define JSVALUE64 EncodedJSValue as int64_t, which is also unified with JSVALUE32_64.
- (JSC):
- * runtime/JSValueInlineMethods.h: New implementation of some JSValue methods to make them more conformant
- with the new rule that "JSValue is a 64-bit integer rather than a pointer" for JSVALUE64 platforms.
- (JSC):
- (JSC::JSValue::JSValue):
- (JSC::JSValue::operator bool):
- (JSC::JSValue::operator==):
- (JSC::JSValue::operator!=):
- (JSC::reinterpretDoubleToInt64):
- (JSC::reinterpretInt64ToDouble):
- (JSC::JSValue::asDouble):
-
-2012-10-18 Michael Saboff <msaboff@apple.com>
-
- convertUTF8ToUTF16() Should Check for ASCII Input
- ihttps://bugs.webkit.org/show_bug.cgi?id=99739
-
- Reviewed by Geoffrey Garen.
-
- Using the updated convertUTF8ToUTF16() , we can determine if is makes more sense to
- create a string using the 8 bit source. Added a new OpaqueJSString::create(LChar*, unsigned).
- Had to add a cast n JSStringCreateWithCFString to differentiate which create() to call.
-
- * API/JSStringRef.cpp:
- (JSStringCreateWithUTF8CString):
- * API/JSStringRefCF.cpp:
- (JSStringCreateWithCFString):
- * API/OpaqueJSString.h:
- (OpaqueJSString::create):
- (OpaqueJSString):
- (OpaqueJSString::OpaqueJSString):
-
-2012-10-18 Oliver Hunt <oliver@apple.com>
-
- Unbreak jsc tests. Last minute "clever"-ness is clearly just not
- a good plan.
-
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
-
-2012-10-18 Oliver Hunt <oliver@apple.com>
-
- Bytecode should not have responsibility for determining how to perform non-local resolves
- https://bugs.webkit.org/show_bug.cgi?id=99349
-
- Reviewed by Gavin Barraclough.
-
- This patch removes lexical analysis from the bytecode generation. This allows
- us to delay lookup of a non-local variables until the lookup is actually necessary,
- and simplifies a lot of the resolve logic in BytecodeGenerator.
-
- Once a lookup is performed we cache the lookup information in a set of out-of-line
- buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
- etc, and allows the respective JITs to recreated optimal lookup code.
-
- This is currently still a performance regression in LLInt, but most of the remaining
- regression is caused by a lot of indirection that I'll remove in future work, as well
- as some work necessary to allow LLInt to perform in line instruction repatching.
- We will also want to improve the behaviour of the baseline JIT for some of the lookup
- operations, however this patch was getting quite large already so I'm landing it now
- that we've reached the bar of "performance-neutral".
-
- Basic browsing seems to work.
-
- * GNUmakefile.list.am:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::printStructures):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::CodeBlock):
- (JSC::CodeBlock::visitStructures):
- (JSC):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::shrinkToFit):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::addResolve):
- (JSC::CodeBlock::addPutToBase):
- (CodeBlock):
- (JSC::CodeBlock::resolveOperations):
- (JSC::CodeBlock::putToBaseOperation):
- (JSC::CodeBlock::numberOfResolveOperations):
- (JSC::CodeBlock::numberOfPutToBaseOperations):
- (JSC::CodeBlock::addPropertyAccessInstruction):
- (JSC::CodeBlock::globalObjectConstant):
- (JSC::CodeBlock::setGlobalObjectConstant):
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecode/ResolveGlobalStatus.cpp:
- (JSC::computeForStructure):
- (JSC::ResolveGlobalStatus::computeFor):
- * bytecode/ResolveGlobalStatus.h:
- (JSC):
- (ResolveGlobalStatus):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::ResolveResult::checkValidity):
- (JSC):
- (JSC::BytecodeGenerator::BytecodeGenerator):
- (JSC::BytecodeGenerator::resolve):
- (JSC::BytecodeGenerator::resolveConstDecl):
- (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
- (JSC::BytecodeGenerator::emitResolve):
- (JSC::BytecodeGenerator::emitResolveBase):
- (JSC::BytecodeGenerator::emitResolveBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithThis):
- (JSC::BytecodeGenerator::emitGetLocalVar):
- (JSC::BytecodeGenerator::emitInitGlobalConst):
- (JSC::BytecodeGenerator::emitPutToBase):
- * bytecompiler/BytecodeGenerator.h:
- (JSC::ResolveResult::registerResolve):
- (JSC::ResolveResult::dynamicResolve):
- (ResolveResult):
- (JSC::ResolveResult::ResolveResult):
- (JSC):
- (NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::resolved):
- (JSC::NonlocalResolveInfo::put):
- (BytecodeGenerator):
- (JSC::BytecodeGenerator::getResolveOperations):
- (JSC::BytecodeGenerator::getResolveWithThisOperations):
- (JSC::BytecodeGenerator::getResolveBaseOperations):
- (JSC::BytecodeGenerator::getResolveBaseForPutOperations):
- (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
- (JSC::BytecodeGenerator::getPutToBaseOperation):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::ResolveNode::isPure):
- (JSC::FunctionCallResolveNode::emitBytecode):
- (JSC::PostfixNode::emitResolve):
- (JSC::PrefixNode::emitResolve):
- (JSC::ReadModifyResolveNode::emitBytecode):
- (JSC::AssignResolveNode::emitBytecode):
- (JSC::ConstDeclNode::emitCodeSingle):
- (JSC::ForInNode::emitBytecode):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGByteCodeParser.cpp:
- (ByteCodeParser):
- (InlineStackEntry):
- (JSC::DFG::ByteCodeParser::handleGetByOffset):
- (DFG):
- (JSC::DFG::ByteCodeParser::parseResolveOperations):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canInlineResolveOperations):
- (DFG):
- (JSC::DFG::canCompileOpcode):
- (JSC::DFG::canInlineOpcode):
- * dfg/DFGGraph.h:
- (ResolveGlobalData):
- (ResolveOperationData):
- (DFG):
- (PutToBaseOperationData):
- (Graph):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::hasIdentifier):
- (JSC::DFG::Node::resolveOperationsDataIndex):
- (Node):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGOSRExit.cpp:
- (JSC::DFG::OSRExit::OSRExit):
- * dfg/DFGOSRExit.h:
- (OSRExit):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::resolveOperations):
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::putToBaseOperation):
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- * jit/JIT.h:
- (JIT):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_put_to_base):
- (JSC):
- (JSC::JIT::emit_resolve_operations):
- (JSC::JIT::emitSlow_link_resolve_operations):
- (JSC::JIT::emit_op_resolve):
- (JSC::JIT::emitSlow_op_resolve):
- (JSC::JIT::emit_op_resolve_base):
- (JSC::JIT::emitSlow_op_resolve_base):
- (JSC::JIT::emit_op_resolve_with_base):
- (JSC::JIT::emitSlow_op_resolve_with_base):
- (JSC::JIT::emit_op_resolve_with_this):
- (JSC::JIT::emitSlow_op_resolve_with_this):
- (JSC::JIT::emitSlow_op_put_to_base):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emit_op_put_to_base):
- (JSC):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitSlow_op_init_global_const_check):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitSlow_op_init_global_const_check):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- (JSC):
- * jit/JITStubs.h:
- * llint/LLIntSlowPaths.cpp:
- (LLInt):
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * llint/LLIntSlowPaths.h:
- (LLInt):
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * runtime/JSScope.cpp:
- (JSC::LookupResult::base):
- (JSC::LookupResult::value):
- (JSC::LookupResult::setBase):
- (JSC::LookupResult::setValue):
- (LookupResult):
- (JSC):
- (JSC::setPutPropertyAccessOffset):
- (JSC::executeResolveOperations):
- (JSC::JSScope::resolveContainingScopeInternal):
- (JSC::JSScope::resolveContainingScope):
- (JSC::JSScope::resolve):
- (JSC::JSScope::resolveBase):
- (JSC::JSScope::resolveWithBase):
- (JSC::JSScope::resolveWithThis):
- (JSC::JSScope::resolvePut):
- (JSC::JSScope::resolveGlobal):
- * runtime/JSScope.h:
- (JSScope):
- * runtime/JSVariableObject.cpp:
- (JSC):
- * runtime/JSVariableObject.h:
- (JSVariableObject):
- * runtime/Structure.h:
- (JSC::Structure::propertyAccessesAreCacheable):
- (Structure):
-
-2012-10-18 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Live oversize copied blocks should count toward overall heap fragmentation
- https://bugs.webkit.org/show_bug.cgi?id=99548
-
- Reviewed by Filip Pizlo.
-
- The CopiedSpace uses overall heap fragmentation to determine whether or not it should do any copying.
- Currently it doesn't include live oversize CopiedBlocks in the calculation, but it should. We should
- treat them as 100% utilized, since running a copying phase won't be able to free/compact any of their
- memory. We can also free any dead oversize CopiedBlocks while we're iterating over them, rather than
- iterating over them again at the end of the copying phase.
-
- * heap/CopiedSpace.cpp:
- (JSC::CopiedSpace::doneFillingBlock):
- (JSC::CopiedSpace::startedCopying):
- (JSC::CopiedSpace::doneCopying): Also removed a branch when iterating over from-space at the end of
- copying. Since we eagerly recycle blocks as soon as they're fully evacuated, we should see no
- unpinned blocks in from-space at the end of copying.
- * heap/CopiedSpaceInlineMethods.h:
- (JSC::CopiedSpace::recycleBorrowedBlock):
- * heap/CopyVisitorInlineMethods.h:
- (JSC::CopyVisitor::checkIfShouldCopy):
-
-2012-10-18 Roger Fong <roger_fong@apple.com>
-
- Unreviewed. Build fix after r131701 and r131777.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-10-18 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Race condition between GCThread and main thread during copying phase
- https://bugs.webkit.org/show_bug.cgi?id=99641
-
- Reviewed by Filip Pizlo.
-
- When a GCThread returns from copyFromShared(), it then calls doneCopying(), which returns
- its borrowed CopiedBlock to the CopiedSpace. This final block allows the CopiedSpace to
- continue and finish the cleanup of the copying phase. However, the GCThread can loop back
- around, see that m_currentPhase is still "Copy", and try to go through the copying phase again.
- This can cause all sorts of issues. To fix this, we should add a cyclic barrier to GCThread::waitForNextPhase().
-
- * heap/GCThread.cpp:
- (JSC::GCThread::waitForNextPhase): All GCThreads will wait when they finish one iteration until the main thread
- notifies them to move down to the second while loop, where they wait for the next GCPhase to start. They also
- decrement the m_numberOfActiveGCThreads counter as they begin to wait for the next phase and increment it as
- they enter the next phase. This allows the main thread to wait in endCurrentPhase() until all the threads have
- finished the current phase and are waiting on the next phase to begin. Without the counter, there would be
- no way to ensure that every thread was available for each GCPhase.
- (JSC::GCThread::gcThreadMain): We now use the m_phaseLock to synchronize with the main thread when we're being created.
- * heap/GCThreadSharedData.cpp:
- (JSC::GCThreadSharedData::GCThreadSharedData): As we create each GCThread, we increment the m_numberOfActiveGCThreads
- counter. When we are done creating the threads, we wait until they're all waiting for the next GCPhase. This prevents
- us from leaving some GCThreads behind during the first GCPhase, which could hurt us on our very short-running
- benchmarks (e.g. SunSpider).
- (JSC::GCThreadSharedData::~GCThreadSharedData):
- (JSC::GCThreadSharedData::startNextPhase): We atomically swap the two flags, m_gcThreadsShouldWait and m_currentPhase,
- so that if the threads finish very quickly, they will wait until the main thread is ready to end the current phase.
- (JSC::GCThreadSharedData::endCurrentPhase): Here atomically we swap the two flags again to allow the threads to
- advance to waiting on the next GCPhase. We wait until all of the GCThreads have settled into the second wait loop
- before allowing the main thread to continue. This prevents us from leaving one of the GCThreads stuck in the first
- wait loop if we were to call startNextPhase() before it had time to wake up and move on to the second wait loop.
- (JSC):
- (JSC::GCThreadSharedData::didStartMarking): We now use startNextPhase() to properly swap the flags.
- (JSC::GCThreadSharedData::didFinishMarking): Ditto for endCurrentPhase().
- (JSC::GCThreadSharedData::didStartCopying): Ditto.
- (JSC::GCThreadSharedData::didFinishCopying): Ditto.
- * heap/GCThreadSharedData.h:
- (GCThreadSharedData):
- * heap/Heap.cpp:
- (JSC::Heap::copyBackingStores): No reason to use the extra reference.
-
-2012-10-18 Pablo Flouret <pablof@motorola.com>
-
- Implement css3-conditional's @supports rule
- https://bugs.webkit.org/show_bug.cgi?id=86146
-
- Reviewed by Antti Koivisto.
-
- * Configurations/FeatureDefines.xcconfig:
- Add an ENABLE_CSS3_CONDITIONAL_RULES flag.
-
-2012-10-18 Michael Saboff <msaboff@apple.com>
-
- Make conversion between JSStringRef and WKStringRef work without character size conversions
- https://bugs.webkit.org/show_bug.cgi?id=99727
-
- Reviewed by Anders Carlsson.
-
- Export the string() method for use in WebKit.
-
- * API/OpaqueJSString.h:
- (OpaqueJSString::string):
-
-2012-10-18 Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
-
- [CMake] Avoid unnecessarily running the LLInt generation commands.
- https://bugs.webkit.org/show_bug.cgi?id=99708
-
- Reviewed by Rob Buis.
-
- As described in the comments in the change itself, in some cases
- the Ruby generation scripts used when LLInt is on would each be
- run twice in every build even if nothing had changed.
-
- Fix that by not setting the OBJECT_DEPENDS property of some source
- files to depend on the generated headers; instead, they are now
- just part of the final binaries/libraries which use them.
-
- * CMakeLists.txt:
-
-2012-10-17 Zoltan Horvath <zoltan@webkit.org>
-
- Remove the JSHeap memory measurement of the PageLoad performacetests since it creates bogus JSGlobalDatas
- https://bugs.webkit.org/show_bug.cgi?id=99609
-
- Reviewed by Ryosuke Niwa.
-
- Remove the implementation since it creates bogus JSGlobalDatas in the layout tests.
-
- * heap/HeapStatistics.cpp:
- (JSC):
- * heap/HeapStatistics.h:
- (HeapStatistics):
-
-2012-10-17 Sam Weinig <sam@webkit.org>
-
- Attempt to fix the build.
-
- * bytecode/GlobalResolveInfo.h: Copied from bytecode/GlobalResolveInfo.h.
-
-2012-10-17 Filip Pizlo <fpizlo@apple.com>
-
- REGRESSION (r130826 or r130828): Twitter top bar is dysfunctional
- https://bugs.webkit.org/show_bug.cgi?id=99577
- <rdar://problem/12518883>
-
- Reviewed by Mark Hahnenberg.
-
- It turns out that it's a good idea to maintain the invariants of your object model, such as that
- elements past publicLength should have the hole value.
-
- * dfg/DFGGraph.cpp:
- (JSC::DFG::Graph::dump):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-17 Anders Carlsson <andersca@apple.com>
-
- Clean up Vector.h
- https://bugs.webkit.org/show_bug.cgi?id=99622
-
- Reviewed by Benjamin Poulain.
-
- Fix fallout from removing std::max and std::min using declarations.
-
- * runtime/StringPrototype.cpp:
- (JSC::jsSpliceSubstrings):
- (JSC::jsSpliceSubstringsWithSeparators):
- (JSC::stringProtoFuncIndexOf):
- * yarr/YarrPattern.cpp:
- (JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
-
-2012-10-17 Oliver Hunt <oliver@apple.com>
-
- Committing new files is so overrated.
-
- * bytecode/ResolveOperation.h: Added.
- (JSC):
- (JSC::ResolveOperation::getAndReturnScopedVar):
- (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
- (ResolveOperation):
- (JSC::ResolveOperation::getAndReturnGlobalVar):
- (JSC::ResolveOperation::getAndReturnGlobalProperty):
- (JSC::ResolveOperation::resolveFail):
- (JSC::ResolveOperation::skipTopScopeNode):
- (JSC::ResolveOperation::skipScopes):
- (JSC::ResolveOperation::returnGlobalObjectAsBase):
- (JSC::ResolveOperation::setBaseToGlobal):
- (JSC::ResolveOperation::setBaseToUndefined):
- (JSC::ResolveOperation::setBaseToScope):
- (JSC::ResolveOperation::returnScopeAsBase):
- (JSC::PutToBaseOperation::PutToBaseOperation):
-
-2012-10-17 Michael Saboff <msaboff@apple.com>
-
- StringPrototype::jsSpliceSubstringsWithSeparators() doesn't optimally handle 8 bit strings
- https://bugs.webkit.org/show_bug.cgi?id=99230
-
- Reviewed by Geoffrey Garen.
-
- Added code to select characters8() or characters16() on the not all 8 bit path for both the
- processing of the source and the separators.
-
- * runtime/StringPrototype.cpp:
- (JSC::jsSpliceSubstringsWithSeparators):
-
-2012-10-17 Filip Pizlo <fpizlo@apple.com>
-
- Array and object allocations via 'new Object' or 'new Array' should be inlined in bytecode to allow allocation site profiling
- https://bugs.webkit.org/show_bug.cgi?id=99557
-
- Reviewed by Geoffrey Garen.
-
- Removed an inaccurate and misleading comment as per Geoff's review. (I forgot
- to make this change as part of http://trac.webkit.org/changeset/131644).
-
- * bytecompiler/NodesCodegen.cpp:
- (JSC::FunctionCallResolveNode::emitBytecode):
-
-2012-10-17 Oliver Hunt <oliver@apple.com>
-
- Bytecode should not have responsibility for determining how to perform non-local resolves
- https://bugs.webkit.org/show_bug.cgi?id=99349
-
- Reviewed by Gavin Barraclough.
-
- This patch removes lexical analysis from the bytecode generation. This allows
- us to delay lookup of a non-local variables until the lookup is actually necessary,
- and simplifies a lot of the resolve logic in BytecodeGenerator.
-
- Once a lookup is performed we cache the lookup information in a set of out-of-line
- buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
- etc, and allows the respective JITs to recreated optimal lookup code.
-
- This is currently still a performance regression in LLInt, but most of the remaining
- regression is caused by a lot of indirection that I'll remove in future work, as well
- as some work necessary to allow LLInt to perform in line instruction repatching.
- We will also want to improve the behaviour of the baseline JIT for some of the lookup
- operations, however this patch was getting quite large already so I'm landing it now
- that we've reached the bar of "performance-neutral".
-
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::printStructures):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::CodeBlock):
- (JSC::CodeBlock::visitStructures):
- (JSC):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::shrinkToFit):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::addResolve):
- (JSC::CodeBlock::addPutToBase):
- (CodeBlock):
- (JSC::CodeBlock::resolveOperations):
- (JSC::CodeBlock::putToBaseOperation):
- (JSC::CodeBlock::numberOfResolveOperations):
- (JSC::CodeBlock::numberOfPutToBaseOperations):
- (JSC::CodeBlock::addPropertyAccessInstruction):
- (JSC::CodeBlock::globalObjectConstant):
- (JSC::CodeBlock::setGlobalObjectConstant):
- * bytecode/GlobalResolveInfo.h: Removed.
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecode/ResolveGlobalStatus.cpp:
- (JSC::computeForStructure):
- (JSC::ResolveGlobalStatus::computeFor):
- * bytecode/ResolveGlobalStatus.h:
- (JSC):
- (ResolveGlobalStatus):
- * bytecode/ResolveOperation.h: Added.
- The new types and logic we use to perform the cached lookups.
- (JSC):
- (ResolveOperation):
- (JSC::ResolveOperation::getAndReturnScopedVar):
- (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
- (JSC::ResolveOperation::getAndReturnGlobalVar):
- (JSC::ResolveOperation::getAndReturnGlobalProperty):
- (JSC::ResolveOperation::resolveFail):
- (JSC::ResolveOperation::skipTopScopeNode):
- (JSC::ResolveOperation::skipScopes):
- (JSC::ResolveOperation::returnGlobalObjectAsBase):
- (JSC::ResolveOperation::setBaseToGlobal):
- (JSC::ResolveOperation::setBaseToUndefined):
- (JSC::ResolveOperation::setBaseToScope):
- (JSC::ResolveOperation::returnScopeAsBase):
- (JSC::PutToBaseOperation::PutToBaseOperation):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::ResolveResult::checkValidity):
- (JSC):
- (JSC::BytecodeGenerator::BytecodeGenerator):
- (JSC::BytecodeGenerator::resolve):
- (JSC::BytecodeGenerator::resolveConstDecl):
- (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
- (JSC::BytecodeGenerator::emitResolve):
- (JSC::BytecodeGenerator::emitResolveBase):
- (JSC::BytecodeGenerator::emitResolveBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithThis):
- (JSC::BytecodeGenerator::emitGetLocalVar):
- (JSC::BytecodeGenerator::emitInitGlobalConst):
- (JSC::BytecodeGenerator::emitPutToBase):
- * bytecompiler/BytecodeGenerator.h:
- (JSC::ResolveResult::registerResolve):
- (JSC::ResolveResult::dynamicResolve):
- (ResolveResult):
- (JSC::ResolveResult::ResolveResult):
- (JSC):
- (NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::resolved):
- (JSC::NonlocalResolveInfo::put):
- (BytecodeGenerator):
- (JSC::BytecodeGenerator::getResolveOperations):
- (JSC::BytecodeGenerator::getResolveWithThisOperations):
- (JSC::BytecodeGenerator::getResolveBaseOperations):
- (JSC::BytecodeGenerator::getResolveBaseForPutOperations):
- (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
- (JSC::BytecodeGenerator::getPutToBaseOperation):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::ResolveNode::isPure):
- (JSC::FunctionCallResolveNode::emitBytecode):
- (JSC::PostfixNode::emitResolve):
- (JSC::PrefixNode::emitResolve):
- (JSC::ReadModifyResolveNode::emitBytecode):
- (JSC::AssignResolveNode::emitBytecode):
- (JSC::ConstDeclNode::emitCodeSingle):
- (JSC::ForInNode::emitBytecode):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGByteCodeParser.cpp:
- (ByteCodeParser):
- (InlineStackEntry):
- (JSC::DFG::ByteCodeParser::handleGetByOffset):
- (DFG):
- (JSC::DFG::ByteCodeParser::parseResolveOperations):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canCompileResolveOperations):
- (DFG):
- (JSC::DFG::canCompilePutToBaseOperation):
- (JSC::DFG::canCompileOpcode):
- (JSC::DFG::canInlineOpcode):
- * dfg/DFGGraph.h:
- (ResolveGlobalData):
- (ResolveOperationData):
- (DFG):
- (PutToBaseOperationData):
- (Graph):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::hasIdentifier):
- (JSC::DFG::Node::resolveOperationsDataIndex):
- (Node):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGOSRExit.cpp:
- (JSC::DFG::OSRExit::OSRExit):
- * dfg/DFGOSRExit.h:
- (OSRExit):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::resolveOperations):
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::putToBaseOperation):
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- * jit/JIT.h:
- (JIT):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_put_to_base):
- (JSC):
- (JSC::JIT::emit_resolve_operations):
- (JSC::JIT::emitSlow_link_resolve_operations):
- (JSC::JIT::emit_op_resolve):
- (JSC::JIT::emitSlow_op_resolve):
- (JSC::JIT::emit_op_resolve_base):
- (JSC::JIT::emitSlow_op_resolve_base):
- (JSC::JIT::emit_op_resolve_with_base):
- (JSC::JIT::emitSlow_op_resolve_with_base):
- (JSC::JIT::emit_op_resolve_with_this):
- (JSC::JIT::emitSlow_op_resolve_with_this):
- (JSC::JIT::emitSlow_op_put_to_base):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emit_op_put_to_base):
- (JSC):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitSlow_op_init_global_const_check):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitSlow_op_init_global_const_check):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- (JSC):
- * jit/JITStubs.h:
- * llint/LLIntSlowPaths.cpp:
- (LLInt):
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * llint/LLIntSlowPaths.h:
- (LLInt):
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * runtime/JSScope.cpp:
- (JSC::LookupResult::base):
- (JSC::LookupResult::value):
- (JSC::LookupResult::setBase):
- (JSC::LookupResult::setValue):
- (LookupResult):
- (JSC):
- (JSC::setPutPropertyAccessOffset):
- (JSC::executeResolveOperations):
- (JSC::JSScope::resolveContainingScopeInternal):
- (JSC::JSScope::resolveContainingScope):
- (JSC::JSScope::resolve):
- (JSC::JSScope::resolveBase):
- (JSC::JSScope::resolveWithBase):
- (JSC::JSScope::resolveWithThis):
- (JSC::JSScope::resolvePut):
- (JSC::JSScope::resolveGlobal):
- * runtime/JSScope.h:
- (JSScope):
- * runtime/JSVariableObject.cpp:
- (JSC):
- * runtime/JSVariableObject.h:
- (JSVariableObject):
- * runtime/Structure.h:
- (JSC::Structure::propertyAccessesAreCacheable):
- (Structure):
-
-2012-10-17 Filip Pizlo <fpizlo@apple.com>
-
- Array and object allocations via 'new Object' or 'new Array' should be inlined in bytecode to allow allocation site profiling
- https://bugs.webkit.org/show_bug.cgi?id=99557
-
- Reviewed by Geoffrey Garen.
-
- This uses the old jneq_ptr trick to allow for the bytecode to "see" that the
- operation in question is what we almost certainly know it to be.
-
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecode/SpecialPointer.h:
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::emitCall):
- (JSC::BytecodeGenerator::emitCallEval):
- (JSC::BytecodeGenerator::expectedFunctionForIdentifier):
- (JSC):
- (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
- (JSC::BytecodeGenerator::emitConstruct):
- * bytecompiler/BytecodeGenerator.h:
- (BytecodeGenerator):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::NewExprNode::emitBytecode):
- (JSC::FunctionCallValueNode::emitBytecode):
- (JSC::FunctionCallResolveNode::emitBytecode):
- (JSC::FunctionCallBracketNode::emitBytecode):
- (JSC::FunctionCallDotNode::emitBytecode):
- (JSC::CallFunctionCallDotNode::emitBytecode):
- (JSC::ApplyFunctionCallDotNode::emitBytecode):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::parseBlock):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canCompileOpcode):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- * jit/JIT.h:
- (JIT):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_new_array_with_size):
- (JSC):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- (JSC):
- * jit/JITStubs.h:
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- (LLInt):
- * llint/LLIntSlowPaths.h:
- (LLInt):
- * llint/LowLevelInterpreter.asm:
- * runtime/ArrayConstructor.cpp:
- (JSC::constructArrayWithSizeQuirk):
- (JSC):
- * runtime/ArrayConstructor.h:
- (JSC):
- * runtime/CommonIdentifiers.h:
- * runtime/JSGlobalObject.cpp:
- (JSC::JSGlobalObject::reset):
- (JSC):
-
-2012-10-17 Filip Pizlo <fpizlo@apple.com>
-
- JIT op_get_by_pname should call cti_get_by_val_generic and not cti_get_by_val
- https://bugs.webkit.org/show_bug.cgi?id=99631
- <rdar://problem/12483221>
-
- Reviewed by Mark Hahnenberg.
-
- cti_get_by_val assumes that the return address has patching metadata associated with it, which won't
- be true for op_get_by_pname. cti_get_by_val_generic makes no such assumptions.
-
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emitSlow_op_get_by_pname):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emitSlow_op_get_by_pname):
-
-2012-10-17 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Block freeing thread should sleep indefinitely when there's no work to do
- https://bugs.webkit.org/show_bug.cgi?id=98084
-
- Reviewed by Geoffrey Garen.
-
- r130212 didn't fully fix the problem.
-
- * heap/BlockAllocator.cpp:
- (JSC::BlockAllocator::blockFreeingThreadMain): We would just continue to the next iteration if
- we found that we had zero blocks to copy. We should move the indefinite wait up to where that
- check is done so that we properly detect the "no more blocks to copy, wait for more" condition.
-
-2012-10-16 Csaba Osztrogonác <ossy@webkit.org>
-
- Unreviewed, rolling out r131516 and r131550.
- http://trac.webkit.org/changeset/131516
- http://trac.webkit.org/changeset/131550
- https://bugs.webkit.org/show_bug.cgi?id=99349
-
- It caused zillion different problem on different platforms
-
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * bytecode/CodeBlock.cpp:
- (JSC):
- (JSC::isGlobalResolve):
- (JSC::instructionOffsetForNth):
- (JSC::printGlobalResolveInfo):
- (JSC::CodeBlock::printStructures):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::CodeBlock):
- (JSC::CodeBlock::visitStructures):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset):
- (JSC::CodeBlock::globalResolveInfoForBytecodeOffset):
- (JSC::CodeBlock::shrinkToFit):
- * bytecode/CodeBlock.h:
- (CodeBlock):
- (JSC::CodeBlock::addGlobalResolveInstruction):
- (JSC::CodeBlock::addGlobalResolveInfo):
- (JSC::CodeBlock::globalResolveInfo):
- (JSC::CodeBlock::numberOfGlobalResolveInfos):
- (JSC::CodeBlock::globalResolveInfoCount):
- * bytecode/GlobalResolveInfo.h: Copied from Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp.
- (JSC):
- (JSC::GlobalResolveInfo::GlobalResolveInfo):
- (GlobalResolveInfo):
- (JSC::getGlobalResolveInfoBytecodeOffset):
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecode/ResolveGlobalStatus.cpp:
- (JSC):
- (JSC::computeForStructure):
- (JSC::computeForLLInt):
- (JSC::ResolveGlobalStatus::computeFor):
- * bytecode/ResolveGlobalStatus.h:
- (JSC):
- (ResolveGlobalStatus):
- * bytecode/ResolveOperation.h: Removed.
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::ResolveResult::checkValidity):
- (JSC::ResolveResult::registerPointer):
- (JSC):
- (JSC::BytecodeGenerator::BytecodeGenerator):
- (JSC::BytecodeGenerator::resolve):
- (JSC::BytecodeGenerator::resolveConstDecl):
- (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
- (JSC::BytecodeGenerator::emitResolve):
- (JSC::BytecodeGenerator::emitResolveBase):
- (JSC::BytecodeGenerator::emitResolveBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithBase):
- (JSC::BytecodeGenerator::emitResolveWithThis):
- (JSC::BytecodeGenerator::emitGetStaticVar):
- (JSC::BytecodeGenerator::emitInitGlobalConst):
- (JSC::BytecodeGenerator::emitPutStaticVar):
- * bytecompiler/BytecodeGenerator.h:
- (JSC::ResolveResult::registerResolve):
- (JSC::ResolveResult::dynamicResolve):
- (JSC::ResolveResult::lexicalResolve):
- (JSC::ResolveResult::indexedGlobalResolve):
- (JSC::ResolveResult::dynamicIndexedGlobalResolve):
- (JSC::ResolveResult::globalResolve):
- (JSC::ResolveResult::dynamicGlobalResolve):
- (JSC::ResolveResult::type):
- (JSC::ResolveResult::index):
- (JSC::ResolveResult::depth):
- (JSC::ResolveResult::globalObject):
- (ResolveResult):
- (JSC::ResolveResult::isStatic):
- (JSC::ResolveResult::isIndexed):
- (JSC::ResolveResult::isScoped):
- (JSC::ResolveResult::isGlobal):
- (JSC::ResolveResult::ResolveResult):
- (BytecodeGenerator):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::ResolveNode::isPure):
- (JSC::FunctionCallResolveNode::emitBytecode):
- (JSC::PostfixNode::emitResolve):
- (JSC::PrefixNode::emitResolve):
- (JSC::ReadModifyResolveNode::emitBytecode):
- (JSC::AssignResolveNode::emitBytecode):
- (JSC::ConstDeclNode::emitCodeSingle):
- (JSC::ForInNode::emitBytecode):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGByteCodeParser.cpp:
- (ByteCodeParser):
- (InlineStackEntry):
- (JSC::DFG::ByteCodeParser::handleGetByOffset):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canCompileOpcode):
- (JSC::DFG::canInlineOpcode):
- * dfg/DFGGraph.h:
- (ResolveGlobalData):
- (DFG):
- (Graph):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::hasIdentifier):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGOSRExit.cpp:
- (JSC::DFG::OSRExit::OSRExit):
- * dfg/DFGOSRExit.h:
- (OSRExit):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- (JSC):
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- * jit/JIT.h:
- (JIT):
- (JSC::JIT::emit_op_get_global_var_watchable):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_resolve):
- (JSC):
- (JSC::JIT::emit_op_resolve_base):
- (JSC::JIT::emit_op_resolve_skip):
- (JSC::JIT::emit_op_resolve_global):
- (JSC::JIT::emitSlow_op_resolve_global):
- (JSC::JIT::emit_op_resolve_with_base):
- (JSC::JIT::emit_op_resolve_with_this):
- (JSC::JIT::emit_op_resolve_global_dynamic):
- (JSC::JIT::emitSlow_op_resolve_global_dynamic):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emit_op_resolve):
- (JSC):
- (JSC::JIT::emit_op_resolve_base):
- (JSC::JIT::emit_op_resolve_skip):
- (JSC::JIT::emit_op_resolve_global):
- (JSC::JIT::emitSlow_op_resolve_global):
- (JSC::JIT::emit_op_resolve_with_base):
- (JSC::JIT::emit_op_resolve_with_this):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_scoped_var):
- (JSC):
- (JSC::JIT::emit_op_put_scoped_var):
- (JSC::JIT::emit_op_get_global_var):
- (JSC::JIT::emit_op_put_global_var):
- (JSC::JIT::emit_op_put_global_var_check):
- (JSC::JIT::emitSlow_op_put_global_var_check):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_get_scoped_var):
- (JSC):
- (JSC::JIT::emit_op_put_scoped_var):
- (JSC::JIT::emit_op_get_global_var):
- (JSC::JIT::emit_op_put_global_var):
- (JSC::JIT::emit_op_put_global_var_check):
- (JSC::JIT::emitSlow_op_put_global_var_check):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- (JSC):
- * jit/JITStubs.h:
- * llint/LLIntSlowPaths.cpp:
- (LLInt):
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * llint/LLIntSlowPaths.h:
- (LLInt):
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * runtime/JSScope.cpp:
- (JSC::JSScope::resolve):
- (JSC::JSScope::resolveSkip):
- (JSC::JSScope::resolveGlobal):
- (JSC::JSScope::resolveGlobalDynamic):
- (JSC::JSScope::resolveBase):
- (JSC::JSScope::resolveWithBase):
- (JSC::JSScope::resolveWithThis):
- * runtime/JSScope.h:
- (JSScope):
- * runtime/JSVariableObject.cpp:
- * runtime/JSVariableObject.h:
- * runtime/Structure.h:
-
-2012-10-16 Dongwoo Joshua Im <dw.im@samsung.com>
-
- [GTK] Fix build break - ResolveOperations.h is not in WebKit.
- https://bugs.webkit.org/show_bug.cgi?id=99538
-
- Unreviewed build fix.
-
- There are some files including ResolveOperations.h which is not exist at all.
-
- * GNUmakefile.list.am: s/ResolveOperations.h/ResolveOperation.h/
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: s/ResolveOperations.h/ResolveOperation.h/
-
-2012-10-16 Jian Li <jianli@chromium.org>
-
- Rename feature define ENABLE_WIDGET_REGION to ENABLE_DRAGGBALE_REGION
- https://bugs.webkit.org/show_bug.cgi?id=98975
-
- Reviewed by Adam Barth.
-
- Renaming is needed to better match with the draggable region code.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-15 Oliver Hunt <oliver@apple.com>
-
- Bytecode should not have responsibility for determining how to perform non-local resolves
- https://bugs.webkit.org/show_bug.cgi?id=99349
-
- Reviewed by Gavin Barraclough.
-
- This patch removes lexical analysis from the bytecode generation. This allows
- us to delay lookup of a non-local variables until the lookup is actually necessary,
- and simplifies a lot of the resolve logic in BytecodeGenerator.
-
- Once a lookup is performed we cache the lookup information in a set of out-of-line
- buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
- etc, and allows the respective JITs to recreated optimal lookup code.
-
- This is currently still a performance regression in LLInt, but most of the remaining
- regression is caused by a lot of indirection that I'll remove in future work, as well
- as some work necessary to allow LLInt to perform in line instruction repatching.
- We will also want to improve the behaviour of the baseline JIT for some of the lookup
- operations, however this patch was getting quite large already so I'm landing it now
- that we've reached the bar of "performance-neutral".
-
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::printStructures):
- (JSC::CodeBlock::dump):
- (JSC::CodeBlock::CodeBlock):
- (JSC::CodeBlock::visitStructures):
- (JSC):
- (JSC::CodeBlock::finalizeUnconditionally):
- (JSC::CodeBlock::shrinkToFit):
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::addResolve):
- (JSC::CodeBlock::addPutToBase):
- (CodeBlock):
- (JSC::CodeBlock::resolveOperations):
- (JSC::CodeBlock::putToBaseOperation):
- (JSC::CodeBlock::numberOfResolveOperations):
- (JSC::CodeBlock::numberOfPutToBaseOperations):
- (JSC::CodeBlock::addPropertyAccessInstruction):
- (JSC::CodeBlock::globalObjectConstant):
- (JSC::CodeBlock::setGlobalObjectConstant):
- * bytecode/GlobalResolveInfo.h: Removed.
- * bytecode/Opcode.h:
- (JSC):
- (JSC::padOpcodeName):
- * bytecode/ResolveGlobalStatus.cpp:
- (JSC::computeForStructure):
- (JSC::ResolveGlobalStatus::computeFor):
- * bytecode/ResolveGlobalStatus.h:
- (JSC):
- (ResolveGlobalStatus):
- * bytecode/ResolveOperation.h: Added.
- The new types and logic we use to perform the cached lookups.
- (JSC):
- (ResolveOperation):
- (JSC::ResolveOperation::getAndReturnScopedVar):
- (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
- (JSC::ResolveOperation::getAndReturnGlobalVar):
- (JSC::ResolveOperation::getAndReturnGlobalProperty):
- (JSC::ResolveOperation::resolveFail):
- (JSC::ResolveOperation::skipTopScopeNode):
- (JSC::ResolveOperation::skipScopes):
- (JSC::ResolveOperation::returnGlobalObjectAsBase):
- (JSC::ResolveOperation::setBaseToGlobal):
- (JSC::ResolveOperation::setBaseToUndefined):
- (JSC::ResolveOperation::setBaseToScope):
- (JSC::ResolveOperation::returnScopeAsBase):
- (JSC::PutToBaseOperation::PutToBaseOperation):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::ResolveResult::checkValidity):
- (JSC):
- (JSC::BytecodeGenerator::BytecodeGenerator):
- (JSC::BytecodeGenerator::resolve):
- (JSC::BytecodeGenerator::resolveConstDecl):
- (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
- (JSC::BytecodeGenerator::emitResolve):
- (JSC::BytecodeGenerator::emitResolveBase):
- (JSC::BytecodeGenerator::emitResolveBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
- (JSC::BytecodeGenerator::emitResolveWithThis):
- (JSC::BytecodeGenerator::emitGetLocalVar):
- (JSC::BytecodeGenerator::emitInitGlobalConst):
- (JSC::BytecodeGenerator::emitPutToBase):
- * bytecompiler/BytecodeGenerator.h:
- (JSC::ResolveResult::registerResolve):
- (JSC::ResolveResult::dynamicResolve):
- (ResolveResult):
- (JSC::ResolveResult::ResolveResult):
- (JSC):
- (NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
- (JSC::NonlocalResolveInfo::resolved):
- (JSC::NonlocalResolveInfo::put):
- (BytecodeGenerator):
- (JSC::BytecodeGenerator::getResolveOperations):
- (JSC::BytecodeGenerator::getResolveWithThisOperations):
- (JSC::BytecodeGenerator::getResolveBaseOperations):
- (JSC::BytecodeGenerator::getResolveBaseForPutOperations):
- (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
- (JSC::BytecodeGenerator::getPutToBaseOperation):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::ResolveNode::isPure):
- (JSC::FunctionCallResolveNode::emitBytecode):
- (JSC::PostfixNode::emitResolve):
- (JSC::PrefixNode::emitResolve):
- (JSC::ReadModifyResolveNode::emitBytecode):
- (JSC::AssignResolveNode::emitBytecode):
- (JSC::ConstDeclNode::emitCodeSingle):
- (JSC::ForInNode::emitBytecode):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGByteCodeParser.cpp:
- (ByteCodeParser):
- (InlineStackEntry):
- (JSC::DFG::ByteCodeParser::handleGetByOffset):
- (DFG):
- (JSC::DFG::ByteCodeParser::parseResolveOperations):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canCompileResolveOperations):
- (DFG):
- (JSC::DFG::canCompilePutToBaseOperation):
- (JSC::DFG::canCompileOpcode):
- (JSC::DFG::canInlineOpcode):
- * dfg/DFGGraph.h:
- (ResolveGlobalData):
- (ResolveOperationData):
- (DFG):
- (PutToBaseOperationData):
- (Graph):
- * dfg/DFGNode.h:
- (JSC::DFG::Node::hasIdentifier):
- (JSC::DFG::Node::resolveOperationsDataIndex):
- (Node):
- * dfg/DFGNodeType.h:
- (DFG):
- * dfg/DFGOSRExit.cpp:
- (JSC::DFG::OSRExit::OSRExit):
- * dfg/DFGOSRExit.h:
- (OSRExit):
- * dfg/DFGOSRExitCompiler.cpp:
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGPredictionPropagationPhase.cpp:
- (JSC::DFG::PredictionPropagationPhase::propagate):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::resolveOperations):
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::putToBaseOperation):
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileMainPass):
- (JSC::JIT::privateCompileSlowCases):
- * jit/JIT.h:
- (JIT):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emit_op_put_to_base):
- (JSC):
- (JSC::JIT::emit_resolve_operations):
- (JSC::JIT::emitSlow_link_resolve_operations):
- (JSC::JIT::emit_op_resolve):
- (JSC::JIT::emitSlow_op_resolve):
- (JSC::JIT::emit_op_resolve_base):
- (JSC::JIT::emitSlow_op_resolve_base):
- (JSC::JIT::emit_op_resolve_with_base):
- (JSC::JIT::emitSlow_op_resolve_with_base):
- (JSC::JIT::emit_op_resolve_with_this):
- (JSC::JIT::emitSlow_op_resolve_with_this):
- (JSC::JIT::emitSlow_op_put_to_base):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emit_op_put_to_base):
- (JSC):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitSlow_op_init_global_const_check):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_init_global_const):
- (JSC::JIT::emit_op_init_global_const_check):
- (JSC::JIT::emitSlow_op_init_global_const_check):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- (JSC):
- * jit/JITStubs.h:
- * llint/LLIntSlowPaths.cpp:
- (LLInt):
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- * llint/LLIntSlowPaths.h:
- (LLInt):
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * runtime/JSScope.cpp:
- (JSC::LookupResult::base):
- (JSC::LookupResult::value):
- (JSC::LookupResult::setBase):
- (JSC::LookupResult::setValue):
- (LookupResult):
- (JSC):
- (JSC::setPutPropertyAccessOffset):
- (JSC::executeResolveOperations):
- (JSC::JSScope::resolveContainingScopeInternal):
- (JSC::JSScope::resolveContainingScope):
- (JSC::JSScope::resolve):
- (JSC::JSScope::resolveBase):
- (JSC::JSScope::resolveWithBase):
- (JSC::JSScope::resolveWithThis):
- (JSC::JSScope::resolvePut):
- (JSC::JSScope::resolveGlobal):
- * runtime/JSScope.h:
- (JSScope):
- * runtime/JSVariableObject.cpp:
- (JSC):
- * runtime/JSVariableObject.h:
- (JSVariableObject):
- * runtime/Structure.h:
- (JSC::Structure::propertyAccessesAreCacheable):
- (Structure):
-
-2012-10-16 Filip Pizlo <fpizlo@apple.com>
-
- Accidental switch fall-through in DFG::FixupPhase
- https://bugs.webkit.org/show_bug.cgi?id=96956
- <rdar://problem/12313242>
-
- Reviewed by Mark Hahnenberg.
-
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
-
-2012-10-16 Filip Pizlo <fpizlo@apple.com>
-
- GetScopedVar CSE matches dead GetScopedVar's leading to IR corruption
- https://bugs.webkit.org/show_bug.cgi?id=99470
- <rdar://problem/12363698>
-
- Reviewed by Mark Hahnenberg.
-
- All it takes is to follow the "if (!shouldGenerate) continue" idiom and everything will be OK.
-
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::globalVarLoadElimination):
- (JSC::DFG::CSEPhase::scopedVarLoadElimination):
- (JSC::DFG::CSEPhase::globalVarWatchpointElimination):
- (JSC::DFG::CSEPhase::getByValLoadElimination):
- (JSC::DFG::CSEPhase::checkStructureElimination):
- (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
- (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
-
-2012-10-16 Dima Gorbik <dgorbik@apple.com>
-
- Remove Platform.h include from the header files.
- https://bugs.webkit.org/show_bug.cgi?id=98665
-
- Reviewed by Eric Seidel.
-
- We don't want other clients that include WebKit headers to know about Platform.h.
-
- * API/tests/minidom.c:
- * API/tests/testapi.c:
-
-2012-10-16 Balazs Kilvady <kilvadyb@homejinni.com>
-
- Add missing MIPS functions to assembler.
- https://bugs.webkit.org/show_bug.cgi?id=98856
-
- Reviewed by Oliver Hunt.
-
- Implement missing functions in MacroAssemblerMIPS and MIPSAssembler.
-
- * assembler/MIPSAssembler.h:
- (JSC::MIPSAssembler::lb):
- (MIPSAssembler):
- (JSC::MIPSAssembler::lh):
- (JSC::MIPSAssembler::cvtds):
- (JSC::MIPSAssembler::cvtsd):
- (JSC::MIPSAssembler::vmov):
- * assembler/MacroAssemblerMIPS.h:
- (MacroAssemblerMIPS):
- (JSC::MacroAssemblerMIPS::load8Signed):
- (JSC::MacroAssemblerMIPS::load16Signed):
- (JSC::MacroAssemblerMIPS::moveDoubleToInts):
- (JSC::MacroAssemblerMIPS::moveIntsToDouble):
- (JSC::MacroAssemblerMIPS::loadFloat):
- (JSC::MacroAssemblerMIPS::loadDouble):
- (JSC::MacroAssemblerMIPS::storeFloat):
- (JSC::MacroAssemblerMIPS::storeDouble):
- (JSC::MacroAssemblerMIPS::addDouble):
- (JSC::MacroAssemblerMIPS::convertFloatToDouble):
- (JSC::MacroAssemblerMIPS::convertDoubleToFloat):
-
-2012-10-16 Balazs Kilvady <kilvadyb@homejinni.com>
-
- MIPS assembler coding-style fix.
- https://bugs.webkit.org/show_bug.cgi?id=99359
-
- Reviewed by Oliver Hunt.
-
- Coding style fix of existing MIPS assembler header files.
-
- * assembler/MIPSAssembler.h:
- (JSC::MIPSAssembler::addiu):
- (JSC::MIPSAssembler::addu):
- (JSC::MIPSAssembler::subu):
- (JSC::MIPSAssembler::mul):
- (JSC::MIPSAssembler::andInsn):
- (JSC::MIPSAssembler::andi):
- (JSC::MIPSAssembler::nor):
- (JSC::MIPSAssembler::orInsn):
- (JSC::MIPSAssembler::ori):
- (JSC::MIPSAssembler::xorInsn):
- (JSC::MIPSAssembler::xori):
- (JSC::MIPSAssembler::slt):
- (JSC::MIPSAssembler::sltu):
- (JSC::MIPSAssembler::sltiu):
- (JSC::MIPSAssembler::sll):
- (JSC::MIPSAssembler::sllv):
- (JSC::MIPSAssembler::sra):
- (JSC::MIPSAssembler::srav):
- (JSC::MIPSAssembler::srl):
- (JSC::MIPSAssembler::srlv):
- (JSC::MIPSAssembler::lbu):
- (JSC::MIPSAssembler::lw):
- (JSC::MIPSAssembler::lwl):
- (JSC::MIPSAssembler::lwr):
- (JSC::MIPSAssembler::lhu):
- (JSC::MIPSAssembler::sb):
- (JSC::MIPSAssembler::sh):
- (JSC::MIPSAssembler::sw):
- (JSC::MIPSAssembler::addd):
- (JSC::MIPSAssembler::subd):
- (JSC::MIPSAssembler::muld):
- (JSC::MIPSAssembler::divd):
- (JSC::MIPSAssembler::lwc1):
- (JSC::MIPSAssembler::ldc1):
- (JSC::MIPSAssembler::swc1):
- (JSC::MIPSAssembler::sdc1):
- (MIPSAssembler):
- (JSC::MIPSAssembler::relocateJumps):
- (JSC::MIPSAssembler::linkWithOffset):
- * assembler/MacroAssemblerMIPS.h:
- (JSC::MacroAssemblerMIPS::add32):
- (JSC::MacroAssemblerMIPS::and32):
- (JSC::MacroAssemblerMIPS::sub32):
- (MacroAssemblerMIPS):
- (JSC::MacroAssemblerMIPS::load8):
- (JSC::MacroAssemblerMIPS::load32):
- (JSC::MacroAssemblerMIPS::load32WithUnalignedHalfWords):
- (JSC::MacroAssemblerMIPS::load16):
- (JSC::MacroAssemblerMIPS::store8):
- (JSC::MacroAssemblerMIPS::store16):
- (JSC::MacroAssemblerMIPS::store32):
- (JSC::MacroAssemblerMIPS::nearCall):
- (JSC::MacroAssemblerMIPS::test8):
- (JSC::MacroAssemblerMIPS::test32):
-
-2012-10-16 Yuqiang Xian <yuqiang.xian@intel.com>
-
- Refactor MacroAssembler interfaces to differentiate the pointer operands from the 64-bit integer operands
- https://bugs.webkit.org/show_bug.cgi?id=99154
-
- Reviewed by Gavin Barraclough.
-
- In current JavaScriptCore implementation for JSVALUE64 platform (i.e.,
- the X64 platform), we assume that the JSValue size is same to the
- pointer size, and thus EncodedJSValue is simply type defined as a
- "void*". In the JIT compiler, we also take this assumption and invoke
- the same macro assembler interfaces for both JSValue and pointer
- operands. We need to differentiate the operations on pointers from the
- operations on JSValues, and let them invoking different macro
- assembler interfaces. For example, we now use the interface of
- "loadPtr" to load either a pointer or a JSValue, and we need to switch
- to using "loadPtr" to load a pointer and some new "load64" interface
- to load a JSValue. This would help us supporting other JSVALUE64
- platforms where pointer size is not necessarily 64-bits, for example
- x32 (bug #99153).
-
- The major modification I made is to introduce the "*64" interfaces in
- the MacroAssembler for those operations on JSValues, keep the "*Ptr"
- interfaces for those operations on real pointers, and go through all
- the JIT compiler code to correct the usage.
-
- This is the first part of the work, i.e, to add the *64 interfaces to
- the MacroAssembler.
-
- * assembler/AbstractMacroAssembler.h: Add the Imm64 interfaces.
- (AbstractMacroAssembler):
- (JSC::AbstractMacroAssembler::TrustedImm64::TrustedImm64):
- (TrustedImm64):
- (JSC::AbstractMacroAssembler::Imm64::Imm64):
- (Imm64):
- (JSC::AbstractMacroAssembler::Imm64::asTrustedImm64):
- * assembler/MacroAssembler.h: map <foo>Ptr methods to <foo>64 for X86_64.
- (MacroAssembler):
- (JSC::MacroAssembler::peek64):
- (JSC::MacroAssembler::poke):
- (JSC::MacroAssembler::poke64):
- (JSC::MacroAssembler::addPtr):
- (JSC::MacroAssembler::andPtr):
- (JSC::MacroAssembler::negPtr):
- (JSC::MacroAssembler::orPtr):
- (JSC::MacroAssembler::rotateRightPtr):
- (JSC::MacroAssembler::subPtr):
- (JSC::MacroAssembler::xorPtr):
- (JSC::MacroAssembler::loadPtr):
- (JSC::MacroAssembler::loadPtrWithAddressOffsetPatch):
- (JSC::MacroAssembler::loadPtrWithCompactAddressOffsetPatch):
- (JSC::MacroAssembler::storePtr):
- (JSC::MacroAssembler::storePtrWithAddressOffsetPatch):
- (JSC::MacroAssembler::movePtrToDouble):
- (JSC::MacroAssembler::moveDoubleToPtr):
- (JSC::MacroAssembler::comparePtr):
- (JSC::MacroAssembler::testPtr):
- (JSC::MacroAssembler::branchPtr):
- (JSC::MacroAssembler::branchTestPtr):
- (JSC::MacroAssembler::branchAddPtr):
- (JSC::MacroAssembler::branchSubPtr):
- (JSC::MacroAssembler::shouldBlindDouble):
- (JSC::MacroAssembler::shouldBlind):
- (JSC::MacroAssembler::RotatedImm64::RotatedImm64):
- (RotatedImm64):
- (JSC::MacroAssembler::rotationBlindConstant):
- (JSC::MacroAssembler::loadRotationBlindedConstant):
- (JSC::MacroAssembler::move):
- (JSC::MacroAssembler::and64):
- (JSC::MacroAssembler::store64):
- * assembler/MacroAssemblerX86Common.h:
- (JSC::MacroAssemblerX86Common::shouldBlindForSpecificArch):
- (MacroAssemblerX86Common):
- (JSC::MacroAssemblerX86Common::move):
- * assembler/MacroAssemblerX86_64.h: Add the <foo>64 methods for X86_64.
- (JSC::MacroAssemblerX86_64::branchAdd32):
- (JSC::MacroAssemblerX86_64::add64):
- (MacroAssemblerX86_64):
- (JSC::MacroAssemblerX86_64::and64):
- (JSC::MacroAssemblerX86_64::neg64):
- (JSC::MacroAssemblerX86_64::or64):
- (JSC::MacroAssemblerX86_64::rotateRight64):
- (JSC::MacroAssemblerX86_64::sub64):
- (JSC::MacroAssemblerX86_64::xor64):
- (JSC::MacroAssemblerX86_64::load64):
- (JSC::MacroAssemblerX86_64::load64WithAddressOffsetPatch):
- (JSC::MacroAssemblerX86_64::load64WithCompactAddressOffsetPatch):
- (JSC::MacroAssemblerX86_64::store64):
- (JSC::MacroAssemblerX86_64::store64WithAddressOffsetPatch):
- (JSC::MacroAssemblerX86_64::move64ToDouble):
- (JSC::MacroAssemblerX86_64::moveDoubleTo64):
- (JSC::MacroAssemblerX86_64::compare64):
- (JSC::MacroAssemblerX86_64::branch64):
- (JSC::MacroAssemblerX86_64::branchTest64):
- (JSC::MacroAssemblerX86_64::test64):
- (JSC::MacroAssemblerX86_64::branchAdd64):
- (JSC::MacroAssemblerX86_64::branchSub64):
- (JSC::MacroAssemblerX86_64::branchPtrWithPatch):
- (JSC::MacroAssemblerX86_64::storePtrWithPatch):
-
-2012-10-15 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Make CopiedSpace and MarkedSpace regions independent
- https://bugs.webkit.org/show_bug.cgi?id=99222
-
- Reviewed by Filip Pizlo.
-
- Right now CopiedSpace and MarkedSpace have the same block size and share the same regions,
- but there's no reason that they can't have different block sizes while still sharing the
- same underlying regions. We should factor the two "used" lists of regions apart so that
- MarkedBlocks and CopiedBlocks can be different sizes. Regions will still be a uniform size
- so that when they become empty they may be shared between the CopiedSpace and the MarkedSpace,
- since benchmarks indicate that sharing is a boon for performance.
-
- * heap/BlockAllocator.cpp:
- (JSC::BlockAllocator::BlockAllocator):
- * heap/BlockAllocator.h:
- (JSC):
- (Region):
- (JSC::Region::create): We now have a fixed size for Regions so that empty regions can continue to
- be shared between the MarkedSpace and CopiedSpace. Once they are used for a specific type of block,
- however, they can only be used for that type of block until they become empty again.
- (JSC::Region::createCustomSize):
- (JSC::Region::Region):
- (JSC::Region::~Region):
- (JSC::Region::reset):
- (BlockAllocator):
- (JSC::BlockAllocator::RegionSet::RegionSet):
- (RegionSet):
- (JSC::BlockAllocator::tryAllocateFromRegion): We change this function so that it correctly
- moves blocks between empty, partial, and full lists.
- (JSC::BlockAllocator::allocate):
- (JSC::BlockAllocator::allocateCustomSize):
- (JSC::BlockAllocator::deallocate): Ditto.
- (JSC::CopiedBlock):
- (JSC::MarkedBlock):
- (JSC::BlockAllocator::regionSetFor): We use this so that we can use the same allocate/deallocate
- functions with different RegionSets. We specialize the function for each type of block that we
- want to allocate.
- * heap/CopiedBlock.h:
- (CopiedBlock):
- * heap/CopiedSpace.h:
- (CopiedSpace):
- * heap/HeapBlock.h:
- (HeapBlock):
- * heap/MarkedBlock.cpp:
- (JSC::MarkedBlock::MarkedBlock): For oversize MarkedBlocks, if the block size gets too big we can
- underflow the endAtom, which will cause us to segfault when we try to sweep a block. If we're a
- custom size MarkedBlock we need to calculate endAtom so it doesn't underflow.
-
-2012-10-14 Filip Pizlo <fpizlo@apple.com>
-
- JIT::JIT fails to initialize all of its fields
- https://bugs.webkit.org/show_bug.cgi?id=99283
-
- Reviewed by Andreas Kling.
-
- There were two groups of such fields, all of which are eventually initialized
- prior to use inside of privateCompile(). But it's safer to make sure that they
- are initialized in the constructor as well, since we may use the JIT to do a
- stub compile without calling into privateCompile().
-
- Unsigned index fields for dynamic repatching meta-data: this change
- initializes them to UINT_MAX, so we should crash if we try to use those
- indices without initializing them.
-
- Boolean flags for value profiling: this change initializes them to false, so
- we at worst turn off value profiling.
-
- * jit/JIT.cpp:
- (JSC::JIT::JIT):
-
-2012-10-15 Mark Hahnenberg <mhahnenberg@apple.com>
-
- We should avoid weakCompareAndSwap when parallel GC is disabled
- https://bugs.webkit.org/show_bug.cgi?id=99331
-
- Reviewed by Filip Pizlo.
-
- CopiedBlock::reportLiveBytes and didEvacuateBytes uses weakCompareAndSwap, which some platforms
- don't support. For platforms that don't have parallel GC enabled, we should just use a normal store.
-
- * heap/CopiedBlock.h:
- (JSC::CopiedBlock::reportLiveBytes):
- (JSC::CopiedBlock::didEvacuateBytes):
-
-2012-10-15 Carlos Garcia Campos <cgarcia@igalia.com>
-
- Unreviewed. Fix make distcheck.
-
- * GNUmakefile.list.am: Add missing header file.
-
-2012-10-14 Filip Pizlo <fpizlo@apple.com>
-
- DFG should handle polymorphic array modes by eagerly transforming arrays into the most general applicable form
- https://bugs.webkit.org/show_bug.cgi?id=99269
-
- Reviewed by Geoffrey Garen.
-
- This kills off a bunch of code for "polymorphic" array modes in the DFG. It should
- also be a performance win for code that uses a lot of array storage arrays.
-
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::fromObserved):
- (JSC::DFG::modeAlreadyChecked):
- (JSC::DFG::modeToString):
- * dfg/DFGArrayMode.h:
- (DFG):
- (JSC::DFG::modeUsesButterfly):
- (JSC::DFG::modeIsJSArray):
- (JSC::DFG::mayStoreToTail):
- (JSC::DFG::mayStoreToHole):
- (JSC::DFG::canCSEStorage):
- (JSC::DFG::modeSupportsLength):
- (JSC::DFG::benefitsFromStructureCheck):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::checkArray):
- (JSC::DFG::FixupPhase::blessArrayOperation):
- * dfg/DFGGraph.h:
- (JSC::DFG::Graph::byValIsPure):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::arrayify):
- (DFG):
- (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
- (SpeculativeJIT):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-14 Filip Pizlo <fpizlo@apple.com>
-
- REGRESSION(126886): Fat binary builds don't know how to handle architecture variants to which the LLInt is agnostic
- https://bugs.webkit.org/show_bug.cgi?id=99270
-
- Reviewed by Geoffrey Garen.
-
- The fix is to hash cons the offsets based on configuration index, not the offsets
- themselves.
-
- * offlineasm/offsets.rb:
-
-2012-10-13 Filip Pizlo <fpizlo@apple.com>
-
- IndexingType should not have a bit for each type
- https://bugs.webkit.org/show_bug.cgi?id=98997
-
- Reviewed by Oliver Hunt.
-
- Somewhat incidentally, the introduction of butterflies led to each indexing
- type being represented by a unique bit. This is superficially nice since it
- allows you to test if a structure corresponds to a particular indexing type
- by saying !!(structure->indexingType() & TheType). But the downside is that
- given the 8 bits we have for the m_indexingType field, that leaves only a
- small number of possible indexing types if we have one per bit.
-
- This changeset changes the indexing type to be:
-
- Bit #1: Tells you if you're an array.
-
- Bits #2 - #5: 16 possible indexing types, including the blank type for
- objects that don't have indexed properties.
-
- Bits #6-8: Auxiliary bits that we could use for other things. Currently we
- just use one of those bits, for MayHaveIndexedAccessors.
-
- This is performance-neutral, and is primarily intended to give us more
- breathing room for introducing new inferred array modes.
-
- * assembler/AbstractMacroAssembler.h:
- (JSC::AbstractMacroAssembler::JumpList::jumps):
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- (JSC::MacroAssembler::patchableBranch32):
- * assembler/MacroAssemblerARMv7.h:
- (JSC::MacroAssemblerARMv7::patchableBranch32):
- (MacroAssemblerARMv7):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::modeAlreadyChecked):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::speculationCheck):
- (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
- (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
- (DFG):
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::arrayify):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * jit/JITInlineMethods.h:
- (JSC::JIT::emitAllocateJSArray):
- (JSC::JIT::chooseArrayMode):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emitArrayStorageGetByVal):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::emitContiguousPutByVal):
- (JSC::JIT::emitArrayStoragePutByVal):
- (JSC::JIT::privateCompilePatchGetArrayLength):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emitArrayStorageGetByVal):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::emitContiguousPutByVal):
- (JSC::JIT::emitArrayStoragePutByVal):
- (JSC::JIT::privateCompilePatchGetArrayLength):
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * runtime/IndexingType.h:
- (JSC):
- (JSC::hasIndexedProperties):
- (JSC::hasContiguous):
- (JSC::hasFastArrayStorage):
- (JSC::hasArrayStorage):
- (JSC::shouldUseSlowPut):
- * runtime/JSGlobalObject.cpp:
- (JSC):
- * runtime/StructureTransitionTable.h:
- (JSC::newIndexingType):
-
-2012-10-14 Filip Pizlo <fpizlo@apple.com>
-
- DFG structure check hoisting should attempt to ignore side effects and make transformations that are sound even in their presence
- https://bugs.webkit.org/show_bug.cgi?id=99262
-
- Reviewed by Oliver Hunt.
-
- This hugely simplifies the structure check hoisting phase. It will no longer be necessary
- to modify it when the effectfulness of operations changes. This also enables the hoister
- to hoist effectful things in the future.
-
- The downside is that the hoister may end up adding strictly more checks than were present
- in the original code, if the code truly has a lot of side-effects. I don't see evidence
- of this happening. This patch does have some speed-ups and some slow-downs, but is
- neutral in the average, and the slow-downs do not appear to have more structure checks
- than ToT.
-
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck):
- (StructureCheckHoistingPhase):
- (CheckData):
- (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData):
-
-2012-10-14 Filip Pizlo <fpizlo@apple.com>
-
- Fix the build of universal binary with ARMv7s of JavaScriptCore
-
- * llint/LLIntOfflineAsmConfig.h:
- * llint/LowLevelInterpreter.asm:
-
-2012-10-13 Filip Pizlo <fpizlo@apple.com>
-
- Array length array profiling is broken in the baseline JIT
- https://bugs.webkit.org/show_bug.cgi?id=99258
-
- Reviewed by Oliver Hunt.
-
- The code generator for array length stubs calls into
- emitArrayProfilingSiteForBytecodeIndex(), which emits profiling only if
- canBeOptimized() returns true. But m_canBeOptimized is only initialized during
- full method compiles, so in a stub compile it may (or may not) be false, meaning
- that we may, or may not, get meaningful profiling info.
-
- This appeared to not affect too many programs since the LLInt has good array
- length array profiling.
-
- * jit/JIT.h:
- (JSC::JIT::compilePatchGetArrayLength):
-
-2012-10-14 Patrick Gansterer <paroga@webkit.org>
-
- Build fix for WinCE after r131089.
-
- WinCE does not support getenv().
-
- * runtime/Options.cpp:
- (JSC::overrideOptionWithHeuristic):
-
-2012-10-12 Kangil Han <kangil.han@samsung.com>
-
- Fix build error on DFGSpeculativeJIT32_64.cpp
- https://bugs.webkit.org/show_bug.cgi?id=99234
-
- Reviewed by Anders Carlsson.
-
- Seems BUG 98608 causes build error on 32bit machine so fix it.
-
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-12 Filip Pizlo <fpizlo@apple.com>
-
- Contiguous array allocation should always be inlined
- https://bugs.webkit.org/show_bug.cgi?id=98608
-
- Reviewed by Oliver Hunt and Mark Hahnenberg.
-
- This inlines contiguous array allocation in the most obvious way possible.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * assembler/MacroAssembler.h:
- (JSC::MacroAssembler::branchSubPtr):
- (MacroAssembler):
- * assembler/MacroAssemblerX86_64.h:
- (JSC::MacroAssemblerX86_64::branchSubPtr):
- (MacroAssemblerX86_64):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGCCallHelpers.h:
- (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
- (CCallHelpers):
- * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: Added.
- (DFG):
- (CallArrayAllocatorSlowPathGenerator):
- (JSC::DFG::CallArrayAllocatorSlowPathGenerator::CallArrayAllocatorSlowPathGenerator):
- (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal):
- (CallArrayAllocatorWithVariableSizeSlowPathGenerator):
- (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableSizeSlowPathGenerator):
- (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
- (DFG):
- (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
- (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::callOperation):
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
- (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
- (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Race condition during CopyingPhase can lead to deadlock
- https://bugs.webkit.org/show_bug.cgi?id=99226
-
- Reviewed by Filip Pizlo.
-
- The main thread calls startCopying() for each of the GCThreads at the beginning of the copy phase.
- It then proceeds to start copying. If copying completes before one of the GCThreads wakes up, the
- main thread will set m_currentPhase back to NoPhase, the GCThread will wake up, see that there's
- nothing to do, and then it will go back to sleep without ever calling CopyVisitor::doneCopying()
- to return its borrowed block to the CopiedSpace. CopiedSpace::doneCopying() will then sleep forever
- waiting on the block.
-
- The fix for this is to make sure we call CopiedSpace::doneCopying() on the main thread before we
- call GCThreadSharedData::didFinishCopying(), which sets the m_currentPhase flag to NoPhase. This
- way we will wait until all threads have woken up and given back their borrowed blocks before
- clearing the flag.
-
- * heap/Heap.cpp:
- (JSC::Heap::copyBackingStores):
-
-2012-10-12 Anders Carlsson <andersca@apple.com>
-
- Move macros from Parser.h to Parser.cpp
- https://bugs.webkit.org/show_bug.cgi?id=99217
-
- Reviewed by Andreas Kling.
-
- There are a bunch of macros in Parser.h that are only used in Parser.cpp. Move them to Parser.cpp
- so they won't pollute the global namespace.
- * parser/Parser.cpp:
- * parser/Parser.h:
- (JSC):
-
-2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Another build fix after r131213
-
- Added some symbol magic to placate the linker on some platforms.
-
- * JavaScriptCore.order:
-
-2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Build fix after r131213
-
- Removed an unused variable that was making compilers unhappy.
-
- * heap/GCThread.cpp:
- (JSC::GCThread::GCThread):
- * heap/GCThread.h:
- (GCThread):
- * heap/GCThreadSharedData.cpp:
- (JSC::GCThreadSharedData::GCThreadSharedData):
-
-2012-10-09 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Copying collection shouldn't require O(live bytes) memory overhead
- https://bugs.webkit.org/show_bug.cgi?id=98792
-
- Reviewed by Filip Pizlo.
-
- Currently our copying collection occurs simultaneously with the marking phase. We'd like
- to be able to reuse CopiedBlocks as soon as they become fully evacuated, but this is not
- currently possible because we don't know the liveness statistics of each old CopiedBlock
- until marking/copying has already finished. Instead, we have to allocate additional memory
- from the OS to use as our working set of CopiedBlocks while copying. We then return the
- fully evacuated old CopiedBlocks back to the block allocator, thus giving our copying phase
- an O(live bytes) overhead.
-
- To fix this, we should instead split the copying phase apart from the marking phase. This
- way we have full liveness data for each CopiedBlock during the copying phase so that we
- can reuse them the instant they become fully evacuated. With the additional liveness data
- that each CopiedBlock accumulates, we can add some additional heuristics to the collector.
- For example, we can calculate our global Heap fragmentation and only choose to do a copying
- phase if that fragmentation exceeds some limit. As another example, we can skip copying
- blocks that are already above a particular fragmentation limit, which allows older objects
- to coalesce into blocks that are rarely copied.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * heap/CopiedBlock.h:
- (CopiedBlock):
- (JSC::CopiedBlock::CopiedBlock): Added support for tracking live bytes in a CopiedBlock in a
- thread-safe fashion.
- (JSC::CopiedBlock::reportLiveBytes): Adds a number of live bytes to the block in a thread-safe
- fashion using compare and swap.
- (JSC):
- (JSC::CopiedBlock::didSurviveGC): Called when a block survives a single GC without being
- evacuated. This could be called for a couple reasons: (a) the block was pinned or (b) we
- decided not to do any copying. A block can become pinned for a few reasons: (1) a pointer into
- the block was found during the conservative scan. (2) the block was deemed full enough to
- not warrant any copying. (3) The block is oversize and was found to be live.
- (JSC::CopiedBlock::didEvacuateBytes): Called when some number of bytes are copied from this
- block. If the number of live bytes ever hits zero, the block will return itself to the
- BlockAllocator to be recycled.
- (JSC::CopiedBlock::canBeRecycled): Indicates that a block has no live bytes and can be
- immediately recycled. This is used for blocks that are found to have zero live bytes at the
- beginning of the copying phase.
- (JSC::CopiedBlock::shouldEvacuate): This function returns true if the current fragmentation
- of the block is above our fragmentation threshold, and false otherwise.
- (JSC::CopiedBlock::isPinned): Added an accessor for the pinned flag
- (JSC::CopiedBlock::liveBytes):
- * heap/CopiedSpace.cpp:
- (JSC::CopiedSpace::CopiedSpace):
- (JSC::CopiedSpace::doneFillingBlock): Changed so that we can exchange our filled block for a
- fresh block. This avoids the situation where a thread returns its borrowed block, it's the last
- borrowed block, so CopiedSpace thinks that copying has completed, and it starts doing all of the
- copying phase cleanup. In actuality, the thread wanted another block after returning the current
- block. So we allow the thread to atomically exchange its block for another block.
- (JSC::CopiedSpace::startedCopying): Added the calculation of global Heap fragmentation to
- determine if the copying phase should commence. We include the MarkedSpace in our fragmentation
- calculation by assuming that the MarkedSpace is 0% fragmented since we can reuse any currently
- free memory in it (i.e. we ignore any internal fragmentation in the MarkedSpace). While we're
- calculating the fragmentation of CopiedSpace, we also return any free blocks we find along the
- way (meaning liveBytes() == 0).
- (JSC):
- (JSC::CopiedSpace::doneCopying): We still have to iterate over all the blocks, regardless of
- whether the copying phase took place or not so that we can reset all of the live bytes counters
- and un-pin any pinned blocks.
- * heap/CopiedSpace.h:
- (CopiedSpace):
- (JSC::CopiedSpace::shouldDoCopyPhase):
- * heap/CopiedSpaceInlineMethods.h:
- (JSC::CopiedSpace::recycleEvacuatedBlock): This function is distinct from recycling a borrowed block
- because a borrowed block hasn't been added to the CopiedSpace yet, but an evacuated block is still
- currently in CopiedSpace, so we have to make sure we properly remove all traces of the block from
- CopiedSpace before returning it to BlockAllocator.
- (JSC::CopiedSpace::recycleBorrowedBlock): Renamed to indicate the distinction mentioned above.
- * heap/CopyVisitor.cpp: Added.
- (JSC):
- (JSC::CopyVisitor::CopyVisitor):
- (JSC::CopyVisitor::copyFromShared): Main function for any thread participating in the copying phase.
- Grabs chunks of MarkedBlocks from the shared list and copies the backing store of anybody who needs
- it until there are no more chunks to copy.
- * heap/CopyVisitor.h: Added.
- (JSC):
- (CopyVisitor):
- * heap/CopyVisitorInlineMethods.h: Added.
- (JSC):
- (GCCopyPhaseFunctor):
- (JSC::GCCopyPhaseFunctor::GCCopyPhaseFunctor):
- (JSC::GCCopyPhaseFunctor::operator()):
- (JSC::CopyVisitor::checkIfShouldCopy): We don't have to check shouldEvacuate() because all of those
- checks are done during the marking phase.
- (JSC::CopyVisitor::allocateNewSpace):
- (JSC::CopyVisitor::allocateNewSpaceSlow):
- (JSC::CopyVisitor::startCopying): Initialization function for a thread that is about to start copying.
- (JSC::CopyVisitor::doneCopying):
- (JSC::CopyVisitor::didCopy): This callback is called by an object that has just successfully copied its
- backing store. It indicates to the CopiedBlock that somebody has just finished evacuating some number of
- bytes from it, and, if the CopiedBlock now has no more live bytes, can be recycled immediately.
- * heap/GCThread.cpp: Added.
- (JSC):
- (JSC::GCThread::GCThread): This is a new class that encapsulates a single thread responsible for participating
- in a specific set of GC phases. Currently, that set of phases includes Mark, Copy, and Exit. Each thread
- monitors a shared variable in its associated GCThreadSharedData. The main thread updates this m_currentPhase
- variable as collection progresses through the various phases. Parallel marking still works exactly like it
- has. In other words, the "run loop" for each of the GC threads sits above any individual phase, thus keeping
- the separate phases of the collector orthogonal.
- (JSC::GCThread::threadID):
- (JSC::GCThread::initializeThreadID):
- (JSC::GCThread::slotVisitor):
- (JSC::GCThread::copyVisitor):
- (JSC::GCThread::waitForNextPhase):
- (JSC::GCThread::gcThreadMain):
- (JSC::GCThread::gcThreadStartFunc):
- * heap/GCThread.h: Added.
- (JSC):
- (GCThread):
- * heap/GCThreadSharedData.cpp: The GCThreadSharedData now has a list of GCThread objects rather than raw
- ThreadIdentifiers.
- (JSC::GCThreadSharedData::resetChildren):
- (JSC::GCThreadSharedData::childVisitCount):
- (JSC::GCThreadSharedData::GCThreadSharedData):
- (JSC::GCThreadSharedData::~GCThreadSharedData):
- (JSC::GCThreadSharedData::reset):
- (JSC::GCThreadSharedData::didStartMarking): Callback to let the GCThreadSharedData know that marking has
- started and updates the m_currentPhase variable and notifies the GCThreads accordingly.
- (JSC::GCThreadSharedData::didFinishMarking): Ditto for finishing marking.
- (JSC::GCThreadSharedData::didStartCopying): Ditto for starting the copying phase.
- (JSC::GCThreadSharedData::didFinishCopying): Ditto for finishing copying.
- * heap/GCThreadSharedData.h:
- (JSC):
- (GCThreadSharedData):
- (JSC::GCThreadSharedData::getNextBlocksToCopy): Atomically gets the next chunk of work for a copying thread.
- * heap/Heap.cpp:
- (JSC::Heap::Heap):
- (JSC::Heap::markRoots):
- (JSC):
- (JSC::Heap::copyBackingStores): Responsible for setting up the copying phase, notifying the copying threads,
- and doing any copying work if necessary.
- (JSC::Heap::collect):
- * heap/Heap.h:
- (Heap):
- (JSC):
- (JSC::CopyFunctor::CopyFunctor):
- (CopyFunctor):
- (JSC::CopyFunctor::operator()):
- * heap/IncrementalSweeper.cpp: Changed the incremental sweeper to have a reference to the list of MarkedBlocks
- that need sweeping, since this now resides in the Heap so that it can be easily shared by the GCThreads.
- (JSC::IncrementalSweeper::IncrementalSweeper):
- (JSC::IncrementalSweeper::startSweeping):
- * heap/IncrementalSweeper.h:
- (JSC):
- (IncrementalSweeper):
- * heap/SlotVisitor.cpp:
- (JSC::SlotVisitor::setup):
- (JSC::SlotVisitor::drainFromShared): We no longer do any copying-related work here.
- (JSC):
- * heap/SlotVisitor.h:
- (SlotVisitor):
- * heap/SlotVisitorInlineMethods.h:
- (JSC):
- (JSC::SlotVisitor::copyLater): Notifies the CopiedBlock that there are some live bytes that may need
- to be copied.
- * runtime/Butterfly.h:
- (JSC):
- (Butterfly):
- * runtime/ButterflyInlineMethods.h:
- (JSC::Butterfly::createUninitializedDuringCollection): Uses the new CopyVisitor.
- * runtime/ClassInfo.h:
- (MethodTable): Added new "virtual" function copyBackingStore to method table.
- (JSC):
- * runtime/JSCell.cpp:
- (JSC::JSCell::copyBackingStore): Default implementation that does nothing.
- (JSC):
- * runtime/JSCell.h:
- (JSC):
- (JSCell):
- * runtime/JSObject.cpp:
- (JSC::JSObject::copyButterfly): Does the actual copying of the butterfly.
- (JSC):
- (JSC::JSObject::visitButterfly): Calls copyLater for the butterfly.
- (JSC::JSObject::copyBackingStore):
- * runtime/JSObject.h:
- (JSObject):
- (JSC::JSCell::methodTable):
- (JSC::JSCell::inherits):
- * runtime/Options.h: Added two new constants, minHeapUtilization and minCopiedBlockUtilization,
- to govern the amount of fragmentation we allow before doing copying.
- (JSC):
-
-2012-10-12 Filip Pizlo <fpizlo@apple.com>
-
- DFG array allocation calls should not return an encoded JSValue
- https://bugs.webkit.org/show_bug.cgi?id=99196
-
- Reviewed by Mark Hahnenberg.
-
- The array allocation operations now return a pointer instead. This makes it
- easier to share code between 32-bit and 64-bit.
-
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-01 Jer Noble <jer.noble@apple.com>
-
- Enable ENCRYPTED_MEDIA support on Mac.
- https://bugs.webkit.org/show_bug.cgi?id=98044
-
- Reviewed by Anders Carlsson.
-
- Enable the ENCRYPTED_MEDIA flag.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-12 Filip Pizlo <fpizlo@apple.com>
-
- Unreviewed. It should be possible to build JSC on ARMv7.
-
- * assembler/MacroAssemblerARMv7.h:
- (JSC::MacroAssemblerARMv7::patchableBranchPtr):
-
-2012-10-11 Mark Hahnenberg <mhahnenberg@apple.com>
-
- BlockAllocator should use regions as its VM allocation abstraction
- https://bugs.webkit.org/show_bug.cgi?id=99107
-
- Reviewed by Geoffrey Garen.
-
- Currently the BlockAllocator allocates a single block at a time directly from the OS. Our block
- allocations are on the large-ish side (64 KB) to amortize across many allocations the expense of
- mapping new virtual memory from the OS. These large blocks are then shared between the MarkedSpace
- and the CopiedSpace. This design makes it difficult to vary the size of the blocks in different
- parts of the Heap while still allowing us to amortize the VM allocation costs.
-
- We should redesign the BlockAllocator so that it has a layer of indirection between blocks that are
- used by the allocator/collector and our primary unit of VM allocation from the OS. In particular,
- the BlockAllocator should allocate Regions of virtual memory from the OS, which are then subdivided
- into one or more Blocks to be used in our custom allocators. This design has the following nice properties:
-
- 1) We can remove the knowledge of PageAllocationAligned from HeapBlocks. Each HeapBlock will now
- only know what Region it belongs to. The Region maintains all the metadata for how to allocate
- and deallocate virtual memory from the OS.
-
- 2) We can easily allocate in larger chunks than we need to satisfy a particular request for a Block.
- We can then continue to amortize our VM allocation costs while allowing for smaller block sizes,
- which should increase locality in the mutator when allocating, lazy sweeping, etc.
-
- 3) By encapsulating the logic of where our memory comes from inside of the Region class, we can more
- easily transition over to allocating VM from a specific range of pre-reserved address space. This
- will be a necessary step along the way to 32-bit pointers.
-
- This particular patch will not change the size of MarkedBlocks or CopiedBlocks, nor will it change how
- much VM we allocate per failed Block request. It only sets up the data structures that we need to make
- these changes in future patches.
-
- Most of the changes in this patch relate to the addition of the Region class to be used by the
- BlockAllocator and the threading of changes made to BlockAllocator's interface through to the call sites.
-
- * heap/BlockAllocator.cpp: The BlockAllocator now has three lists that track the three disjoint sets of
- Regions that it cares about: empty regions, partially full regions, and completely full regions.
- Empty regions have no blocks currently in use and can be freed immediately if the freeing thread
- determines they should be. Partial regions have some blocks used, but aren't completely in use yet.
- These regions are preferred for recycling before empty regions to mitigate fragmentation within regions.
- Completely full regions are no longer able to be used for allocations. Regions move between these
- three lists as they are created and their constituent blocks are allocated and deallocated.
- (JSC::BlockAllocator::BlockAllocator):
- (JSC::BlockAllocator::~BlockAllocator):
- (JSC::BlockAllocator::releaseFreeRegions):
- (JSC::BlockAllocator::waitForRelativeTimeWhileHoldingLock):
- (JSC::BlockAllocator::waitForRelativeTime):
- (JSC::BlockAllocator::blockFreeingThreadMain):
- * heap/BlockAllocator.h:
- (JSC):
- (DeadBlock):
- (JSC::DeadBlock::DeadBlock):
- (Region):
- (JSC::Region::blockSize):
- (JSC::Region::isFull):
- (JSC::Region::isEmpty):
- (JSC::Region::create): This function is responsible for doing the actual VM allocation. This should be the
- only function in the entire JSC object runtime that calls out the OS for virtual memory allocation.
- (JSC::Region::Region):
- (JSC::Region::~Region):
- (JSC::Region::allocate):
- (JSC::Region::deallocate):
- (BlockAllocator):
- (JSC::BlockAllocator::tryAllocateFromRegion): Helper function that encapsulates checking a particular list
- of regions for a free block.
- (JSC::BlockAllocator::allocate):
- (JSC::BlockAllocator::allocateCustomSize): This function is responsible for allocating one-off custom size
- regions for use in oversize allocations in both the MarkedSpace and the CopiedSpace. These regions are not
- tracked by the BlockAllocator. The only pointer to them is in the HeapBlock that is returned. These regions
- contain exactly one block.
- (JSC::BlockAllocator::deallocate):
- (JSC::BlockAllocator::deallocateCustomSize): This function is responsible for deallocating one-off custom size
- regions. The regions are deallocated back to the OS eagerly.
- * heap/CopiedBlock.h: Re-worked CopiedBlocks to use Regions instead of PageAllocationAligned.
- (CopiedBlock):
- (JSC::CopiedBlock::createNoZeroFill):
- (JSC::CopiedBlock::create):
- (JSC::CopiedBlock::CopiedBlock):
- (JSC::CopiedBlock::payloadEnd):
- (JSC::CopiedBlock::capacity):
- * heap/CopiedSpace.cpp:
- (JSC::CopiedSpace::~CopiedSpace):
- (JSC::CopiedSpace::tryAllocateOversize):
- (JSC::CopiedSpace::tryReallocateOversize):
- (JSC::CopiedSpace::doneCopying):
- * heap/CopiedSpaceInlineMethods.h:
- (JSC::CopiedSpace::allocateBlockForCopyingPhase):
- (JSC::CopiedSpace::allocateBlock):
- * heap/HeapBlock.h:
- (JSC::HeapBlock::destroy):
- (JSC::HeapBlock::HeapBlock):
- (JSC::HeapBlock::region):
- (HeapBlock):
- * heap/MarkedAllocator.cpp:
- (JSC::MarkedAllocator::allocateBlock):
- * heap/MarkedBlock.cpp:
- (JSC::MarkedBlock::create):
- (JSC::MarkedBlock::MarkedBlock):
- * heap/MarkedBlock.h:
- (JSC::MarkedBlock::capacity):
- * heap/MarkedSpace.cpp:
- (JSC::MarkedSpace::freeBlock):
-
-2012-10-11 Filip Pizlo <fpizlo@apple.com>
-
- UInt32ToNumber and OSR exit should be aware of copy propagation and correctly recover both versions of a variable that was subject to a UInt32ToNumber cast
- https://bugs.webkit.org/show_bug.cgi?id=99100
- <rdar://problem/12480955>
-
- Reviewed by Michael Saboff and Mark Hahnenberg.
-
- Fixed by forcing UInt32ToNumber to use a different register. This "undoes" the copy propagation that we
- would have been doing, since it has no performance effect in this case and has the benefit of making the
- OSR exit compiler a lot simpler.
-
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
-
-2012-10-11 Geoffrey Garen <ggaren@apple.com>
-
- Removed some more static assumptions about inline object capacity
- https://bugs.webkit.org/show_bug.cgi?id=98603
-
- Reviewed by Filip Pizlo.
-
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): Use JSObject::allocationSize()
- for a little more flexibility. We still pass it a constant inline capacity
- because the JIT doesn't have a strategy for selecting a size class based
- on non-constant capacity yet. "INLINE_STORAGE_CAPACITY" is a marker for
- code that makes static assumptions about object size.
-
- * jit/JITInlineMethods.h:
- (JSC::JIT::emitAllocateBasicJSObject):
- * llint/LLIntData.cpp:
- (JSC::LLInt::Data::performAssertions):
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm: Ditto for the rest of our many execution engines.
-
- * runtime/JSObject.h:
- (JSC::JSObject::allocationSize):
- (JSC::JSFinalObject::finishCreation):
- (JSC::JSFinalObject::create): New helper function for computing object
- size dynamically, since we plan to have objects of different sizes.
-
- (JSC::JSFinalObject::JSFinalObject): Note that our m_inlineStorage used
- to auto-generate an implicit C++ constructor with default null initialization.
- This memory is not observed in its uninitialized state, and our LLInt and
- JIT allocators do not initialize it, so I did not add any explicit code
- to do so, now that the implicit code is gone.
-
- (JSC::JSObject::offsetOfInlineStorage): Changed the math here to match
- inlineStorageUnsafe(), since we can rely on an explicit data member anymore.
-
-2012-10-11 Geoffrey Garen <ggaren@apple.com>
-
- Enable RUNTIME_HEURISTICS all the time, for easier testing
- https://bugs.webkit.org/show_bug.cgi?id=99090
-
- Reviewed by Filip Pizlo.
-
- I find myself using this a lot, and there doesn't seem to be an obvious
- reason to compile it out, since it only runs once at startup.
-
- * runtime/Options.cpp:
- (JSC::overrideOptionWithHeuristic):
- (JSC::Options::initialize):
- * runtime/Options.h: Removed the #ifdef.
-
-2012-10-11 Geoffrey Garen <ggaren@apple.com>
-
- Removed ASSERT_CLASS_FITS_IN_CELL
- https://bugs.webkit.org/show_bug.cgi?id=97634
-
- Reviewed by Mark Hahnenberg.
-
- Our collector now supports arbitrarily sized objects, so the ASSERT is not needed.
-
- * API/JSCallbackFunction.cpp:
- * API/JSCallbackObject.cpp:
- * heap/MarkedSpace.h:
- * jsc.cpp:
- * runtime/Arguments.cpp:
- * runtime/ArrayConstructor.cpp:
- * runtime/ArrayPrototype.cpp:
- * runtime/BooleanConstructor.cpp:
- * runtime/BooleanObject.cpp:
- * runtime/BooleanPrototype.cpp:
- * runtime/DateConstructor.cpp:
- * runtime/DatePrototype.cpp:
- * runtime/Error.cpp:
- * runtime/ErrorConstructor.cpp:
- * runtime/ErrorPrototype.cpp:
- * runtime/FunctionConstructor.cpp:
- * runtime/FunctionPrototype.cpp:
- * runtime/InternalFunction.cpp:
- * runtime/JSActivation.cpp:
- * runtime/JSArray.cpp:
- * runtime/JSBoundFunction.cpp:
- * runtime/JSFunction.cpp:
- * runtime/JSGlobalObject.cpp:
- * runtime/JSGlobalThis.cpp:
- * runtime/JSNameScope.cpp:
- * runtime/JSNotAnObject.cpp:
- * runtime/JSONObject.cpp:
- * runtime/JSObject.cpp:
- * runtime/JSPropertyNameIterator.cpp:
- * runtime/JSScope.cpp:
- * runtime/JSWithScope.cpp:
- * runtime/JSWrapperObject.cpp:
- * runtime/MathObject.cpp:
- * runtime/NameConstructor.cpp:
- * runtime/NamePrototype.cpp:
- * runtime/NativeErrorConstructor.cpp:
- * runtime/NativeErrorPrototype.cpp:
- * runtime/NumberConstructor.cpp:
- * runtime/NumberObject.cpp:
- * runtime/NumberPrototype.cpp:
- * runtime/ObjectConstructor.cpp:
- * runtime/ObjectPrototype.cpp:
- * runtime/RegExpConstructor.cpp:
- * runtime/RegExpMatchesArray.cpp:
- * runtime/RegExpObject.cpp:
- * runtime/RegExpPrototype.cpp:
- * runtime/StringConstructor.cpp:
- * runtime/StringObject.cpp:
- * runtime/StringPrototype.cpp:
- * testRegExp.cpp: Removed the ASSERT.
-
-2012-10-11 Filip Pizlo <fpizlo@apple.com>
-
- DFG should inline code blocks that use new_array_buffer
- https://bugs.webkit.org/show_bug.cgi?id=98996
-
- Reviewed by Geoffrey Garen.
-
- This adds plumbing to drop in constant buffers from the inlinees to the inliner.
- It's smart about not duplicating buffers needlessly but doesn't try to completely
- hash-cons them, either.
-
- * bytecode/CodeBlock.h:
- (JSC::CodeBlock::numberOfConstantBuffers):
- (JSC::CodeBlock::addConstantBuffer):
- (JSC::CodeBlock::constantBufferAsVector):
- (JSC::CodeBlock::constantBuffer):
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGByteCodeParser.cpp:
- (ConstantBufferKey):
- (JSC::DFG::ConstantBufferKey::ConstantBufferKey):
- (JSC::DFG::ConstantBufferKey::operator==):
- (JSC::DFG::ConstantBufferKey::hash):
- (JSC::DFG::ConstantBufferKey::isHashTableDeletedValue):
- (JSC::DFG::ConstantBufferKey::codeBlock):
- (JSC::DFG::ConstantBufferKey::index):
- (DFG):
- (JSC::DFG::ConstantBufferKeyHash::hash):
- (JSC::DFG::ConstantBufferKeyHash::equal):
- (ConstantBufferKeyHash):
- (WTF):
- (ByteCodeParser):
- (InlineStackEntry):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGCapabilities.h:
- (JSC::DFG::canInlineOpcode):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGSpeculativeJIT.h:
- (JSC::DFG::SpeculativeJIT::callOperation):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
-
-2012-10-10 Zoltan Horvath <zoltan@webkit.org>
-
- Pageload tests should measure memory usage
- https://bugs.webkit.org/show_bug.cgi?id=93958
-
- Reviewed by Ryosuke Niwa.
-
- Add JS Heap and Heap memory measurement to PageLoad tests.
-
- * heap/HeapStatistics.cpp:
- (JSC::HeapStatistics::usedJSHeap): Add new private function to expose the used JS Heap size.
- (JSC):
- * heap/HeapStatistics.h:
- (HeapStatistics): Add new private function to expose the used JS Heap size.
-
-2012-10-10 Balazs Kilvady <kilvadyb@homejinni.com>
-
- RegisterFile to JSStack rename fix for a struct member.
-
- Compilation problem in debug build on MIPS
- https://bugs.webkit.org/show_bug.cgi?id=98808
-
- Reviewed by Alexey Proskuryakov.
-
- In ASSERT conditions structure field name "registerFile" was replaced
- with type name "JSStack" and it should be "stack".
-
- * jit/JITStubs.cpp:
- (JSC::JITThunks::JITThunks): structure member name fix.
-
-2012-10-10 Michael Saboff <msaboff@apple.com>
-
- After r130344, OpaqueJSString::string() shouldn't directly return the wrapped String
- https://bugs.webkit.org/show_bug.cgi?id=98801
-
- Reviewed by Geoffrey Garen.
-
- Return a copy of the wrapped String so that the wrapped string cannot be turned into
- an Identifier.
-
- * API/OpaqueJSString.cpp:
- (OpaqueJSString::string):
- * API/OpaqueJSString.h:
- (OpaqueJSString):
-
-2012-10-10 Peter Gal <galpeter@inf.u-szeged.hu>
-
- Add moveDoubleToInts and moveIntsToDouble to MacroAssemblerARM
- https://bugs.webkit.org/show_bug.cgi?id=98855
-
- Reviewed by Filip Pizlo.
-
- Implement the missing moveDoubleToInts and moveIntsToDouble
- methods in the MacroAssemblerARM after r130839.
-
- * assembler/MacroAssemblerARM.h:
- (JSC::MacroAssemblerARM::moveDoubleToInts):
- (MacroAssemblerARM):
- (JSC::MacroAssemblerARM::moveIntsToDouble):
-
-2012-10-09 Filip Pizlo <fpizlo@apple.com>
-
- Typed arrays should not be 20x slower in the baseline JIT than in the DFG JIT
- https://bugs.webkit.org/show_bug.cgi?id=98605
-
- Reviewed by Oliver Hunt and Gavin Barraclough.
-
- This adds typed array get_by_val/put_by_val patching to the baseline JIT. It's
- a big (~40%) win on benchmarks that have trouble staying in the DFG JIT. Even
- if we fix those benchmarks, this functionality gives us the insurance that we
- typically desire with all speculative optimizations: even if we bail to
- baseline, we're still reasonably performant.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * assembler/MacroAssembler.cpp: Added.
- (JSC):
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- (JSC::MacroAssembler::patchableBranchPtr):
- * assembler/MacroAssemblerARMv7.h:
- (MacroAssemblerARMv7):
- (JSC::MacroAssemblerARMv7::moveDoubleToInts):
- (JSC::MacroAssemblerARMv7::moveIntsToDouble):
- (JSC::MacroAssemblerARMv7::patchableBranchPtr):
- * assembler/MacroAssemblerX86.h:
- (MacroAssemblerX86):
- (JSC::MacroAssemblerX86::moveDoubleToInts):
- (JSC::MacroAssemblerX86::moveIntsToDouble):
- * bytecode/ByValInfo.h:
- (JSC::hasOptimizableIndexingForClassInfo):
- (JSC):
- (JSC::hasOptimizableIndexing):
- (JSC::jitArrayModeForClassInfo):
- (JSC::jitArrayModeForStructure):
- (JSC::ByValInfo::ByValInfo):
- (ByValInfo):
- * dfg/DFGAssemblyHelpers.cpp:
- (DFG):
- * dfg/DFGAssemblyHelpers.h:
- (AssemblyHelpers):
- (JSC::DFG::AssemblyHelpers::boxDouble):
- (JSC::DFG::AssemblyHelpers::unboxDouble):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
- (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- * jit/JIT.h:
- (JIT):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::privateCompileGetByVal):
- (JSC::JIT::privateCompilePutByVal):
- (JSC::JIT::emitIntTypedArrayGetByVal):
- (JSC):
- (JSC::JIT::emitFloatTypedArrayGetByVal):
- (JSC::JIT::emitIntTypedArrayPutByVal):
- (JSC::JIT::emitFloatTypedArrayPutByVal):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC::JIT::emit_op_put_by_val):
- * jit/JITStubs.cpp:
- (JSC::DEFINE_STUB_FUNCTION):
- * runtime/JSCell.h:
- * runtime/JSGlobalData.h:
- (JSGlobalData):
- (JSC::JSGlobalData::typedArrayDescriptor):
- * runtime/TypedArrayDescriptor.h: Added.
- (JSC):
- (JSC::TypedArrayDescriptor::TypedArrayDescriptor):
- (TypedArrayDescriptor):
-
-2012-10-09 Michael Saboff <msaboff@apple.com>
-
- Add tests to testapi for null OpaqueJSStrings
- https://bugs.webkit.org/show_bug.cgi?id=98805
-
- Reviewed by Geoffrey Garen.
-
- Added tests that check that OpaqueJSString, which is wrapped via JSStringRef, properly returns
- null strings and that a null string in a JSStringRef will return a NULL JSChar* and 0 length
- via the JSStringGetCharactersPtr() and JSStringGetLength() APIs respectively. Added a check that
- JSValueMakeFromJSONString() properly handles a null string as well.
-
- * API/tests/testapi.c:
- (main):
-
-2012-10-09 Jian Li <jianli@chromium.org>
-
- Update the CSS property used to support draggable regions.
- https://bugs.webkit.org/show_bug.cgi?id=97156
-
- Reviewed by Adam Barth.
-
- The CSS property to support draggable regions, guarded under
- WIDGET_REGION is now disabled from Mac WebKit, in order not to cause
- confusion with DASHBOARD_SUPPORT feature.
-
- * Configurations/FeatureDefines.xcconfig: Disable WIDGET_REGION feature.
-
-2012-10-09 Filip Pizlo <fpizlo@apple.com>
-
- Unreviewed, adding forgotten files.
-
- * bytecode/ByValInfo.h: Added.
- (JSC):
- (JSC::isOptimizableIndexingType):
- (JSC::jitArrayModeForIndexingType):
- (JSC::ByValInfo::ByValInfo):
- (ByValInfo):
- (JSC::getByValInfoBytecodeIndex):
- * runtime/IndexingType.cpp: Added.
- (JSC):
- (JSC::indexingTypeToString):
-
-2012-10-08 Filip Pizlo <fpizlo@apple.com>
-
- JSC should infer when indexed storage is contiguous, and optimize for it
- https://bugs.webkit.org/show_bug.cgi?id=97288
-
- Reviewed by Mark Hahnenberg.
-
- This introduces a new kind of indexed property storage called Contiguous,
- which has the following properties:
-
- - No header bits beyond IndexedHeader. This results in a 16 byte reduction
- in memory usage per array versus an ArrayStorage array. It also means
- that the total memory usage for an empty array is now just 3 * 8 on both
- 32-bit and 64-bit. Of that, only 8 bytes are array-specific; the rest is
- our standard object header overhead.
-
- - No need for hole checks on store. This results in a ~4% speed-up on
- Kraken and a ~1% speed-up on V8v7.
-
- - publicLength <= vectorLength. This means that doing new Array(blah)
- immediately allocates room for blah elements.
-
- - No sparse map or index bias.
-
- If you ever do things to an array that would require publicLength >
- vectorLength, a sparse map, or index bias, then we switch to ArrayStorage
- mode. This seems to never happen in any benchmark we track, and is unlikely
- to happen very frequently on any website.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * assembler/AbstractMacroAssembler.h:
- (JSC::AbstractMacroAssembler::JumpList::append):
- * assembler/MacroAssembler.h:
- (MacroAssembler):
- (JSC::MacroAssembler::patchableBranchTest32):
- * bytecode/ByValInfo.h: Added.
- (JSC):
- (JSC::isOptimizableIndexingType):
- (JSC::jitArrayModeForIndexingType):
- (JSC::ByValInfo::ByValInfo):
- (ByValInfo):
- (JSC::getByValInfoBytecodeIndex):
- * bytecode/CodeBlock.h:
- (CodeBlock):
- (JSC::CodeBlock::getByValInfo):
- (JSC::CodeBlock::setNumberOfByValInfos):
- (JSC::CodeBlock::numberOfByValInfos):
- (JSC::CodeBlock::byValInfo):
- * bytecode/SamplingTool.h:
- * dfg/DFGAbstractState.cpp:
- (JSC::DFG::AbstractState::execute):
- * dfg/DFGArrayMode.cpp:
- (JSC::DFG::fromObserved):
- (JSC::DFG::modeAlreadyChecked):
- (JSC::DFG::modeToString):
- * dfg/DFGArrayMode.h:
- (DFG):
- (JSC::DFG::modeUsesButterfly):
- (JSC::DFG::modeIsJSArray):
- (JSC::DFG::isInBoundsAccess):
- (JSC::DFG::mayStoreToTail):
- (JSC::DFG::mayStoreToHole):
- (JSC::DFG::modeIsPolymorphic):
- (JSC::DFG::polymorphicIncludesContiguous):
- (JSC::DFG::polymorphicIncludesArrayStorage):
- (JSC::DFG::canCSEStorage):
- (JSC::DFG::modeSupportsLength):
- (JSC::DFG::benefitsFromStructureCheck):
- (JSC::DFG::isEffectful):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::handleIntrinsic):
- * dfg/DFGCSEPhase.cpp:
- (JSC::DFG::CSEPhase::getArrayLengthElimination):
- (JSC::DFG::CSEPhase::getByValLoadElimination):
- (JSC::DFG::CSEPhase::performNodeCSE):
- * dfg/DFGFixupPhase.cpp:
- (JSC::DFG::FixupPhase::fixupNode):
- (JSC::DFG::FixupPhase::checkArray):
- (JSC::DFG::FixupPhase::blessArrayOperation):
- * dfg/DFGGraph.h:
- (JSC::DFG::Graph::byValIsPure):
- * dfg/DFGOperations.cpp:
- * dfg/DFGOperations.h:
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryCacheGetByID):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::checkArray):
- (JSC::DFG::SpeculativeJIT::arrayify):
- (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
- (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
- (DFG):
- * dfg/DFGSpeculativeJIT.h:
- (DFG):
- (JSC::DFG::SpeculativeJIT::callOperation):
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
- (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal):
- (DFG):
- (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal):
- (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
- (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal):
- (DFG):
- (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal):
- (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
- (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal):
- (JSC::DFG::SpeculativeJIT::compile):
- * interpreter/Interpreter.cpp:
- (SamplingScope):
- (JSC::SamplingScope::SamplingScope):
- (JSC::SamplingScope::~SamplingScope):
- (JSC):
- (JSC::Interpreter::execute):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompileSlowCases):
- (JSC::JIT::privateCompile):
- * jit/JIT.h:
- (JSC::ByValCompilationInfo::ByValCompilationInfo):
- (ByValCompilationInfo):
- (JSC):
- (JIT):
- (JSC::JIT::compileGetByVal):
- (JSC::JIT::compilePutByVal):
- * jit/JITInlineMethods.h:
- (JSC::JIT::emitAllocateJSArray):
- (JSC::JIT::emitArrayProfileStoreToHoleSpecialCase):
- (JSC):
- (JSC::arrayProfileSaw):
- (JSC::JIT::chooseArrayMode):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::emitSlow_op_get_argument_by_val):
- (JSC::JIT::emit_op_new_array):
- (JSC::JIT::emitSlow_op_new_array):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::emitSlow_op_get_argument_by_val):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emitArrayStorageGetByVal):
- (JSC::JIT::emitSlow_op_get_by_val):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::emitContiguousPutByVal):
- (JSC::JIT::emitArrayStoragePutByVal):
- (JSC::JIT::emitSlow_op_put_by_val):
- (JSC::JIT::privateCompilePatchGetArrayLength):
- (JSC::JIT::privateCompileGetByVal):
- (JSC::JIT::privateCompilePutByVal):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_get_by_val):
- (JSC):
- (JSC::JIT::emitContiguousGetByVal):
- (JSC::JIT::emitArrayStorageGetByVal):
- (JSC::JIT::emitSlow_op_get_by_val):
- (JSC::JIT::emit_op_put_by_val):
- (JSC::JIT::emitContiguousPutByVal):
- (JSC::JIT::emitArrayStoragePutByVal):
- (JSC::JIT::emitSlow_op_put_by_val):
- * jit/JITStubs.cpp:
- (JSC::getByVal):
- (JSC):
- (JSC::DEFINE_STUB_FUNCTION):
- (JSC::putByVal):
- * jit/JITStubs.h:
- * llint/LowLevelInterpreter.asm:
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm:
- * runtime/ArrayConventions.h:
- (JSC::isDenseEnoughForVector):
- * runtime/ArrayPrototype.cpp:
- (JSC):
- (JSC::shift):
- (JSC::unshift):
- (JSC::arrayProtoFuncPush):
- (JSC::arrayProtoFuncShift):
- (JSC::arrayProtoFuncSplice):
- (JSC::arrayProtoFuncUnShift):
- * runtime/Butterfly.h:
- (Butterfly):
- (JSC::Butterfly::fromPointer):
- (JSC::Butterfly::pointer):
- (JSC::Butterfly::publicLength):
- (JSC::Butterfly::vectorLength):
- (JSC::Butterfly::setPublicLength):
- (JSC::Butterfly::setVectorLength):
- (JSC::Butterfly::contiguous):
- (JSC::Butterfly::fromContiguous):
- * runtime/ButterflyInlineMethods.h:
- (JSC::Butterfly::unshift):
- (JSC::Butterfly::shift):
- * runtime/IndexingHeaderInlineMethods.h:
- (JSC::IndexingHeader::indexingPayloadSizeInBytes):
- * runtime/IndexingType.cpp: Added.
- (JSC):
- (JSC::indexingTypeToString):
- * runtime/IndexingType.h:
- (JSC):
- (JSC::hasContiguous):
- * runtime/JSArray.cpp:
- (JSC::JSArray::setLengthWithArrayStorage):
- (JSC::JSArray::setLength):
- (JSC):
- (JSC::JSArray::pop):
- (JSC::JSArray::push):
- (JSC::JSArray::shiftCountWithArrayStorage):
- (JSC::JSArray::shiftCountWithAnyIndexingType):
- (JSC::JSArray::unshiftCountWithArrayStorage):
- (JSC::JSArray::unshiftCountWithAnyIndexingType):
- (JSC::JSArray::sortNumericVector):
- (JSC::JSArray::sortNumeric):
- (JSC::JSArray::sortCompactedVector):
- (JSC::JSArray::sort):
- (JSC::JSArray::sortVector):
- (JSC::JSArray::fillArgList):
- (JSC::JSArray::copyToArguments):
- (JSC::JSArray::compactForSorting):
- * runtime/JSArray.h:
- (JSC::JSArray::shiftCountForShift):
- (JSC::JSArray::shiftCountForSplice):
- (JSArray):
- (JSC::JSArray::shiftCount):
- (JSC::JSArray::unshiftCountForShift):
- (JSC::JSArray::unshiftCountForSplice):
- (JSC::JSArray::unshiftCount):
- (JSC::JSArray::isLengthWritable):
- (JSC::createContiguousArrayButterfly):
- (JSC):
- (JSC::JSArray::create):
- (JSC::JSArray::tryCreateUninitialized):
- * runtime/JSGlobalObject.cpp:
- (JSC::JSGlobalObject::reset):
- (JSC):
- (JSC::JSGlobalObject::haveABadTime):
- (JSC::JSGlobalObject::visitChildren):
- * runtime/JSGlobalObject.h:
- (JSGlobalObject):
- (JSC::JSGlobalObject::arrayStructureWithArrayStorage):
- (JSC::JSGlobalObject::addressOfArrayStructureWithArrayStorage):
- (JSC::constructEmptyArray):
- * runtime/JSObject.cpp:
- (JSC::JSObject::visitButterfly):
- (JSC::JSObject::getOwnPropertySlotByIndex):
- (JSC::JSObject::putByIndex):
- (JSC::JSObject::enterDictionaryIndexingMode):
- (JSC::JSObject::createInitialContiguous):
- (JSC):
- (JSC::JSObject::createArrayStorage):
- (JSC::JSObject::convertContiguousToArrayStorage):
- (JSC::JSObject::ensureContiguousSlow):
- (JSC::JSObject::ensureArrayStorageSlow):
- (JSC::JSObject::ensureIndexedStorageSlow):
- (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
- (JSC::JSObject::switchToSlowPutArrayStorage):
- (JSC::JSObject::setPrototype):
- (JSC::JSObject::deletePropertyByIndex):
- (JSC::JSObject::getOwnPropertyNames):
- (JSC::JSObject::defineOwnIndexedProperty):
- (JSC::JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes):
- (JSC::JSObject::putByIndexBeyondVectorLength):
- (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
- (JSC::JSObject::putDirectIndexBeyondVectorLength):
- (JSC::JSObject::getNewVectorLength):
- (JSC::JSObject::countElementsInContiguous):
- (JSC::JSObject::increaseVectorLength):
- (JSC::JSObject::ensureContiguousLengthSlow):
- (JSC::JSObject::getOwnPropertyDescriptor):
- * runtime/JSObject.h:
- (JSC::JSObject::getArrayLength):
- (JSC::JSObject::getVectorLength):
- (JSC::JSObject::canGetIndexQuickly):
- (JSC::JSObject::getIndexQuickly):
- (JSC::JSObject::tryGetIndexQuickly):
- (JSC::JSObject::canSetIndexQuickly):
- (JSC::JSObject::canSetIndexQuicklyForPutDirect):
- (JSC::JSObject::setIndexQuickly):
- (JSC::JSObject::initializeIndex):
- (JSC::JSObject::hasSparseMap):
- (JSC::JSObject::inSparseIndexingMode):
- (JSObject):
- (JSC::JSObject::ensureContiguous):
- (JSC::JSObject::ensureIndexedStorage):
- (JSC::JSObject::ensureContiguousLength):
- (JSC::JSObject::indexingData):
- (JSC::JSObject::relevantLength):
- * runtime/JSValue.cpp:
- (JSC::JSValue::description):
- * runtime/Options.cpp:
- (JSC::Options::initialize):
- * runtime/Structure.cpp:
- (JSC::Structure::needsSlowPutIndexing):
- (JSC):
- (JSC::Structure::suggestedArrayStorageTransition):
- * runtime/Structure.h:
- (Structure):
- * runtime/StructureTransitionTable.h:
- (JSC::newIndexingType):
-
-2012-10-09 Michael Saboff <msaboff@apple.com>
-
- After r130344, OpaqueJSString::identifier() adds wrapped String to identifier table
- https://bugs.webkit.org/show_bug.cgi?id=98693
- REGRESSION (r130344): Install failed in Install Environment
- <rdar://problem/12450118>
-
- Reviewed by Mark Rowe.
-
- Use Identifier(LChar*, length) or Identifier(UChar*, length) constructors so that we don't
- add the String instance in the OpaqueJSString to any identifier tables.
-
- * API/OpaqueJSString.cpp:
- (OpaqueJSString::identifier):
-
-2012-10-08 Mark Lam <mark.lam@apple.com>
-
- Renamed RegisterFile to JSStack, and removed prototype of the
- previously deleted Interpreter::privateExecute().
- https://bugs.webkit.org/show_bug.cgi?id=98717.
-
- Reviewed by Filip Pizlo.
-
- * CMakeLists.txt:
- * GNUmakefile.list.am:
- * JavaScriptCore.order:
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * Target.pri:
- * bytecode/BytecodeConventions.h:
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::nameForRegister):
- * bytecode/CodeBlock.h:
- (CodeBlock):
- * bytecode/ValueRecovery.h:
- (JSC::ValueRecovery::alreadyInJSStack):
- (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt32):
- (JSC::ValueRecovery::alreadyInJSStackAsUnboxedCell):
- (JSC::ValueRecovery::alreadyInJSStackAsUnboxedBoolean):
- (JSC::ValueRecovery::alreadyInJSStackAsUnboxedDouble):
- (JSC::ValueRecovery::displacedInJSStack):
- (JSC::ValueRecovery::isAlreadyInJSStack):
- (JSC::ValueRecovery::virtualRegister):
- (JSC::ValueRecovery::dump):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::resolveCallee):
- (JSC::BytecodeGenerator::emitCall):
- (JSC::BytecodeGenerator::emitConstruct):
- * bytecompiler/BytecodeGenerator.h:
- (JSC::BytecodeGenerator::registerFor):
- * dfg/DFGAbstractState.h:
- (AbstractState):
- * dfg/DFGAssemblyHelpers.h:
- (JSC::DFG::AssemblyHelpers::emitGetFromCallFrameHeaderPtr):
- (JSC::DFG::AssemblyHelpers::emitPutToCallFrameHeader):
- (JSC::DFG::AssemblyHelpers::emitPutImmediateToCallFrameHeader):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::getDirect):
- (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal):
- (JSC::DFG::ByteCodeParser::addCall):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
- (JSC::DFG::ByteCodeParser::handleInlining):
- (JSC::DFG::ByteCodeParser::parseBlock):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGGenerationInfo.h:
- (GenerationInfo):
- (JSC::DFG::GenerationInfo::needsSpill):
- * dfg/DFGGraph.h:
- * dfg/DFGJITCompiler.cpp:
- (JSC::DFG::JITCompiler::compileEntry):
- (JSC::DFG::JITCompiler::compileFunction):
- * dfg/DFGJITCompiler.h:
- (JSC::DFG::JITCompiler::beginCall):
- * dfg/DFGOSREntry.cpp:
- (JSC::DFG::prepareOSREntry):
- * dfg/DFGOSRExitCompiler32_64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGOSRExitCompiler64.cpp:
- (JSC::DFG::OSRExitCompiler::compileExit):
- * dfg/DFGRepatch.cpp:
- (JSC::DFG::tryBuildGetByIDList):
- * dfg/DFGSpeculativeJIT.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
- (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
- * dfg/DFGSpeculativeJIT.h:
- (SpeculativeJIT):
- (JSC::DFG::SpeculativeJIT::spill):
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::emitCall):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::fillInteger):
- (JSC::DFG::SpeculativeJIT::emitCall):
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGThunks.cpp:
- (JSC::DFG::throwExceptionFromCallSlowPathGenerator):
- (JSC::DFG::slowPathFor):
- (JSC::DFG::virtualForThunkGenerator):
- * dfg/DFGValueSource.cpp:
- (JSC::DFG::ValueSource::dump):
- * dfg/DFGValueSource.h:
- (JSC::DFG::dataFormatToValueSourceKind):
- (JSC::DFG::valueSourceKindToDataFormat):
- (JSC::DFG::isInJSStack):
- (JSC::DFG::ValueSource::forSpeculation):
- (JSC::DFG::ValueSource::isInJSStack):
- (JSC::DFG::ValueSource::valueRecovery):
- * dfg/DFGVariableEventStream.cpp:
- (JSC::DFG::VariableEventStream::reconstruct):
- * heap/Heap.cpp:
- (JSC::Heap::stack):
- (JSC::Heap::getConservativeRegisterRoots):
- (JSC::Heap::markRoots):
- * heap/Heap.h:
- (JSC):
- (Heap):
- * interpreter/CallFrame.cpp:
- (JSC::CallFrame::stack):
- * interpreter/CallFrame.h:
- (JSC::ExecState::calleeAsValue):
- (JSC::ExecState::callee):
- (JSC::ExecState::codeBlock):
- (JSC::ExecState::scope):
- (JSC::ExecState::callerFrame):
- (JSC::ExecState::returnPC):
- (JSC::ExecState::hasReturnPC):
- (JSC::ExecState::clearReturnPC):
- (JSC::ExecState::bytecodeOffsetForNonDFGCode):
- (JSC::ExecState::setBytecodeOffsetForNonDFGCode):
- (JSC::ExecState::inlineCallFrame):
- (JSC::ExecState::codeOriginIndexForDFG):
- (JSC::ExecState::currentVPC):
- (JSC::ExecState::setCurrentVPC):
- (JSC::ExecState::setCallerFrame):
- (JSC::ExecState::setScope):
- (JSC::ExecState::init):
- (JSC::ExecState::argumentCountIncludingThis):
- (JSC::ExecState::offsetFor):
- (JSC::ExecState::setArgumentCountIncludingThis):
- (JSC::ExecState::setCallee):
- (JSC::ExecState::setCodeBlock):
- (JSC::ExecState::setReturnPC):
- (JSC::ExecState::setInlineCallFrame):
- (ExecState):
- * interpreter/Interpreter.cpp:
- (JSC::Interpreter::slideRegisterWindowForCall):
- (JSC::eval):
- (JSC::loadVarargs):
- (JSC::Interpreter::dumpRegisters):
- (JSC::Interpreter::throwException):
- (JSC::Interpreter::execute):
- (JSC::Interpreter::executeCall):
- (JSC::Interpreter::executeConstruct):
- (JSC::Interpreter::prepareForRepeatCall):
- (JSC::Interpreter::endRepeatCall):
- * interpreter/Interpreter.h:
- (JSC::Interpreter::stack):
- (Interpreter):
- (JSC::Interpreter::execute):
- (JSC):
- * interpreter/JSStack.cpp: Copied from Source/JavaScriptCore/interpreter/RegisterFile.cpp.
- (JSC::stackStatisticsMutex):
- (JSC::JSStack::~JSStack):
- (JSC::JSStack::growSlowCase):
- (JSC::JSStack::gatherConservativeRoots):
- (JSC::JSStack::releaseExcessCapacity):
- (JSC::JSStack::initializeThreading):
- (JSC::JSStack::committedByteCount):
- (JSC::JSStack::addToCommittedByteCount):
- * interpreter/JSStack.h: Copied from Source/JavaScriptCore/interpreter/RegisterFile.h.
- (JSStack):
- (JSC::JSStack::JSStack):
- (JSC::JSStack::shrink):
- (JSC::JSStack::grow):
- * interpreter/RegisterFile.cpp: Removed.
- * interpreter/RegisterFile.h: Removed.
- * interpreter/VMInspector.cpp:
- (JSC::VMInspector::dumpFrame):
- * jit/JIT.cpp:
- (JSC::JIT::JIT):
- (JSC::JIT::privateCompile):
- * jit/JIT.h:
- (JSC):
- (JIT):
- * jit/JITCall.cpp:
- (JSC::JIT::compileLoadVarargs):
- (JSC::JIT::compileCallEval):
- (JSC::JIT::compileCallEvalSlowCase):
- (JSC::JIT::compileOpCall):
- * jit/JITCall32_64.cpp:
- (JSC::JIT::emit_op_ret):
- (JSC::JIT::emit_op_ret_object_or_this):
- (JSC::JIT::compileLoadVarargs):
- (JSC::JIT::compileCallEval):
- (JSC::JIT::compileCallEvalSlowCase):
- (JSC::JIT::compileOpCall):
- * jit/JITCode.h:
- (JSC):
- (JSC::JITCode::execute):
- * jit/JITInlineMethods.h:
- (JSC::JIT::emitPutToCallFrameHeader):
- (JSC::JIT::emitPutCellToCallFrameHeader):
- (JSC::JIT::emitPutIntToCallFrameHeader):
- (JSC::JIT::emitPutImmediateToCallFrameHeader):
- (JSC::JIT::emitGetFromCallFrameHeaderPtr):
- (JSC::JIT::emitGetFromCallFrameHeader32):
- (JSC::JIT::updateTopCallFrame):
- (JSC::JIT::unmap):
- * jit/JITOpcodes.cpp:
- (JSC::JIT::privateCompileCTIMachineTrampolines):
- (JSC::JIT::privateCompileCTINativeCall):
- (JSC::JIT::emit_op_end):
- (JSC::JIT::emit_op_ret):
- (JSC::JIT::emit_op_ret_object_or_this):
- (JSC::JIT::emit_op_create_this):
- (JSC::JIT::emit_op_get_arguments_length):
- (JSC::JIT::emit_op_get_argument_by_val):
- (JSC::JIT::emit_op_resolve_global_dynamic):
- * jit/JITOpcodes32_64.cpp:
- (JSC::JIT::privateCompileCTIMachineTrampolines):
- (JSC::JIT::privateCompileCTINativeCall):
- (JSC::JIT::emit_op_end):
- (JSC::JIT::emit_op_create_this):
- (JSC::JIT::emit_op_get_arguments_length):
- (JSC::JIT::emit_op_get_argument_by_val):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::emit_op_get_scoped_var):
- (JSC::JIT::emit_op_put_scoped_var):
- * jit/JITPropertyAccess32_64.cpp:
- (JSC::JIT::emit_op_get_scoped_var):
- (JSC::JIT::emit_op_put_scoped_var):
- * jit/JITStubs.cpp:
- (JSC::ctiTrampoline):
- (JSC::JITThunks::JITThunks):
- (JSC):
- (JSC::DEFINE_STUB_FUNCTION):
- * jit/JITStubs.h:
- (JSC):
- (JITStackFrame):
- * jit/JSInterfaceJIT.h:
- * jit/SpecializedThunkJIT.h:
- (JSC::SpecializedThunkJIT::SpecializedThunkJIT):
- (JSC::SpecializedThunkJIT::returnJSValue):
- (JSC::SpecializedThunkJIT::returnDouble):
- (JSC::SpecializedThunkJIT::returnInt32):
- (JSC::SpecializedThunkJIT::returnJSCell):
- * llint/LLIntData.cpp:
- (JSC::LLInt::Data::performAssertions):
- * llint/LLIntOffsetsExtractor.cpp:
- * llint/LLIntSlowPaths.cpp:
- (JSC::LLInt::LLINT_SLOW_PATH_DECL):
- (JSC::LLInt::genericCall):
- * llint/LLIntSlowPaths.h:
- (LLInt):
- * llint/LowLevelInterpreter.asm:
- * runtime/Arguments.cpp:
- (JSC::Arguments::tearOffForInlineCallFrame):
- * runtime/CommonSlowPaths.h:
- (JSC::CommonSlowPaths::arityCheckFor):
- * runtime/InitializeThreading.cpp:
- (JSC::initializeThreadingOnce):
- * runtime/JSActivation.cpp:
- (JSC::JSActivation::visitChildren):
- * runtime/JSGlobalObject.cpp:
- (JSC::JSGlobalObject::globalExec):
- * runtime/JSGlobalObject.h:
- (JSC):
- (JSGlobalObject):
- * runtime/JSLock.cpp:
- (JSC):
- * runtime/JSVariableObject.h:
- (JSVariableObject):
- * runtime/MemoryStatistics.cpp:
- (JSC::globalMemoryStatistics):
-
-2012-10-08 Kiran Muppala <cmuppala@apple.com>
-
- Throttle DOM timers on hidden pages.
- https://bugs.webkit.org/show_bug.cgi?id=98474
-
- Reviewed by Maciej Stachowiak.
-
- Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-08 Michael Saboff <msaboff@apple.com>
-
- After r130344, OpaqueJSString() creates an empty string which should be a null string
- https://bugs.webkit.org/show_bug.cgi?id=98417
-
- Reviewed by Sam Weinig.
-
- Changed create() of a null string to return 0. This is the same behavior as before r130344.
-
- * API/OpaqueJSString.cpp:
- (OpaqueJSString::create):
-
-2012-10-07 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>
-
- Rename first/second to key/value in HashMap iterators
- https://bugs.webkit.org/show_bug.cgi?id=82784
-
- Reviewed by Eric Seidel.
-
- * API/JSCallbackObject.h:
- (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty):
- (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty):
- (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren):
- * API/JSCallbackObjectFunctions.h:
- (JSC::::getOwnNonIndexPropertyNames):
- * API/JSClassRef.cpp:
- (OpaqueJSClass::~OpaqueJSClass):
- (OpaqueJSClassContextData::OpaqueJSClassContextData):
- (OpaqueJSClass::contextData):
- * bytecode/CodeBlock.cpp:
- (JSC::CodeBlock::dump):
- (JSC::EvalCodeCache::visitAggregate):
- (JSC::CodeBlock::nameForRegister):
- * bytecode/JumpTable.h:
- (JSC::StringJumpTable::offsetForValue):
- (JSC::StringJumpTable::ctiForValue):
- * bytecode/LazyOperandValueProfile.cpp:
- (JSC::LazyOperandValueProfileParser::getIfPresent):
- * bytecode/SamplingTool.cpp:
- (JSC::SamplingTool::dump):
- * bytecompiler/BytecodeGenerator.cpp:
- (JSC::BytecodeGenerator::addVar):
- (JSC::BytecodeGenerator::addGlobalVar):
- (JSC::BytecodeGenerator::addConstant):
- (JSC::BytecodeGenerator::addConstantValue):
- (JSC::BytecodeGenerator::emitLoad):
- (JSC::BytecodeGenerator::addStringConstant):
- (JSC::BytecodeGenerator::emitLazyNewFunction):
- * bytecompiler/NodesCodegen.cpp:
- (JSC::PropertyListNode::emitBytecode):
- * debugger/Debugger.cpp:
- * dfg/DFGArgumentsSimplificationPhase.cpp:
- (JSC::DFG::ArgumentsSimplificationPhase::run):
- (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
- (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse):
- (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize):
- (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
- * dfg/DFGAssemblyHelpers.cpp:
- (JSC::DFG::AssemblyHelpers::decodedCodeMapFor):
- * dfg/DFGByteCodeCache.h:
- (JSC::DFG::ByteCodeCache::~ByteCodeCache):
- (JSC::DFG::ByteCodeCache::get):
- * dfg/DFGByteCodeParser.cpp:
- (JSC::DFG::ByteCodeParser::cellConstant):
- (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
- * dfg/DFGStructureCheckHoistingPhase.cpp:
- (JSC::DFG::StructureCheckHoistingPhase::run):
- (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck):
- (JSC::DFG::StructureCheckHoistingPhase::noticeClobber):
- * heap/Heap.cpp:
- (JSC::Heap::markProtectedObjects):
- * heap/Heap.h:
- (JSC::Heap::forEachProtectedCell):
- * heap/JITStubRoutineSet.cpp:
- (JSC::JITStubRoutineSet::markSlow):
- (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines):
- * heap/SlotVisitor.cpp:
- (JSC::SlotVisitor::internalAppend):
- * heap/Weak.h:
- (JSC::weakRemove):
- * jit/JIT.cpp:
- (JSC::JIT::privateCompile):
- * jit/JITStubs.cpp:
- (JSC::JITThunks::ctiStub):
- * parser/Parser.cpp:
- (JSC::::parseStrictObjectLiteral):
- * profiler/Profile.cpp:
- (JSC::functionNameCountPairComparator):
- (JSC::Profile::debugPrintDataSampleStyle):
- * runtime/Identifier.cpp:
- (JSC::Identifier::add):
- * runtime/JSActivation.cpp:
- (JSC::JSActivation::getOwnNonIndexPropertyNames):
- (JSC::JSActivation::symbolTablePutWithAttributes):
- * runtime/JSArray.cpp:
- (JSC::JSArray::setLength):
- * runtime/JSObject.cpp:
- (JSC::JSObject::getOwnPropertySlotByIndex):
- (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
- (JSC::JSObject::deletePropertyByIndex):
- (JSC::JSObject::getOwnPropertyNames):
- (JSC::JSObject::defineOwnIndexedProperty):
- (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
- (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage):
- (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
- (JSC::JSObject::getOwnPropertyDescriptor):
- * runtime/JSSymbolTableObject.cpp:
- (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
- * runtime/JSSymbolTableObject.h:
- (JSC::symbolTableGet):
- (JSC::symbolTablePut):
- (JSC::symbolTablePutWithAttributes):
- * runtime/RegExpCache.cpp:
- (JSC::RegExpCache::invalidateCode):
- * runtime/SparseArrayValueMap.cpp:
- (JSC::SparseArrayValueMap::putEntry):
- (JSC::SparseArrayValueMap::putDirect):
- (JSC::SparseArrayValueMap::visitChildren):
- * runtime/WeakGCMap.h:
- (JSC::WeakGCMap::clear):
- (JSC::WeakGCMap::set):
- * tools/ProfileTreeNode.h:
- (JSC::ProfileTreeNode::sampleChild):
- (JSC::ProfileTreeNode::childCount):
- (JSC::ProfileTreeNode::dumpInternal):
- (JSC::ProfileTreeNode::compareEntries):
-
-2012-10-05 Mark Hahnenberg <mhahnenberg@apple.com>
-
- JSC should have a way to gather and log Heap memory use and pause times
- https://bugs.webkit.org/show_bug.cgi?id=98431
-
- Reviewed by Geoffrey Garen.
-
- In order to improve our infrastructure for benchmark-driven development, we should
- have a centralized method of gathering and logging various statistics about the state
- of the JS heap. This would allow us to create and to use other tools to analyze the
- output of the VM after running various workloads.
-
- The first two statistics that might be interesting is memory use by JSC and GC pause
- times. We can control whether this recording happens through the use of the Options
- class, allowing us to either use environment variables or command line flags.
-
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * heap/Heap.cpp:
- (JSC::Heap::collect): If we finish a collection and are still over our set GC heap size,
- we end the program immediately and report an error. Also added recording of pause times.
- * heap/Heap.h:
- (Heap):
- (JSC::Heap::shouldCollect): When we set a specific GC heap size through Options, we
- ignore all other heuristics on when we should collect and instead only ask if we're
- greater than the amount specified in the Option value. This allows us to view time/memory
- tradeoffs more clearly.
- * heap/HeapStatistics.cpp: Added.
- (JSC):
- (JSC::HeapStatistics::initialize):
- (JSC::HeapStatistics::recordGCPauseTime):
- (JSC::HeapStatistics::logStatistics):
- (JSC::HeapStatistics::exitWithFailure):
- (JSC::HeapStatistics::reportSuccess):
- (JSC::HeapStatistics::parseMemoryAmount):
- (StorageStatistics):
- (JSC::StorageStatistics::StorageStatistics):
- (JSC::StorageStatistics::operator()):
- (JSC::StorageStatistics::objectWithOutOfLineStorageCount):
- (JSC::StorageStatistics::objectCount):
- (JSC::StorageStatistics::storageSize):
- (JSC::StorageStatistics::storageCapacity):
- (JSC::HeapStatistics::showObjectStatistics): Moved the old showHeapStatistics (renamed to showObjectStatistics)
- to try to start collecting our various memory statistics gathering/reporting mechanisms scattered throughout the
- codebase into one place.
- * heap/HeapStatistics.h: Added.
- (JSC):
- (HeapStatistics):
- * jsc.cpp:
- (main):
- * runtime/InitializeThreading.cpp:
- (JSC::initializeThreadingOnce): We need to initialize our data structures for recording
- statistics if necessary.
- * runtime/Options.cpp: Add new Options for the various types of statistics we'll be gathering.
- (JSC::parse):
- (JSC):
- (JSC::Options::initialize): Initialize the various new options using environment variables.
- (JSC::Options::dumpOption):
- * runtime/Options.h:
- (JSC):
-
-2012-10-04 Rik Cabanier <cabanier@adobe.com>
-
- Turn Compositing on by default in WebKit build
- https://bugs.webkit.org/show_bug.cgi?id=98315
-
- Reviewed by Simon Fraser.
-
- enable -webkit-blend-mode on trunk.
-
- * Configurations/FeatureDefines.xcconfig:
-
-2012-10-04 Michael Saboff <msaboff@apple.com>
-
- Crash in Safari at com.apple.JavaScriptCore: WTF::StringImpl::is8Bit const + 12
- https://bugs.webkit.org/show_bug.cgi?id=98433
-
- Reviewed by Jessie Berlin.
-
- The problem is due to a String with a null StringImpl (i.e. a null string).
- Added a length check before the is8Bit() check since length() checks for a null StringImpl. Changed the
- characters16() call to characters() since it can handle a null StringImpl as well.
-
- * API/JSValueRef.cpp:
- (JSValueMakeFromJSONString):
-
-2012-10-04 Benjamin Poulain <bpoulain@apple.com>
-
- Use copyLCharsFromUCharSource() for IdentifierLCharFromUCharTranslator translation
- https://bugs.webkit.org/show_bug.cgi?id=98335
-
- Reviewed by Michael Saboff.
-
- Michael Saboff added an optimized version of UChar->LChar conversion in r125846.
- Use this function in JSC::Identifier.
-
- * runtime/Identifier.cpp:
- (JSC::IdentifierLCharFromUCharTranslator::translate):
-
-2012-10-04 Michael Saboff <msaboff@apple.com>
-
- After r130344, OpaqueJSString() creates a empty string which should be a null string
- https://bugs.webkit.org/show_bug.cgi?id=98417
-
- Reviewed by Alexey Proskuryakov.
-
- Removed the setting of enclosed string to an empty string from default constructor.
- Before changeset r130344, the semantic was the default constructor produced a null
- string.
-
- * API/OpaqueJSString.h:
- (OpaqueJSString::OpaqueJSString):
-
-2012-10-04 Csaba Osztrogonác <ossy@webkit.org>
-
- [Qt] Add missing LLInt dependencies to the build system
- https://bugs.webkit.org/show_bug.cgi?id=98394
-
- Reviewed by Geoffrey Garen.
-
- * DerivedSources.pri:
- * LLIntOffsetsExtractor.pro:
-
-2012-10-03 Geoffrey Garen <ggaren@apple.com>
-
- Next step toward fixing Windows: add new symbol.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-10-03 Geoffrey Garen <ggaren@apple.com>
-
- First step toward fixing Windows: remove old symbol.
-
- * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
-
-2012-10-03 Geoffrey Garen <ggaren@apple.com>
-
- Removed the assumption that "final" objects have a fixed number of inline slots
- https://bugs.webkit.org/show_bug.cgi?id=98332
-
- Reviewed by Filip Pizlo.
-
- This is a step toward object size inference.
-
- I replaced the inline storage capacity constant with a data member per
- structure, set the the maximum supported value for the constant to 100,
- then fixed what broke. (Note that even though this patch increases the
- theoretical maximum inline capacity, it doesn't change any actual inline
- capacity.)
-
- * dfg/DFGSpeculativeJIT32_64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * dfg/DFGSpeculativeJIT64.cpp:
- (JSC::DFG::SpeculativeJIT::compile):
- * jit/JITPropertyAccess.cpp:
- (JSC::JIT::compileGetDirectOffset): These functions just get a rename:
- the constant they need is the first out of line offset along the offset
- number line, which is not necessarily the same thing (and is, in this
- patch, never the same thing) as the inline capacity of any given object.
-
- (JSC::JIT::emit_op_get_by_pname):
- * jit/JITPropertyAccess32_64.cpp: This function changes functionality,
- since it needs to convert from the abstract offset number line to an
- actual offset in memory, and it can't assume that inline and out-of-line
- offsets are contiguous on the number line.
-
- (JSC::JIT::compileGetDirectOffset): Updated for rename.
-
- (JSC::JIT::emit_op_get_by_pname): Same as emit_op_get_by_pname above.
-
- * llint/LowLevelInterpreter.asm: Updated to mirror changes in PropertyOffset.h,
- since we duplicate values from there.
-
- * llint/LowLevelInterpreter32_64.asm:
- * llint/LowLevelInterpreter64.asm: Just like the JIT, most things are just
- renames, and get_by_pname changes to do more math. I also standardized
- offset calculations to use a hard-coded "-2", to match the JIT. This
- isn't really better, but it makes global search and replace easier,
- should we choose to refactor this code not to hard-code constants.
-
- I also renamed loadPropertyAtVariableOffsetKnownNotFinal to
- loadPropertyAtVariableOffsetKnownNotInline in order to sever the assumption
- that inline capacity is tied to object type, and I changed the 64bit LLInt
- to use this -- not using this previously seems to have been an oversight.
-
- * runtime/JSObject.cpp:
- (JSC::JSObject::visitChildren):
- (JSC::JSFinalObject::visitChildren):
- * runtime/JSObject.h:
- (JSC::JSObject::offsetForLocation):
- (JSNonFinalObject):
- (JSC::JSFinalObject::createStructure):
- (JSFinalObject):
- (JSC::JSFinalObject::finishCreation): Updated for above changes.
-
- * runtime/JSPropertyNameIterator.h:
- (JSPropertyNameIterator):
- (JSC::JSPropertyNameIterator::finishCreation): Store the inline capacity
- of our object, since it's not a constant.
-
- (JSC::JSPropertyNameIterator::getOffset): Removed. This function was
- wrong. Luckily, it was also unused, since the C++ interpreter is gone.
-
- * runtime/PropertyMapHashTable.h:
- (PropertyTable): Use a helper function instead of hard-coding assumptions
- about object types.
-
- (JSC::PropertyTable::nextOffset):
- * runtime/PropertyOffset.h:
- (JSC):
- (JSC::checkOffset):
- (JSC::validateOffset):
- (JSC::isInlineOffset):
- (JSC::numberOfSlotsForLastOffset):
- (JSC::propertyOffsetFor): Refactored these functions to take inline capacity
- as an argument, since it's not fixed at compile time anymore.
-
- * runtime/Structure.cpp:
- (JSC::Structure::Structure):
- (JSC::Structure::flattenDictionaryStructure):
- (JSC::Structure::putSpecificValue):
- * runtime/Structure.h:
- (Structure):
- (JSC::Structure::outOfLineCapacity):
- (JSC::Structure::hasInlineStorage):
- (JSC::Structure::inlineCapacity):
- (JSC::Structure::inlineSize):
- (JSC::Structure::firstValidOffset):
- (JSC::Structure::lastValidOffset):
- (JSC::Structure::create): Removed some hard-coded assumptions about inline
- capacity and object type, and replaced with more liberal use of helper functions.
-
-2012-10-03 Michael Saboff <msaboff@apple.com>
-
- OpaqueJSString doesn't optimally handle 8 bit strings
- https://bugs.webkit.org/show_bug.cgi?id=98300
-
- Reviewed by Geoffrey Garen.
-
- Change OpaqueJSString to store and manage a String instead of a UChar buffer.
- The member string is a copy of any string used during creation.
-
- * API/OpaqueJSString.cpp:
- (OpaqueJSString::create):
- (OpaqueJSString::identifier):
- * API/OpaqueJSString.h:
- (OpaqueJSString::characters):
- (OpaqueJSString::length):
- (OpaqueJSString::string):
- (OpaqueJSString::OpaqueJSString):
- (OpaqueJSString):
-
-2012-10-03 Filip Pizlo <fpizlo@apple.com>
-
- Array.splice should be fast when it is used to remove elements other than the very first
- https://bugs.webkit.org/show_bug.cgi?id=98236
-
- Reviewed by Michael Saboff.
-
- Applied the same technique that was used to optimize the unshift case of splice in
- http://trac.webkit.org/changeset/129676. This is a >20x speed-up on programs that
- use splice for element removal.
-
- * runtime/ArrayPrototype.cpp:
- (JSC::shift):
- * runtime/JSArray.cpp:
- (JSC::JSArray::shiftCount):
- * runtime/JSArray.h:
- (JSArray):
-
-2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com>
-
- Delayed structure sweep can leak structures without bound
- https://bugs.webkit.org/show_bug.cgi?id=96546
-
- Reviewed by Geoffrey Garen.
-
- This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only
- allocators. We now have separate allocators for our three types of objects: those objects with no destructors,
- those objects with destructors and with immortal structures, and those objects with destructors that don't have
- immortal structures. All of the objects of the third type (destructors without immortal structures) now
- inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores
- the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction.
-
- * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor.
- (JSC):
- (JSC::JSCallbackConstructor::JSCallbackConstructor):
- * API/JSCallbackConstructor.h:
- (JSCallbackConstructor):
- * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for
- JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer.
- (JSC):
- (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add
- the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides
- to subclass this. We use this same technique for many other subclasses of JSGlobalObject.
- (JSC::::createStructure):
- * API/JSCallbackObject.h:
- (JSCallbackObject):
- (JSC):
- * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead.
- (OpaqueJSClass::prototype):
- * API/JSObjectRef.cpp: Ditto.
- (JSObjectMake):
- (JSObjectGetPrivate):
- (JSObjectSetPrivate):
- (JSObjectGetPrivateProperty):
- (JSObjectSetPrivateProperty):
- (JSObjectDeletePrivateProperty):
- * API/JSValueRef.cpp: Ditto.
- (JSValueIsObjectOfClass):
- * API/JSWeakObjectMapRefPrivate.cpp: Ditto.
- * JSCTypedArrayStubs.h:
- (JSC):
- * JavaScriptCore.xcodeproj/project.pbxproj:
- * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG.
- (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
- (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
- * heap/Heap.cpp:
- (JSC):
- * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function
- since it's always safe to sweep Structures now.
- (JSC::Heap::allocatorForObjectWithNormalDestructor):
- (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor):
- (Heap):
- (JSC::Heap::allocateWithNormalDestructor):
- (JSC):
- (JSC::Heap::allocateWithImmortalStructureDestructor):
- * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the
- IncrementalSweeper since it's always safe to sweep Structures now.
- (JSC::IncrementalSweeper::IncrementalSweeper):
- (JSC::IncrementalSweeper::sweepNextBlock):
- (JSC::IncrementalSweeper::startSweeping):
- (JSC::IncrementalSweeper::willFinishSweeping):
- (JSC):
- * heap/IncrementalSweeper.h:
- (IncrementalSweeper):
- * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add
- tracking of the specific destructor type of allocator.
- (JSC::MarkedAllocator::tryAllocateHelper):
- (JSC::MarkedAllocator::allocateBlock):
- * heap/MarkedAllocator.h:
- (JSC::MarkedAllocator::destructorType):
- (MarkedAllocator):
- (JSC::MarkedAllocator::MarkedAllocator):
- (JSC::MarkedAllocator::init):
- * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping.
- We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls.
- (JSC::MarkedBlock::create):
- (JSC::MarkedBlock::MarkedBlock):
- (JSC):
- (JSC::MarkedBlock::specializedSweep):
- (JSC::MarkedBlock::sweep):
- (JSC::MarkedBlock::sweepHelper):
- * heap/MarkedBlock.h:
- (JSC):
- (JSC::MarkedBlock::allocator):
- (JSC::MarkedBlock::destructorType):
- * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace.
- (JSC::MarkedSpace::MarkedSpace):
- (JSC::MarkedSpace::resetAllocators):
- (JSC::MarkedSpace::canonicalizeCellLivenessData):
- (JSC::MarkedSpace::isPagedOut):
- (JSC::MarkedSpace::freeBlock):
- * heap/MarkedSpace.h:
- (MarkedSpace):
- (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor):
- (JSC::MarkedSpace::normalDestructorAllocatorFor):
- (JSC::MarkedSpace::allocateWithImmortalStructureDestructor):
- (JSC::MarkedSpace::allocateWithNormalDestructor):
- (JSC::MarkedSpace::forEachBlock):
- * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function.
- * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT.
- * jit/JITInlineMethods.h:
- (JSC::JIT::emitAllocateBasicJSObject):
- (JSC::JIT::emitAllocateJSFinalObject):
- (JSC::JIT::emitAllocateJSArray):
- * jsc.cpp:
- (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from
- JSDestructibleObject.
- * runtime/Arguments.cpp: Inherit from JSDestructibleObject.
- (JSC):
- * runtime/Arguments.h:
- (Arguments):
- (JSC::Arguments::Arguments):
- * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor.
- (JSC):
- * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures.
- (JSC):
- * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject.
- (JSC):
- (JSC::InternalFunction::InternalFunction):
- * runtime/InternalFunction.h:
- (InternalFunction):
- * runtime/JSCell.h: Added two static bools, needsDestruction and hasImmortalStructure, that classes can override
- to indicate at compile time which part of the heap they should be allocated in.
- (JSC::allocateCell): Use the appropriate allocator depending on the destructor type.
- * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be
- accessed safely when the object is being destroyed.
- (JSC):
- (JSDestructibleObject):
- (JSC::JSDestructibleObject::classInfo):
- (JSC::JSDestructibleObject::JSDestructibleObject):
- (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe.
- * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all
- of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well.
- (JSC::JSGlobalObject::reset):
- * runtime/JSGlobalObject.h:
- (JSGlobalObject):
- (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one
- for the m_rareData field when it's created.
- (JSC::JSGlobalObject::create):
- (JSC):
- * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject.
- (JSGlobalThis):
- (JSC::JSGlobalThis::JSGlobalThis):
- * runtime/JSPropertyNameIterator.h: Has an immortal Structure.
- (JSC):
- * runtime/JSScope.cpp:
- (JSC):
- * runtime/JSString.h: Has an immortal Structure.
- (JSC):
- * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject.
- (JSWrapperObject):
- (JSC::JSWrapperObject::JSWrapperObject):
- * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff.
- (JSC):
- * runtime/NameInstance.h: Inherit from JSDestructibleObject.
- (NameInstance):
- * runtime/RegExp.h: Has immortal Structure.
- (JSC):
- * runtime/RegExpObject.cpp: Inheritance cleanup.
- (JSC):
- * runtime/SparseArrayValueMap.h: Has immortal Structure.
- (JSC):
- * runtime/Structure.h: Has immortal Structure.
- (JSC):
- * runtime/StructureChain.h: Ditto.
- (JSC):
- * runtime/SymbolTable.h: Ditto.
- (SharedSymbolTable):
- (JSC):
-
-== Rolled over to ChangeLog-2012-10-02 ==
diff --git a/Source/JavaScriptCore/ChangeLog-2013-04-24 b/Source/JavaScriptCore/ChangeLog-2013-04-24
new file mode 100644
index 000000000..d3b5d15cd
--- /dev/null
+++ b/Source/JavaScriptCore/ChangeLog-2013-04-24
@@ -0,0 +1,29044 @@
+2013-04-23 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CFA filters CheckFunction in a really weird way, and assumes that the function's structure won't change
+ https://bugs.webkit.org/show_bug.cgi?id=115077
+
+ Reviewed by Oliver Hunt.
+
+ The filtering did three things that are unusual:
+
+ 1) AbstractValue::filterByValue() assumed that the passed value's structure wouldn't change, in
+ the sense that at it assumed it could use that value's *current* structure to do structure
+ filtering. Filtering by structure only makes sense if you can prove that the given value will
+ always have that structure (for example by either using a watchpoing or emitting code that
+ checks that structure at run-time).
+
+ 2) AbstractValue::filterByValue() and the CheckFunction case in AbstractState::executeEffects()
+ tried to invalidate the CFA based on whether the filtration led to an empty value. This is
+ well-intentioned, but it's not how the CFA currently works. It's inconsistent with other
+ parts of the CFA. We shouldn't introduce this feature into just one kind of filtration and
+ not have it elsewhere.
+
+ 3) The attempt to detect when the value was empty was actually implemented incorrectly. It
+ relied on AbstractValue::validate(). That method says that a concrete value does not belong
+ to the abstract value if it has a different structure. This makes sense for the other place
+ where AbstractValue::validate() is called: during OSR entry, where we are talking about a
+ JSValue that we see *right now*. It doesn't make sense in the CFA, since in the CFA any
+ value we observe in the code is a value whose structure may change when the code starts
+ running, and so we cannot use the value's current structure to infer things about the code
+ when it starts running.
+
+ I fixed the above problems by (1) changing filterByValue() to not filter the structure, (2)
+ changing filterByValue() and the CheckFunction case to not invalidate the CFA, and (3)
+ making sure that nobody else was misusing AbstractValue::validate() (they weren't).
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::filterByValue):
+
+2013-04-23 Oliver Hunt <oliver@apple.com>
+
+ Default ParserError() initialiser doesn't initialise all fields
+ https://bugs.webkit.org/show_bug.cgi?id=115074
+
+ Reviewed by Joseph Pecoraro.
+
+ Only the jsc command prompt depended on this, but we'll fix it to
+ be on the safe side.
+
+ * parser/ParserError.h:
+ (JSC::ParserError::ParserError):
+
+2013-04-23 Christophe Dumez <ch.dumez@sisa.samsung.com>
+
+ Global constructors should be configurable and not enumerable
+ https://bugs.webkit.org/show_bug.cgi?id=110573
+
+ Reviewed by Geoffrey Garen.
+
+ Update JSObject::deleteProperty() so that mark to set the property
+ value to undefined if it is in static hashtable of properties. The
+ previous code was not doing anything in this case and this meant
+ we could not remove builtin DOMWindow properties such as
+ "ProgressEvent" even if marked as Deletable.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::deleteProperty):
+ * runtime/Lookup.h:
+ (JSC):
+ (JSC::putEntry):
+ (JSC::lookupPut):
+
+2013-04-23 Geoffrey Garen <ggaren@apple.com>
+
+ Filled out more cases of branch folding in bytecode when emitting
+ expressions into a branching context
+ https://bugs.webkit.org/show_bug.cgi?id=115057
+
+ Reviewed by Filip Pizlo.
+
+ This covers a few cases like:
+
+ - while (true) { }
+ - while (1) { }
+ - if (x) break;
+ - if (x) continue;
+ - if (boolean_expr == boolean_const) { }
+ - if (boolean_expr == 1_or_0) { }
+ - if (bitop == 1_or_0) { }
+
+ This also works, but will bring shame on your family:
+
+ - while ("hello world") { }
+
+ No change on the benchmarks we track, but a 2.5X speedup on a microbenchmark
+ that uses these techniques.
+
+ * JavaScriptCore.order: Order!
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitNewArray):
+ (JSC::BytecodeGenerator::emitThrowReferenceError):
+ (JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::shouldEmitDebugHooks): Updated ancillary code
+ for interface simplifications.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ConstantNode::emitBytecodeInConditionContext): Constants can
+ jump unconditionally when used within a condition context.
+
+ (JSC::ConstantNode::emitBytecode):
+ (JSC::StringNode::jsValue): Gave constants a common base class so I
+ could implement their codegen just once.
+
+ (JSC::BinaryOpNode::emitBytecodeInConditionContext):
+ (JSC::canFoldToBranch):
+ (JSC::BinaryOpNode::tryFoldToBranch): Fold (!/=)= and (!/=)== where
+ appropriate. A lot of cases are not appropriate because of the surprising
+ type conversion semantics of ==. For example, if (number == true) { } is
+ not the same as if (number) { } because the former will up-convert true
+ to number and then do numeric comparison.
+
+ (JSC::singleStatement):
+ (JSC::IfElseNode::tryFoldBreakAndContinue):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::ContinueNode::trivialTarget):
+ (JSC::BreakNode::trivialTarget): Fold "if (expression) break" and
+ "if (expression) continue" into direct jumps from expression.
+
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ (JSC::ASTBuilder::createIfStatement):
+ * parser/NodeConstructors.h:
+ (JSC::ConstantNode::ConstantNode):
+ (JSC):
+ (JSC::NullNode::NullNode):
+ (JSC::BooleanNode::BooleanNode):
+ (JSC::NumberNode::NumberNode):
+ (JSC::StringNode::StringNode):
+ (JSC::IfElseNode::IfElseNode):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::isConstant):
+ (JSC::ExpressionNode::isBoolean):
+ (JSC::StatementNode::isBreak):
+ (JSC::StatementNode::isContinue):
+ (ConstantNode):
+ (JSC::ConstantNode::isPure):
+ (JSC::ConstantNode::isConstant):
+ (NullNode):
+ (JSC::NullNode::jsValue):
+ (JSC::BooleanNode::value):
+ (JSC::BooleanNode::isBoolean):
+ (JSC::BooleanNode::jsValue):
+ (JSC::NumberNode::value):
+ (NumberNode):
+ (JSC::NumberNode::jsValue):
+ (StringNode):
+ (BinaryOpNode):
+ (IfElseNode):
+ (ContinueNode):
+ (JSC::ContinueNode::isContinue):
+ (BreakNode):
+ (JSC::BreakNode::isBreak):
+ * parser/Parser.cpp:
+ (JSC::::parseIfStatement):
+ * parser/ResultType.h:
+ (JSC::ResultType::definitelyIsBoolean):
+ (ResultType):
+ * runtime/JSCJSValueInlines.h:
+ (JSC::JSValue::pureToBoolean):
+ * runtime/JSCell.h:
+ * runtime/JSCellInlines.h:
+ (JSC::JSCell::pureToBoolean): Updated for interface changes above.
+
+2013-04-23 Mark Lam <mark.lam@apple.com>
+
+ Simplify the baseline JIT loop hint call site.
+ https://bugs.webkit.org/show_bug.cgi?id=115052.
+
+ Reviewed by Geoffrey Garen.
+
+ Moved the watchdog timer check after the JIT optimization check. This
+ ensures that the JIT opimization counter is incremented on every loop
+ hint even if the watchdog timer fires.
+
+ Removed the code that allows the JIT OSR to happen if the watchdog
+ timer fires but does not result in a termination. It is extremely rare
+ that the JIT optimization counter would trigger an OSR on the same pass
+ as when the watchdog timer fire. If it does happen, we'll simply hold
+ off on servicing the watchdog timer until the next pass (because it's
+ not time critical).
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_hint):
+ (JSC::JIT::emitSlow_op_loop_hint):
+
+2013-04-23 Roger Fong <roger_fong@apple.com>
+
+ AppleWin build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2013-04-18 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Update public header documentation
+ https://bugs.webkit.org/show_bug.cgi?id=114841
+
+ Reviewed by Geoffrey Garen.
+
+ Added documentation for the newly added object lifetime-related stuff.
+
+ * API/JSManagedValue.h:
+ * API/JSVirtualMachine.h:
+
+2013-04-22 Mark Lam <mark.lam@apple.com>
+
+ Fix a typo in MacroAssemblerARMv7.h.
+ https://bugs.webkit.org/show_bug.cgi?id=115011.
+
+ Reviewed by Geoffrey Garen.
+
+ * assembler/ARMAssembler.h: Fix a comment.
+ * assembler/ARMv7Assembler.h: Added some comments.
+ * assembler/MacroAssemblerARMv7.h:
+ - ARMAssembler::PL should be ARMv7Assembler::ConditionPL.
+
+2013-04-22 Julien Brianceau <jbrianceau@nds.com>
+
+ Add branchAdd32 missing implementation in SH4 base JIT.
+ This should fix SH4 build, broken since r148893.
+ https://bugs.webkit.org/show_bug.cgi?id=114993.
+
+ Reviewed by Oliver Hunt.
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::branchAdd32):
+ (MacroAssemblerSH4):
+
+2013-04-22 Benjamin Poulain <bpoulain@apple.com>
+
+ Windows build fix after r148921
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-22 Benjamin Poulain <benjamin@webkit.org>
+
+ Remove the memory instrumentation code
+ https://bugs.webkit.org/show_bug.cgi?id=114931
+
+ Reviewed by Andreas Kling.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-22 Mark Lam <mark.lam@apple.com>
+
+ Fix broken 32-bit build to green the bots.
+ https://bugs.webkit.org/show_bug.cgi?id=114968.
+
+ Unreviewed.
+
+ Basically, I moved a JIT::emit_op_loop_hint() and JIT::emitSlow_op_loop_hint()
+ into common code where they belong, instead of the 64-bit specific section.
+
+ Also fixed some SH4 assertions failures which were also caused by
+ https://bugs.webkit.org/show_bug.cgi?id=114963. Thanks to Julien Brianceau
+ for pointing this out.
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::branchAdd32):
+ * jit/JITOpcodes.cpp:
+ (JSC):
+ (JSC::JIT::emit_op_loop_hint):
+ (JSC::JIT::emitSlow_op_loop_hint):
+
+2013-04-22 Oliver Hunt <oliver@apple.com>
+
+ Perform null check before trying to use the result of readline()
+
+ RS=Gavin
+
+ * jsc.cpp:
+ (runInteractive):
+
+2013-04-22 Oliver Hunt <oliver@apple.com>
+
+ Fix assertions to account for new Vector layout
+
+ RS=Gavin
+
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+
+2013-04-22 Mark Lam <mark.lam@apple.com>
+
+ Change baseline JIT watchdog timer check to use the proper fast slow path
+ infrastructure.
+ https://bugs.webkit.org/show_bug.cgi?id=114963.
+
+ Reviewed by Oliver Hunt.
+
+ Edit: The PositiveOrZero condition is added because it is needed for
+ the JIT optimization check. Previously, the JIT check branches around
+ the slow path if the test result is 'Signed' i.e. negative. Since we
+ now need to test for a condition that branches to the slow path (not
+ around it), we need the complement of 'Signed / Negative' i.e. Positive
+ or zero.
+
+ SH4 parts contributed by Julien Brianceau.
+
+ * assembler/ARMAssembler.h:
+ * assembler/MacroAssemblerARM.h:
+ * assembler/MacroAssemblerARMv7.h:
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::branchAdd32):
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::branchAdd32):
+ * assembler/MacroAssemblerX86Common.h:
+ * assembler/SH4Assembler.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::emitEnterOptimizationCheck):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JSC::JIT::emitEnterOptimizationCheck):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_hint):
+ (JSC::JIT::emitSlow_op_loop_hint):
+ (JSC::JIT::emit_op_enter):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_enter):
+
+2013-04-22 Andreas Kling <akling@apple.com>
+
+ Shrink baseline size of WTF::Vector on 64-bit by switching to unsigned capacity and size.
+ <http://webkit.org/b/97268>
+ <rdar://problem/12376519>
+
+ Reviewed by Sam Weinig.
+
+ Update LLInt WTF::Vector offset constants to match the new memory layout.
+
+ * llint/LowLevelInterpreter.asm:
+
+2013-04-21 Oliver Hunt <oliver@apple.com>
+
+ JS Lexer and Parser should be more informative when they encounter errors
+ https://bugs.webkit.org/show_bug.cgi?id=114924
+
+ Reviewed by Filip Pizlo.
+
+ Add new tokens to represent the various ways that parsing and lexing have failed.
+ This gives us the ability to produce better error messages in some cases,
+ and to indicate whether or not the failure was due to invalid source, or simply
+ early termination.
+
+ The jsc prompt now makes use of this so that you can write functions that
+ are more than one line long.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ * jsc.cpp:
+ (stringFromUTF):
+ (jscSource):
+ (runInteractive):
+ * parser/Lexer.cpp:
+ (JSC::::parseFourDigitUnicodeHex):
+ (JSC::::parseIdentifierSlowCase):
+ (JSC::::parseString):
+ (JSC::::parseStringSlowCase):
+ (JSC::::lex):
+ * parser/Lexer.h:
+ (UnicodeHexValue):
+ (JSC::Lexer::UnicodeHexValue::UnicodeHexValue):
+ (JSC::Lexer::UnicodeHexValue::valueType):
+ (JSC::Lexer::UnicodeHexValue::isValid):
+ (JSC::Lexer::UnicodeHexValue::value):
+ (Lexer):
+ * parser/Parser.h:
+ (JSC::Parser::getTokenName):
+ (JSC::Parser::updateErrorMessageSpecialCase):
+ (JSC::::parse):
+ * parser/ParserError.h:
+ (ParserError):
+ (JSC::ParserError::ParserError):
+ * parser/ParserTokens.h:
+ * runtime/Completion.cpp:
+ (JSC):
+ (JSC::checkSyntax):
+ * runtime/Completion.h:
+ (JSC):
+
+2013-04-21 Mark Lam <mark.lam@apple.com>
+
+ Refactor identical inline functions in JSVALUE64 and JSVALUE32_64 sections
+ out into the common section.
+ https://bugs.webkit.org/show_bug.cgi?id=114910.
+
+ Reviewed by Filip Pizlo.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+
+2013-04-20 Allan Sandfeld Jensen <allan.jensen@digia.com>
+
+ LLint should be able to use x87 instead of SSE for floating pointer
+ https://bugs.webkit.org/show_bug.cgi?id=112239
+
+ Reviewed by Filip Pizlo.
+
+ Implements LLInt floating point operations in x87, to ensure we support
+ x86 without SSE2.
+
+ X86 (except 64bit) now defaults to using x87 instructions in order to
+ support all 32bit x86 back to i686. The implementation uses the fucomi
+ instruction from i686 which sets the new minimum.
+
+ The FPU registers must always be empty on entering or exiting a function.
+ We make sure to only use two X87 registers, and they are always emptied
+ before calling deeper functions or returning from the LLInt.
+
+ * jit/JITStubs.cpp:
+ (JSC): Empty FPU registers before exiting.
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/instructions.rb:
+ * offlineasm/x86.rb:
+
+2013-04-19 Roger Fong <roger_fong@apple.com>
+
+ Remove uses of WebKit_Source from AppleWin build in JavaScriptCore.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.make:
+ * JavaScriptCore.vcxproj/build-generated-files.sh:
+ * JavaScriptCore.vcxproj/copy-files.cmd:
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj:
+
+2013-04-19 Benjamin Poulain <bpoulain@apple.com>
+
+ Rename JSStringJoiner::build() to join()
+ https://bugs.webkit.org/show_bug.cgi?id=114845
+
+ Reviewed by Geoffrey Garen.
+
+ The method name build() came from StringBuilder history. It does not make much
+ sense on the StringJoiner.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ * runtime/JSStringJoiner.cpp:
+ (JSC::JSStringJoiner::join):
+ * runtime/JSStringJoiner.h:
+ (JSStringJoiner):
+
+2013-04-19 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. WebKit_Source is incorrectly set.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.make:
+
+2013-04-19 Martin Robinson <mrobinson@igalia.com>
+
+ [GTK] JSCore.gir.in has a few problems
+ https://bugs.webkit.org/show_bug.cgi?id=114710
+
+ Reviewed by Philippe Normand.
+
+ * GNUmakefile.am: Add the gobject introspection steps for JavaScriptCore here,
+ because they are shared between WebKit1 and WebKit2.
+ * JavaScriptCore.gir.in: Added. Moved from the WebKit1 directory. Now written
+ as foreign interfaces and referencing the javascriptcoregtk library.
+
+2013-04-18 Benjamin Poulain <bpoulain@apple.com>
+
+ Use StringJoiner to create the JSString of arrayProtoFuncToString
+ https://bugs.webkit.org/show_bug.cgi?id=114779
+
+ Reviewed by Geoffrey Garen.
+
+ The function arrayProtoFuncToString was just a glorified JSStringJoiner.
+ This patch replaces it by JSStringJoiner to simplify the code and enjoy any optimization
+ made on JSStringJoiner.
+
+ For some reason, this makes the execution 3.4% faster, despite having almost identical code.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+
+2013-04-18 Oliver Hunt <oliver@apple.com>
+
+ StackFrame::column() returning bogus value
+ https://bugs.webkit.org/show_bug.cgi?id=114840
+
+ Reviewed by Gavin Barraclough.
+
+ Don't add one part of the expression offset to the other part of the expression.
+ Make StackFrame::toString() include the column info.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::StackFrame::expressionInfo):
+ (JSC::StackFrame::toString):
+
+2013-04-18 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Crash beneath JSC::JIT::privateCompileSlowCases @ stephenrdonaldson.com
+ https://bugs.webkit.org/show_bug.cgi?id=114774
+
+ Reviewed by Geoffrey Garen.
+
+ We're not linking up all of the slow cases in the baseline JIT when compiling put_to_base.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emitSlow_op_put_to_base):
+
+2013-04-18 Mark Lam <mark.lam@apple.com>
+
+ Interpreter entry points should throw the TerminatedExecutionException from the caller frame.
+ https://bugs.webkit.org/show_bug.cgi?id=114816.
+
+ Reviewed by Oliver Hunt.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+
+2013-04-18 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ LLInt ARM backend should not use the d8 register as scratch register
+ https://bugs.webkit.org/show_bug.cgi?id=114811
+
+ Reviewed by Filip Pizlo.
+
+ The d8 register must preserved across function calls and should
+ not used as scratch register. Changing it to d6.
+
+ * offlineasm/arm.rb:
+
+2013-04-18 Geoffrey Garen <ggaren@apple.com>
+
+ Removed HeapTimer::synchronize
+ https://bugs.webkit.org/show_bug.cgi?id=114832
+
+ Reviewed by Mark Hahnenberg.
+
+ HeapTimer::synchronize was a flawed attempt to make HeapTimer thread-safe.
+ Instead, we use proper locking now.
+
+ This is a slight API change, since the GC timer will now only fire in the
+ run loop that created the JS VM, even if another run loop later executes
+ some JS.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ * heap/HeapTimer.cpp:
+ (JSC):
+ * heap/HeapTimer.h:
+ (HeapTimer):
+
+2013-04-17 Geoffrey Garen <ggaren@apple.com>
+
+ Renamed JSGlobalData to VM
+ https://bugs.webkit.org/show_bug.cgi?id=114777
+
+ Reviewed by Phil Pizlo.
+
+ * API/APICast.h:
+ (JSC):
+ (toJS):
+ (toRef):
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (APIEntryShimWithoutLock):
+ (JSC::APIEntryShim::APIEntryShim):
+ (APIEntryShim):
+ (JSC::APIEntryShim::~APIEntryShim):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+ (APICallbackShim):
+ * API/JSAPIWrapperObject.h:
+ (JSAPIWrapperObject):
+ * API/JSAPIWrapperObject.mm:
+ (JSC::::createStructure):
+ (JSC::JSAPIWrapperObject::JSAPIWrapperObject):
+ (JSC::JSAPIWrapperObject::finishCreation):
+ (JSC::JSAPIWrapperObject::visitChildren):
+ * API/JSBase.cpp:
+ (JSGarbageCollect):
+ (JSReportExtraMemoryCost):
+ (JSSynchronousGarbageCollectForDebugging):
+ * API/JSCallbackConstructor.cpp:
+ (JSC::JSCallbackConstructor::JSCallbackConstructor):
+ (JSC::JSCallbackConstructor::finishCreation):
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.cpp:
+ (JSC::JSCallbackFunction::finishCreation):
+ (JSC::JSCallbackFunction::create):
+ * API/JSCallbackFunction.h:
+ (JSCallbackFunction):
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.cpp:
+ (JSC::::create):
+ (JSC::::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObjectData::setPrivateProperty):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty):
+ (JSCallbackObject):
+ (JSC::JSCallbackObject::setPrivateProperty):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::JSCallbackObject):
+ (JSC::::finishCreation):
+ (JSC::::put):
+ (JSC::::staticFunctionGetter):
+ * API/JSClassRef.cpp:
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ (OpaqueJSClass::contextData):
+ (OpaqueJSClass::prototype):
+ * API/JSClassRef.h:
+ (OpaqueJSClassContextData):
+ * API/JSContext.mm:
+ (-[JSContext setException:]):
+ (-[JSContext initWithGlobalContextRef:]):
+ (+[JSContext contextWithGlobalContextRef:]):
+ * API/JSContextRef.cpp:
+ (JSContextGroupCreate):
+ (JSContextGroupRelease):
+ (JSGlobalContextCreate):
+ (JSGlobalContextCreateInGroup):
+ (JSGlobalContextRetain):
+ (JSGlobalContextRelease):
+ (JSContextGetGroup):
+ (JSContextCreateBacktrace):
+ * API/JSObjectRef.cpp:
+ (JSObjectMake):
+ (JSObjectMakeConstructor):
+ (JSObjectMakeFunction):
+ (JSObjectSetPrototype):
+ (JSObjectHasProperty):
+ (JSObjectGetProperty):
+ (JSObjectSetProperty):
+ (JSObjectDeleteProperty):
+ (JSObjectGetPrivateProperty):
+ (JSObjectSetPrivateProperty):
+ (JSObjectDeletePrivateProperty):
+ (OpaqueJSPropertyNameArray::OpaqueJSPropertyNameArray):
+ (OpaqueJSPropertyNameArray):
+ (JSObjectCopyPropertyNames):
+ (JSPropertyNameArrayRelease):
+ (JSPropertyNameAccumulatorAddName):
+ * API/JSScriptRef.cpp:
+ (OpaqueJSScript::create):
+ (OpaqueJSScript::vm):
+ (OpaqueJSScript::OpaqueJSScript):
+ (OpaqueJSScript):
+ (parseScript):
+ * API/JSVirtualMachine.mm:
+ (scanExternalObjectGraph):
+ * API/JSVirtualMachineInternal.h:
+ (JSC):
+ * API/JSWrapperMap.mm:
+ (makeWrapper):
+ * API/ObjCCallbackFunction.h:
+ (JSC::ObjCCallbackFunction::createStructure):
+ * API/ObjCCallbackFunction.mm:
+ (JSC::ObjCCallbackFunction::create):
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::identifier):
+ * API/OpaqueJSString.h:
+ (JSC):
+ (OpaqueJSString):
+ * GNUmakefile.list.am:
+ * JSCTypedArrayStubs.h:
+ (JSC):
+ * JavaScriptCore.order:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * KeywordLookupGenerator.py:
+ (Trie.printSubTreeAsC):
+ * Target.pri:
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::executableCopy):
+ * assembler/ARMAssembler.h:
+ (ARMAssembler):
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::executableCopy):
+ * assembler/AssemblerBufferWithConstantPool.h:
+ (JSC::AssemblerBufferWithConstantPool::executableCopy):
+ * assembler/LinkBuffer.cpp:
+ (JSC::LinkBuffer::linkCode):
+ * assembler/LinkBuffer.h:
+ (JSC):
+ (JSC::LinkBuffer::LinkBuffer):
+ (LinkBuffer):
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::executableCopy):
+ * assembler/SH4Assembler.h:
+ (JSC::SH4Assembler::executableCopy):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::executableCopy):
+ (JSC::X86Assembler::X86InstructionFormatter::executableCopy):
+ * bytecode/CallLinkInfo.cpp:
+ (JSC::CallLinkInfo::unlink):
+ * bytecode/CallLinkInfo.h:
+ (CallLinkInfo):
+ * bytecode/CodeBlock.cpp:
+ (JSC::dumpStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::visitStructures):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::createActivation):
+ (JSC::CodeBlock::unlinkCalls):
+ (JSC::CodeBlock::unlinkIncomingCalls):
+ (JSC::CodeBlock::findClosureCallForReturnPC):
+ (JSC::ProgramCodeBlock::jettisonImpl):
+ (JSC::EvalCodeBlock::jettisonImpl):
+ (JSC::FunctionCodeBlock::jettisonImpl):
+ (JSC::CodeBlock::predictedMachineCodeSize):
+ (JSC::CodeBlock::usesOpcode):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::appendWeakReference):
+ (JSC::CodeBlock::appendWeakReferenceTransition):
+ (JSC::CodeBlock::setJITCode):
+ (JSC::CodeBlock::setGlobalData):
+ (JSC::CodeBlock::vm):
+ (JSC::CodeBlock::valueProfileForBytecodeOffset):
+ (JSC::CodeBlock::addConstant):
+ (JSC::CodeBlock::setConstantRegisters):
+ (CodeBlock):
+ (JSC::CodeBlock::WeakReferenceTransition::WeakReferenceTransition):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::getSlow):
+ * bytecode/GetByIdStatus.cpp:
+ (JSC::GetByIdStatus::computeFromLLInt):
+ (JSC::GetByIdStatus::computeForChain):
+ (JSC::GetByIdStatus::computeFor):
+ * bytecode/GetByIdStatus.h:
+ (GetByIdStatus):
+ * bytecode/Instruction.h:
+ (JSC::Instruction::Instruction):
+ * bytecode/ObjectAllocationProfile.h:
+ (JSC::ObjectAllocationProfile::initialize):
+ (JSC::ObjectAllocationProfile::possibleDefaultPropertyCount):
+ * bytecode/PolymorphicAccessStructureList.h:
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+ * bytecode/PolymorphicPutByIdList.h:
+ (JSC::PutByIdAccess::transition):
+ (JSC::PutByIdAccess::replace):
+ * bytecode/PreciseJumpTargets.cpp:
+ (JSC::computePreciseJumpTargets):
+ * bytecode/PutByIdStatus.cpp:
+ (JSC::PutByIdStatus::computeFromLLInt):
+ (JSC::PutByIdStatus::computeFor):
+ * bytecode/PutByIdStatus.h:
+ (JSC):
+ (PutByIdStatus):
+ * bytecode/ResolveGlobalStatus.cpp:
+ (JSC::computeForStructure):
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::notifyOfScope):
+ * bytecode/SamplingTool.h:
+ (JSC::ScriptSampleRecord::ScriptSampleRecord):
+ (SamplingTool):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::initGetByIdSelf):
+ (JSC::StructureStubInfo::initGetByIdProto):
+ (JSC::StructureStubInfo::initGetByIdChain):
+ (JSC::StructureStubInfo::initPutByIdTransition):
+ (JSC::StructureStubInfo::initPutByIdReplace):
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::generateFunctionCodeBlock):
+ (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+ (JSC::UnlinkedFunctionExecutable::link):
+ (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
+ (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedFunctionExecutable::create):
+ (UnlinkedFunctionExecutable):
+ (JSC::UnlinkedFunctionExecutable::finishCreation):
+ (JSC::UnlinkedFunctionExecutable::createStructure):
+ (JSC::UnlinkedCodeBlock::addRegExp):
+ (JSC::UnlinkedCodeBlock::addConstant):
+ (JSC::UnlinkedCodeBlock::addFunctionDecl):
+ (JSC::UnlinkedCodeBlock::addFunctionExpr):
+ (JSC::UnlinkedCodeBlock::vm):
+ (UnlinkedCodeBlock):
+ (JSC::UnlinkedCodeBlock::finishCreation):
+ (JSC::UnlinkedGlobalCodeBlock::UnlinkedGlobalCodeBlock):
+ (JSC::UnlinkedProgramCodeBlock::create):
+ (JSC::UnlinkedProgramCodeBlock::addFunctionDeclaration):
+ (JSC::UnlinkedProgramCodeBlock::UnlinkedProgramCodeBlock):
+ (JSC::UnlinkedProgramCodeBlock::createStructure):
+ (JSC::UnlinkedEvalCodeBlock::create):
+ (JSC::UnlinkedEvalCodeBlock::UnlinkedEvalCodeBlock):
+ (JSC::UnlinkedEvalCodeBlock::createStructure):
+ (JSC::UnlinkedFunctionCodeBlock::create):
+ (JSC::UnlinkedFunctionCodeBlock::UnlinkedFunctionCodeBlock):
+ (JSC::UnlinkedFunctionCodeBlock::createStructure):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::addConstant):
+ (JSC::BytecodeGenerator::emitLoad):
+ (JSC::BytecodeGenerator::emitDirectPutById):
+ (JSC::BytecodeGenerator::addStringConstant):
+ (JSC::BytecodeGenerator::expectedFunctionForIdentifier):
+ (JSC::BytecodeGenerator::emitThrowReferenceError):
+ (JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::vm):
+ (JSC::BytecodeGenerator::propertyNames):
+ (JSC::BytecodeGenerator::makeFunction):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ (JSC::ArrayNode::toArgumentList):
+ (JSC::ApplyFunctionCallDotNode::emitBytecode):
+ (JSC::InstanceOfNode::emitBytecode):
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::recompileAllJSFunctions):
+ (JSC::evaluateInGlobalCallFrame):
+ * debugger/Debugger.h:
+ (JSC):
+ * debugger/DebuggerActivation.cpp:
+ (JSC::DebuggerActivation::DebuggerActivation):
+ (JSC::DebuggerActivation::finishCreation):
+ * debugger/DebuggerActivation.h:
+ (JSC::DebuggerActivation::create):
+ (JSC::DebuggerActivation::createStructure):
+ (DebuggerActivation):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::AssemblyHelpers):
+ (JSC::DFG::AssemblyHelpers::vm):
+ (JSC::DFG::AssemblyHelpers::debugCall):
+ (JSC::DFG::AssemblyHelpers::emitExceptionCheck):
+ (AssemblyHelpers):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::ByteCodeParser):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGByteCodeParser.h:
+ (JSC):
+ * dfg/DFGCCallHelpers.h:
+ (JSC::DFG::CCallHelpers::CCallHelpers):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::canHandleOpcodes):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::reportToProfiler):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGDriver.h:
+ (JSC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+ (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::Graph):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::JITCompiler):
+ (JSC::DFG::JITCompiler::linkOSRExits):
+ (JSC::DFG::JITCompiler::link):
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ (JSC):
+ * dfg/DFGOSREntry.cpp:
+ (JSC::DFG::prepareOSREntry):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::putByVal):
+ (JSC::DFG::operationPutByValInternal):
+ (JSC::getHostCallReturnValueWithExecState):
+ * dfg/DFGPhase.h:
+ (JSC::DFG::Phase::vm):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::generateProtoChainAccessStub):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDList):
+ (JSC::DFG::tryBuildGetByIDProtoList):
+ (JSC::DFG::emitPutReplaceStub):
+ (JSC::DFG::emitPutTransitionStub):
+ (JSC::DFG::tryCachePutByID):
+ (JSC::DFG::tryBuildPutByIdList):
+ (JSC::DFG::linkSlowFor):
+ (JSC::DFG::dfgLinkFor):
+ (JSC::DFG::dfgLinkSlowFor):
+ (JSC::DFG::dfgLinkClosureCall):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ (JSC::DFG::SpeculativeJIT::compileFromCharCode):
+ (JSC::DFG::SpeculativeJIT::compileMakeRope):
+ (JSC::DFG::SpeculativeJIT::compileStringEquality):
+ (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+ (JSC::DFG::SpeculativeJIT::speculateObject):
+ (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+ (JSC::DFG::SpeculativeJIT::speculateString):
+ (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::prepareForExternalCall):
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGThunks.cpp:
+ (JSC::DFG::osrExitGenerationThunkGenerator):
+ (JSC::DFG::throwExceptionFromCallSlowPathGenerator):
+ (JSC::DFG::slowPathFor):
+ (JSC::DFG::linkForThunkGenerator):
+ (JSC::DFG::linkCallThunkGenerator):
+ (JSC::DFG::linkConstructThunkGenerator):
+ (JSC::DFG::linkClosureCallThunkGenerator):
+ (JSC::DFG::virtualForThunkGenerator):
+ (JSC::DFG::virtualCallThunkGenerator):
+ (JSC::DFG::virtualConstructThunkGenerator):
+ * dfg/DFGThunks.h:
+ (JSC):
+ (DFG):
+ * heap/BlockAllocator.h:
+ (JSC):
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::tryAllocateSlowCase):
+ (JSC::CopiedSpace::tryReallocate):
+ * heap/CopiedSpaceInlines.h:
+ (JSC::CopiedSpace::tryAllocate):
+ * heap/GCThreadSharedData.cpp:
+ (JSC::GCThreadSharedData::GCThreadSharedData):
+ (JSC::GCThreadSharedData::reset):
+ * heap/GCThreadSharedData.h:
+ (JSC):
+ (GCThreadSharedData):
+ * heap/HandleSet.cpp:
+ (JSC::HandleSet::HandleSet):
+ (JSC::HandleSet::~HandleSet):
+ (JSC::HandleSet::grow):
+ * heap/HandleSet.h:
+ (JSC):
+ (HandleSet):
+ (JSC::HandleSet::vm):
+ * heap/Heap.cpp:
+ (JSC::Heap::Heap):
+ (JSC):
+ (JSC::Heap::lastChanceToFinalize):
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::stack):
+ (JSC::Heap::getConservativeRegisterRoots):
+ (JSC::Heap::markRoots):
+ (JSC::Heap::deleteAllCompiledCode):
+ (JSC::Heap::collect):
+ (JSC::Heap::isValidAllocation):
+ * heap/Heap.h:
+ (JSC):
+ (Heap):
+ (JSC::Heap::vm):
+ * heap/HeapTimer.cpp:
+ (JSC::HeapTimer::HeapTimer):
+ (JSC::HeapTimer::timerDidFire):
+ (JSC::HeapTimer::timerEvent):
+ * heap/HeapTimer.h:
+ (JSC):
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::IncrementalSweeper):
+ (JSC::IncrementalSweeper::sweepNextBlock):
+ (JSC::IncrementalSweeper::willFinishSweeping):
+ (JSC::IncrementalSweeper::create):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/Local.h:
+ (Local):
+ (JSC::::Local):
+ (JSC::LocalStack::LocalStack):
+ (JSC::LocalStack::push):
+ (LocalStack):
+ * heap/LocalScope.h:
+ (JSC):
+ (LocalScope):
+ (JSC::LocalScope::LocalScope):
+ * heap/MachineStackMarker.cpp:
+ (JSC::MachineThreads::addCurrentThread):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::allocateSlowCase):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::MarkedBlock):
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::vm):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::SlotVisitor):
+ (JSC::SlotVisitor::setup):
+ * heap/Strong.h:
+ (JSC):
+ (Strong):
+ (JSC::Strong::operator=):
+ * heap/StrongInlines.h:
+ (JSC::::Strong):
+ (JSC::::set):
+ * heap/SuperRegion.h:
+ (JSC):
+ * heap/WeakSet.cpp:
+ * heap/WeakSet.h:
+ (WeakSet):
+ (JSC::WeakSet::WeakSet):
+ (JSC::WeakSet::vm):
+ * interpreter/AbstractPC.cpp:
+ (JSC::AbstractPC::AbstractPC):
+ * interpreter/AbstractPC.h:
+ (JSC):
+ (AbstractPC):
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::CachedCall):
+ * interpreter/CallFrame.h:
+ (ExecState):
+ (JSC::ExecState::clearException):
+ (JSC::ExecState::clearSupplementaryExceptionInfo):
+ (JSC::ExecState::exception):
+ (JSC::ExecState::hadException):
+ (JSC::ExecState::propertyNames):
+ (JSC::ExecState::emptyList):
+ (JSC::ExecState::interpreter):
+ (JSC::ExecState::heap):
+ (JSC::ExecState::arrayConstructorTable):
+ (JSC::ExecState::arrayPrototypeTable):
+ (JSC::ExecState::booleanPrototypeTable):
+ (JSC::ExecState::dateTable):
+ (JSC::ExecState::dateConstructorTable):
+ (JSC::ExecState::errorPrototypeTable):
+ (JSC::ExecState::globalObjectTable):
+ (JSC::ExecState::jsonTable):
+ (JSC::ExecState::mathTable):
+ (JSC::ExecState::numberConstructorTable):
+ (JSC::ExecState::numberPrototypeTable):
+ (JSC::ExecState::objectConstructorTable):
+ (JSC::ExecState::privateNamePrototypeTable):
+ (JSC::ExecState::regExpTable):
+ (JSC::ExecState::regExpConstructorTable):
+ (JSC::ExecState::regExpPrototypeTable):
+ (JSC::ExecState::stringConstructorTable):
+ (JSC::ExecState::abstractReturnPC):
+ * interpreter/CallFrameClosure.h:
+ (CallFrameClosure):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::eval):
+ (JSC::loadVarargs):
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::appendSourceToError):
+ (JSC::getCallerInfo):
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::addStackTraceIfNecessary):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ (JSC::Interpreter::retrieveArgumentsFromVMCode):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ * interpreter/Interpreter.h:
+ (JSC):
+ (JSC::TopCallFrameSetter::TopCallFrameSetter):
+ (JSC::TopCallFrameSetter::~TopCallFrameSetter):
+ (TopCallFrameSetter):
+ (JSC::NativeCallFrameTracer::NativeCallFrameTracer):
+ (Interpreter):
+ * interpreter/JSStack.cpp:
+ (JSC::JSStack::JSStack):
+ * interpreter/JSStack.h:
+ (JSC):
+ * jit/ClosureCallStubRoutine.cpp:
+ (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
+ * jit/ClosureCallStubRoutine.h:
+ (ClosureCallStubRoutine):
+ * jit/ExecutableAllocator.cpp:
+ (JSC::ExecutableAllocator::ExecutableAllocator):
+ (JSC::ExecutableAllocator::allocate):
+ * jit/ExecutableAllocator.h:
+ (JSC):
+ (ExecutableAllocator):
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::ExecutableAllocator::ExecutableAllocator):
+ (JSC::ExecutableAllocator::allocate):
+ * jit/GCAwareJITStubRoutine.cpp:
+ (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine):
+ (JSC::MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject):
+ (JSC::createJITStubRoutine):
+ * jit/GCAwareJITStubRoutine.h:
+ (GCAwareJITStubRoutine):
+ (MarkingGCAwareJITStubRoutineWithOneObject):
+ (JSC):
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::linkFor):
+ (JSC::JIT::linkSlowCall):
+ * jit/JIT.h:
+ (JSC::JIT::compile):
+ (JSC::JIT::compileClosureCall):
+ (JSC::JIT::compileGetByIdProto):
+ (JSC::JIT::compileGetByIdSelfList):
+ (JSC::JIT::compileGetByIdProtoList):
+ (JSC::JIT::compileGetByIdChainList):
+ (JSC::JIT::compileGetByIdChain):
+ (JSC::JIT::compilePutByIdTransition):
+ (JSC::JIT::compileGetByVal):
+ (JSC::JIT::compilePutByVal):
+ (JSC::JIT::compileCTINativeCall):
+ (JSC::JIT::compilePatchGetArrayLength):
+ (JIT):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCallSlowCase):
+ (JSC::JIT::privateCompileClosureCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCallSlowCase):
+ (JSC::JIT::privateCompileClosureCall):
+ * jit/JITCode.h:
+ (JSC):
+ (JSC::JITCode::execute):
+ * jit/JITDriver.h:
+ (JSC::jitCompileIfAppropriate):
+ (JSC::jitCompileFunctionIfAppropriate):
+ * jit/JITExceptions.cpp:
+ (JSC::genericThrow):
+ (JSC::jitThrow):
+ * jit/JITExceptions.h:
+ (JSC):
+ * jit/JITInlines.h:
+ (JSC::JIT::emitLoadCharacterString):
+ (JSC::JIT::updateTopCallFrame):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_new_object):
+ (JSC::JIT::emit_op_to_primitive):
+ (JSC::JIT::emit_op_catch):
+ (JSC::JIT::emit_op_convert_this):
+ (JSC::JIT::emitSlow_op_convert_this):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_new_object):
+ (JSC::JIT::emit_op_to_primitive):
+ (JSC::JIT::emitSlow_op_eq):
+ (JSC::JIT::emitSlow_op_neq):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emit_op_catch):
+ (JSC::JIT::emit_op_convert_this):
+ (JSC::JIT::emitSlow_op_convert_this):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompileGetByVal):
+ (JSC::JIT::privateCompilePutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITStubs.cpp:
+ (JSC::ctiTrampoline):
+ (JSC):
+ (JSC::performPlatformSpecificJITAssertions):
+ (JSC::tryCachePutByID):
+ (JSC::tryCacheGetByID):
+ (JSC::returnToThrowTrampoline):
+ (JSC::throwExceptionFromOpCall):
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::jitCompileFor):
+ (JSC::lazyLinkFor):
+ (JSC::putByVal):
+ * jit/JITStubs.h:
+ (JSC):
+ (JITStackFrame):
+ * jit/JITThunks.cpp:
+ (JSC::JITThunks::ctiNativeCall):
+ (JSC::JITThunks::ctiNativeConstruct):
+ (JSC::JITThunks::ctiStub):
+ (JSC::JITThunks::hostFunctionStub):
+ * jit/JITThunks.h:
+ (JSC):
+ (JITThunks):
+ * jit/JITWriteBarrier.h:
+ (JSC):
+ (JSC::JITWriteBarrierBase::set):
+ (JSC::JITWriteBarrier::set):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::loadJSStringArgument):
+ (JSC::SpecializedThunkJIT::finalize):
+ * jit/ThunkGenerator.h:
+ (JSC):
+ * jit/ThunkGenerators.cpp:
+ (JSC::generateSlowCaseFor):
+ (JSC::linkForGenerator):
+ (JSC::linkCallGenerator):
+ (JSC::linkConstructGenerator):
+ (JSC::linkClosureCallGenerator):
+ (JSC::virtualForGenerator):
+ (JSC::virtualCallGenerator):
+ (JSC::virtualConstructGenerator):
+ (JSC::stringLengthTrampolineGenerator):
+ (JSC::nativeForGenerator):
+ (JSC::nativeCallGenerator):
+ (JSC::nativeConstructGenerator):
+ (JSC::stringCharLoad):
+ (JSC::charToString):
+ (JSC::charCodeAtThunkGenerator):
+ (JSC::charAtThunkGenerator):
+ (JSC::fromCharCodeThunkGenerator):
+ (JSC::sqrtThunkGenerator):
+ (JSC::floorThunkGenerator):
+ (JSC::ceilThunkGenerator):
+ (JSC::roundThunkGenerator):
+ (JSC::expThunkGenerator):
+ (JSC::logThunkGenerator):
+ (JSC::absThunkGenerator):
+ (JSC::powThunkGenerator):
+ * jit/ThunkGenerators.h:
+ (JSC):
+ * jsc.cpp:
+ (GlobalObject):
+ (GlobalObject::create):
+ (GlobalObject::createStructure):
+ (GlobalObject::finishCreation):
+ (GlobalObject::addFunction):
+ (GlobalObject::addConstructableFunction):
+ (functionDumpCallFrame):
+ (functionJSCStack):
+ (functionReleaseExecutableMemory):
+ (functionRun):
+ (main):
+ (runWithScripts):
+ (jscmain):
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LLIntData.h:
+ (JSC):
+ (Data):
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LLIntEntrypoints.cpp:
+ (JSC::LLInt::getFunctionEntrypoint):
+ (JSC::LLInt::getEvalEntrypoint):
+ (JSC::LLInt::getProgramEntrypoint):
+ * llint/LLIntEntrypoints.h:
+ (JSC):
+ (LLInt):
+ (JSC::LLInt::getEntrypoint):
+ * llint/LLIntExceptions.cpp:
+ (JSC::LLInt::interpreterThrowInCaller):
+ (JSC::LLInt::returnToThrow):
+ (JSC::LLInt::callToThrow):
+ * llint/LLIntOffsetsExtractor.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::llint_trace_operand):
+ (JSC::LLInt::llint_trace_value):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::shouldJIT):
+ (JSC::LLInt::handleHostCall):
+ (JSC::LLInt::setUpCall):
+ * llint/LLIntThunks.cpp:
+ (JSC::LLInt::generateThunkWithJumpTo):
+ (JSC::LLInt::functionForCallEntryThunkGenerator):
+ (JSC::LLInt::functionForConstructEntryThunkGenerator):
+ (JSC::LLInt::functionForCallArityCheckThunkGenerator):
+ (JSC::LLInt::functionForConstructArityCheckThunkGenerator):
+ (JSC::LLInt::evalEntryThunkGenerator):
+ (JSC::LLInt::programEntryThunkGenerator):
+ * llint/LLIntThunks.h:
+ (JSC):
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter.cpp:
+ (JSC::CLoop::execute):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/cloop.rb:
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::ASTBuilder):
+ (JSC::ASTBuilder::createSourceElements):
+ (JSC::ASTBuilder::createCommaExpr):
+ (JSC::ASTBuilder::createLogicalNot):
+ (JSC::ASTBuilder::createUnaryPlus):
+ (JSC::ASTBuilder::createVoid):
+ (JSC::ASTBuilder::thisExpr):
+ (JSC::ASTBuilder::createResolve):
+ (JSC::ASTBuilder::createObjectLiteral):
+ (JSC::ASTBuilder::createArray):
+ (JSC::ASTBuilder::createNumberExpr):
+ (JSC::ASTBuilder::createString):
+ (JSC::ASTBuilder::createBoolean):
+ (JSC::ASTBuilder::createNull):
+ (JSC::ASTBuilder::createBracketAccess):
+ (JSC::ASTBuilder::createDotAccess):
+ (JSC::ASTBuilder::createRegExp):
+ (JSC::ASTBuilder::createNewExpr):
+ (JSC::ASTBuilder::createConditionalExpr):
+ (JSC::ASTBuilder::createAssignResolve):
+ (JSC::ASTBuilder::createFunctionExpr):
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::createGetterOrSetterProperty):
+ (JSC::ASTBuilder::createArguments):
+ (JSC::ASTBuilder::createArgumentsList):
+ (JSC::ASTBuilder::createProperty):
+ (JSC::ASTBuilder::createPropertyList):
+ (JSC::ASTBuilder::createElementList):
+ (JSC::ASTBuilder::createFormalParameterList):
+ (JSC::ASTBuilder::createClause):
+ (JSC::ASTBuilder::createClauseList):
+ (JSC::ASTBuilder::createFuncDeclStatement):
+ (JSC::ASTBuilder::createBlockStatement):
+ (JSC::ASTBuilder::createExprStatement):
+ (JSC::ASTBuilder::createIfStatement):
+ (JSC::ASTBuilder::createForLoop):
+ (JSC::ASTBuilder::createForInLoop):
+ (JSC::ASTBuilder::createEmptyStatement):
+ (JSC::ASTBuilder::createVarStatement):
+ (JSC::ASTBuilder::createReturnStatement):
+ (JSC::ASTBuilder::createBreakStatement):
+ (JSC::ASTBuilder::createContinueStatement):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createSwitchStatement):
+ (JSC::ASTBuilder::createWhileStatement):
+ (JSC::ASTBuilder::createDoWhileStatement):
+ (JSC::ASTBuilder::createLabelStatement):
+ (JSC::ASTBuilder::createWithStatement):
+ (JSC::ASTBuilder::createThrowStatement):
+ (JSC::ASTBuilder::createDebugger):
+ (JSC::ASTBuilder::createConstStatement):
+ (JSC::ASTBuilder::appendConstDecl):
+ (JSC::ASTBuilder::addVar):
+ (JSC::ASTBuilder::combineCommaNodes):
+ (JSC::ASTBuilder::Scope::Scope):
+ (JSC::ASTBuilder::createNumber):
+ (ASTBuilder):
+ (JSC::ASTBuilder::makeTypeOfNode):
+ (JSC::ASTBuilder::makeDeleteNode):
+ (JSC::ASTBuilder::makeNegateNode):
+ (JSC::ASTBuilder::makeBitwiseNotNode):
+ (JSC::ASTBuilder::makeMultNode):
+ (JSC::ASTBuilder::makeDivNode):
+ (JSC::ASTBuilder::makeModNode):
+ (JSC::ASTBuilder::makeAddNode):
+ (JSC::ASTBuilder::makeSubNode):
+ (JSC::ASTBuilder::makeLeftShiftNode):
+ (JSC::ASTBuilder::makeRightShiftNode):
+ (JSC::ASTBuilder::makeURightShiftNode):
+ (JSC::ASTBuilder::makeBitOrNode):
+ (JSC::ASTBuilder::makeBitAndNode):
+ (JSC::ASTBuilder::makeBitXOrNode):
+ (JSC::ASTBuilder::makeFunctionCallNode):
+ (JSC::ASTBuilder::makeBinaryNode):
+ (JSC::ASTBuilder::makeAssignNode):
+ (JSC::ASTBuilder::makePrefixNode):
+ (JSC::ASTBuilder::makePostfixNode):
+ * parser/Lexer.cpp:
+ (JSC::Keywords::Keywords):
+ (JSC::::Lexer):
+ (JSC::::parseIdentifier):
+ (JSC::::parseIdentifierSlowCase):
+ * parser/Lexer.h:
+ (JSC::Keywords::isKeyword):
+ (JSC::Keywords::getKeyword):
+ (Keywords):
+ (Lexer):
+ (JSC::::makeIdentifier):
+ (JSC::::makeRightSizedIdentifier):
+ (JSC::::makeIdentifierLCharFromUChar):
+ (JSC::::makeLCharIdentifier):
+ * parser/NodeConstructors.h:
+ (JSC::ParserArenaFreeable::operator new):
+ (JSC::ParserArenaDeletable::operator new):
+ (JSC::ParserArenaRefCounted::ParserArenaRefCounted):
+ (JSC::PropertyNode::PropertyNode):
+ (JSC::ContinueNode::ContinueNode):
+ (JSC::BreakNode::BreakNode):
+ (JSC::ForInNode::ForInNode):
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (ParserArenaFreeable):
+ (ParserArenaDeletable):
+ (ParserArenaRefCounted):
+ (ArrayNode):
+ (ForInNode):
+ (ContinueNode):
+ (BreakNode):
+ (ScopeNode):
+ (ProgramNode):
+ (EvalNode):
+ (FunctionBodyNode):
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ (JSC::::parseInner):
+ (JSC::::parseSourceElements):
+ (JSC::::parseTryStatement):
+ (JSC::::parseFunctionBody):
+ (JSC::::parseFunctionInfo):
+ (JSC::::parseAssignmentExpression):
+ (JSC::::parseProperty):
+ (JSC::::parsePrimaryExpression):
+ (JSC::::parseMemberExpression):
+ (JSC::::parseUnaryExpression):
+ * parser/Parser.h:
+ (JSC):
+ (JSC::Scope::Scope):
+ (JSC::Scope::declareVariable):
+ (JSC::Scope::declareParameter):
+ (Scope):
+ (Parser):
+ (JSC::Parser::pushScope):
+ (JSC::::parse):
+ (JSC::parse):
+ * parser/ParserArena.h:
+ (IdentifierArena):
+ (JSC::IdentifierArena::makeIdentifier):
+ (JSC::IdentifierArena::makeIdentifierLCharFromUChar):
+ (JSC::IdentifierArena::makeNumericIdentifier):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::SyntaxChecker):
+ (JSC::SyntaxChecker::createProperty):
+ (JSC::SyntaxChecker::createGetterOrSetterProperty):
+ * profiler/LegacyProfiler.cpp:
+ (JSC::LegacyProfiler::startProfiling):
+ (JSC::LegacyProfiler::stopProfiling):
+ * profiler/LegacyProfiler.h:
+ (JSC):
+ * profiler/ProfilerBytecode.cpp:
+ (JSC::Profiler::Bytecode::toJS):
+ * profiler/ProfilerBytecodeSequence.cpp:
+ (JSC::Profiler::BytecodeSequence::BytecodeSequence):
+ (JSC::Profiler::BytecodeSequence::addSequenceProperties):
+ * profiler/ProfilerBytecodes.cpp:
+ (JSC::Profiler::Bytecodes::toJS):
+ * profiler/ProfilerCompilation.cpp:
+ (JSC::Profiler::Compilation::toJS):
+ * profiler/ProfilerCompiledBytecode.cpp:
+ (JSC::Profiler::CompiledBytecode::toJS):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::Database):
+ (JSC::Profiler::Database::toJS):
+ (JSC::Profiler::Database::toJSON):
+ * profiler/ProfilerDatabase.h:
+ (Database):
+ * profiler/ProfilerOSRExit.cpp:
+ (JSC::Profiler::OSRExit::toJS):
+ * profiler/ProfilerOrigin.cpp:
+ (JSC::Profiler::Origin::toJS):
+ * profiler/ProfilerProfiledBytecodes.cpp:
+ (JSC::Profiler::ProfiledBytecodes::toJS):
+ * runtime/ArgList.h:
+ (MarkedArgumentBuffer):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::putByIndex):
+ (JSC::Arguments::put):
+ (JSC::Arguments::deleteProperty):
+ (JSC::Arguments::defineOwnProperty):
+ (JSC::Arguments::tearOff):
+ (JSC::Arguments::didTearOffActivation):
+ (JSC::Arguments::tearOffForInlineCallFrame):
+ * runtime/Arguments.h:
+ (JSC::Arguments::create):
+ (JSC::Arguments::createStructure):
+ (Arguments):
+ (JSC::Arguments::Arguments):
+ (JSC::Arguments::trySetArgument):
+ (JSC::Arguments::finishCreation):
+ * runtime/ArrayConstructor.cpp:
+ (JSC::ArrayConstructor::finishCreation):
+ * runtime/ArrayConstructor.h:
+ (JSC::ArrayConstructor::createStructure):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::ArrayPrototype):
+ (JSC::ArrayPrototype::finishCreation):
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncSplice):
+ * runtime/ArrayPrototype.h:
+ (JSC::ArrayPrototype::createStructure):
+ * runtime/BatchedTransitionOptimizer.h:
+ (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
+ (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
+ (BatchedTransitionOptimizer):
+ * runtime/BooleanConstructor.cpp:
+ (JSC::BooleanConstructor::finishCreation):
+ (JSC::constructBoolean):
+ (JSC::constructBooleanFromImmediateBoolean):
+ * runtime/BooleanConstructor.h:
+ (JSC::BooleanConstructor::createStructure):
+ * runtime/BooleanObject.cpp:
+ (JSC::BooleanObject::BooleanObject):
+ (JSC::BooleanObject::finishCreation):
+ * runtime/BooleanObject.h:
+ (BooleanObject):
+ (JSC::BooleanObject::create):
+ (JSC::BooleanObject::createStructure):
+ * runtime/BooleanPrototype.cpp:
+ (JSC::BooleanPrototype::BooleanPrototype):
+ (JSC::BooleanPrototype::finishCreation):
+ (JSC::booleanProtoFuncToString):
+ * runtime/BooleanPrototype.h:
+ (JSC::BooleanPrototype::createStructure):
+ * runtime/Butterfly.h:
+ (JSC):
+ (Butterfly):
+ * runtime/ButterflyInlines.h:
+ (JSC::Butterfly::createUninitialized):
+ (JSC::Butterfly::create):
+ (JSC::Butterfly::growPropertyStorage):
+ (JSC::Butterfly::createOrGrowArrayRight):
+ (JSC::Butterfly::growArrayRight):
+ (JSC::Butterfly::resizeArray):
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::getProgramCodeBlock):
+ (JSC::CodeCache::getEvalCodeBlock):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/CodeCache.h:
+ (JSC):
+ (JSC::SourceCodeValue::SourceCodeValue):
+ (CodeCache):
+ * runtime/CommonIdentifiers.cpp:
+ (JSC):
+ (JSC::CommonIdentifiers::CommonIdentifiers):
+ * runtime/CommonIdentifiers.h:
+ (CommonIdentifiers):
+ * runtime/CommonSlowPaths.h:
+ (JSC::CommonSlowPaths::opIn):
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/DateConstructor.cpp:
+ (JSC::DateConstructor::finishCreation):
+ * runtime/DateConstructor.h:
+ (JSC::DateConstructor::createStructure):
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::DateInstance):
+ (JSC::DateInstance::finishCreation):
+ (JSC::DateInstance::calculateGregorianDateTime):
+ (JSC::DateInstance::calculateGregorianDateTimeUTC):
+ * runtime/DateInstance.h:
+ (DateInstance):
+ (JSC::DateInstance::create):
+ (JSC::DateInstance::createStructure):
+ * runtime/DatePrototype.cpp:
+ (JSC::DatePrototype::finishCreation):
+ (JSC::dateProtoFuncSetTime):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncToJSON):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/Error.cpp:
+ (JSC::createError):
+ (JSC::createEvalError):
+ (JSC::createRangeError):
+ (JSC::createReferenceError):
+ (JSC::createSyntaxError):
+ (JSC::createTypeError):
+ (JSC::createURIError):
+ (JSC::addErrorInfo):
+ (JSC::throwError):
+ * runtime/Error.h:
+ (JSC):
+ (JSC::StrictModeTypeErrorFunction::create):
+ (JSC::StrictModeTypeErrorFunction::createStructure):
+ * runtime/ErrorConstructor.cpp:
+ (JSC::ErrorConstructor::finishCreation):
+ * runtime/ErrorConstructor.h:
+ (JSC::ErrorConstructor::createStructure):
+ * runtime/ErrorInstance.cpp:
+ (JSC::ErrorInstance::ErrorInstance):
+ * runtime/ErrorInstance.h:
+ (JSC::ErrorInstance::createStructure):
+ (JSC::ErrorInstance::create):
+ (ErrorInstance):
+ (JSC::ErrorInstance::finishCreation):
+ * runtime/ErrorPrototype.cpp:
+ (JSC::ErrorPrototype::ErrorPrototype):
+ (JSC::ErrorPrototype::finishCreation):
+ * runtime/ErrorPrototype.h:
+ (JSC::ErrorPrototype::createStructure):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createInterruptedExecutionException):
+ (JSC::createTerminatedExecutionException):
+ * runtime/ExceptionHelpers.h:
+ (JSC):
+ (JSC::InterruptedExecutionError::InterruptedExecutionError):
+ (JSC::InterruptedExecutionError::create):
+ (JSC::InterruptedExecutionError::createStructure):
+ (JSC::TerminatedExecutionError::TerminatedExecutionError):
+ (JSC::TerminatedExecutionError::create):
+ (JSC::TerminatedExecutionError::createStructure):
+ * runtime/Executable.cpp:
+ (JSC::jettisonCodeBlock):
+ (JSC::EvalExecutable::EvalExecutable):
+ (JSC::ProgramExecutable::ProgramExecutable):
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::EvalExecutable::compileOptimized):
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::EvalExecutable::jettisonOptimizedCode):
+ (JSC::ProgramExecutable::checkSyntax):
+ (JSC::ProgramExecutable::compileOptimized):
+ (JSC::ProgramExecutable::jettisonOptimizedCode):
+ (JSC::ProgramExecutable::initializeGlobalProperties):
+ (JSC::FunctionExecutable::compileOptimizedForCall):
+ (JSC::FunctionExecutable::compileOptimizedForConstruct):
+ (JSC::FunctionExecutable::produceCodeBlockFor):
+ (JSC::FunctionExecutable::jettisonOptimizedCodeForCall):
+ (JSC::FunctionExecutable::jettisonOptimizedCodeForConstruct):
+ (JSC::FunctionExecutable::fromGlobalCode):
+ * runtime/Executable.h:
+ (JSC::ExecutableBase::ExecutableBase):
+ (JSC::ExecutableBase::finishCreation):
+ (JSC::ExecutableBase::createStructure):
+ (JSC::NativeExecutable::create):
+ (JSC::NativeExecutable::createStructure):
+ (JSC::NativeExecutable::finishCreation):
+ (JSC::NativeExecutable::NativeExecutable):
+ (JSC::ScriptExecutable::ScriptExecutable):
+ (JSC::ScriptExecutable::finishCreation):
+ (JSC::EvalExecutable::compile):
+ (EvalExecutable):
+ (JSC::EvalExecutable::create):
+ (JSC::EvalExecutable::createStructure):
+ (JSC::ProgramExecutable::create):
+ (ProgramExecutable):
+ (JSC::ProgramExecutable::compile):
+ (JSC::ProgramExecutable::createStructure):
+ (JSC::FunctionExecutable::create):
+ (JSC::FunctionExecutable::compileForCall):
+ (FunctionExecutable):
+ (JSC::FunctionExecutable::compileForConstruct):
+ (JSC::FunctionExecutable::jettisonOptimizedCodeFor):
+ (JSC::FunctionExecutable::createStructure):
+ (JSC::JSFunction::JSFunction):
+ * runtime/ExecutionHarness.h:
+ (JSC::prepareForExecution):
+ (JSC::prepareFunctionForExecution):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::FunctionConstructor::finishCreation):
+ * runtime/FunctionConstructor.h:
+ (JSC::FunctionConstructor::createStructure):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::FunctionPrototype::finishCreation):
+ (JSC::FunctionPrototype::addFunctionProperties):
+ (JSC::functionProtoFuncBind):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GCActivityCallback.cpp:
+ (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
+ (JSC::DefaultGCActivityCallback::doWork):
+ (JSC::DefaultGCActivityCallback::didAllocate):
+ * runtime/GCActivityCallback.h:
+ (JSC::GCActivityCallback::GCActivityCallback):
+ * runtime/GCActivityCallbackBlackBerry.cpp:
+ (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
+ (JSC::DefaultGCActivityCallback::doWork):
+ (JSC::DefaultGCActivityCallback::didAllocate):
+ * runtime/GetterSetter.h:
+ (JSC::GetterSetter::GetterSetter):
+ (JSC::GetterSetter::create):
+ (JSC::GetterSetter::setGetter):
+ (JSC::GetterSetter::setSetter):
+ (JSC::GetterSetter::createStructure):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ (JSC::Identifier::add8):
+ (JSC::Identifier::addSlowCase):
+ (JSC::Identifier::from):
+ (JSC::Identifier::checkCurrentIdentifierTable):
+ * runtime/Identifier.h:
+ (JSC::Identifier::Identifier):
+ (JSC::Identifier::createLCharFromUChar):
+ (Identifier):
+ (JSC::Identifier::add):
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::InternalFunction):
+ (JSC::InternalFunction::finishCreation):
+ (JSC::InternalFunction::name):
+ (JSC::InternalFunction::displayName):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ (InternalFunction):
+ * runtime/JSAPIValueWrapper.h:
+ (JSC::JSAPIValueWrapper::createStructure):
+ (JSC::JSAPIValueWrapper::finishCreation):
+ (JSC::JSAPIValueWrapper::JSAPIValueWrapper):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::symbolTablePut):
+ (JSC::JSActivation::symbolTablePutWithAttributes):
+ (JSC::JSActivation::getOwnPropertySlot):
+ (JSC::JSActivation::put):
+ (JSC::JSActivation::putDirectVirtual):
+ (JSC::JSActivation::argumentsGetter):
+ * runtime/JSActivation.h:
+ (JSActivation):
+ (JSC::JSActivation::create):
+ (JSC::JSActivation::createStructure):
+ (JSC::JSActivation::JSActivation):
+ (JSC::JSActivation::tearOff):
+ * runtime/JSArray.cpp:
+ (JSC::createArrayButterflyInDictionaryIndexingMode):
+ (JSC::JSArray::setLengthWritable):
+ (JSC::JSArray::unshiftCountSlowCase):
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::push):
+ (JSC::JSArray::shiftCountWithAnyIndexingType):
+ (JSC::JSArray::unshiftCountWithArrayStorage):
+ (JSC::JSArray::unshiftCountWithAnyIndexingType):
+ (JSC::ContiguousTypeAccessor::setWithValue):
+ (JSC::JSArray::sortCompactedVector):
+ (JSC::JSArray::sortVector):
+ * runtime/JSArray.h:
+ (JSC::JSArray::JSArray):
+ (JSArray):
+ (JSC::JSArray::shiftCountForShift):
+ (JSC::JSArray::unshiftCountForShift):
+ (JSC::JSArray::createStructure):
+ (JSC::createContiguousArrayButterfly):
+ (JSC::createArrayButterfly):
+ (JSC):
+ (JSC::JSArray::create):
+ (JSC::JSArray::tryCreateUninitialized):
+ (JSC::constructArray):
+ * runtime/JSBoundFunction.cpp:
+ (JSC::JSBoundFunction::create):
+ (JSC::JSBoundFunction::JSBoundFunction):
+ * runtime/JSBoundFunction.h:
+ (JSC::JSBoundFunction::createStructure):
+ * runtime/JSCJSValue.cpp:
+ (JSC::JSValue::putToPrimitive):
+ (JSC::JSValue::toStringSlowCase):
+ * runtime/JSCJSValue.h:
+ (JSC):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSCellInlines.h:
+ (JSC::JSCell::JSCell):
+ (JSC::JSCell::finishCreation):
+ (JSC::allocateCell):
+ (JSC::JSCell::setStructure):
+ (JSC::JSCell::fastGetOwnProperty):
+ * runtime/JSDateMath.cpp:
+ (JSC::getDSTOffset):
+ (JSC::getUTCOffset):
+ (JSC::parseDate):
+ * runtime/JSDestructibleObject.h:
+ (JSC::JSDestructibleObject::JSDestructibleObject):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::create):
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::finishCreation):
+ (JSC::JSFunction::createAllocationProfile):
+ (JSC::JSFunction::name):
+ (JSC::JSFunction::displayName):
+ (JSC::JSFunction::getOwnPropertySlot):
+ (JSC::JSFunction::deleteProperty):
+ * runtime/JSFunction.h:
+ (JSFunction):
+ (JSC::JSFunction::create):
+ (JSC::JSFunction::setScope):
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalData.cpp: Removed.
+ * runtime/JSGlobalData.h: Removed.
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ (JSC::JSGlobalObject::~JSGlobalObject):
+ (JSC::JSGlobalObject::setGlobalThis):
+ (JSC::JSGlobalObject::init):
+ (JSC::JSGlobalObject::putDirectVirtual):
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ (JSC::JSGlobalObject::haveABadTime):
+ (JSC::JSGlobalObject::createThrowTypeError):
+ (JSC::JSGlobalObject::resetPrototype):
+ (JSC::JSGlobalObject::addStaticGlobals):
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+ (JSC::JSGlobalObject::createProgramCodeBlock):
+ (JSC::JSGlobalObject::createEvalCodeBlock):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::create):
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::finishCreation):
+ (JSC::JSGlobalObject::vm):
+ (JSC::JSGlobalObject::createStructure):
+ (JSC::ExecState::dynamicGlobalObject):
+ (JSC::constructEmptyArray):
+ (DynamicGlobalObjectScope):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncProtoSetter):
+ * runtime/JSLock.cpp:
+ (JSC::JSLockHolder::JSLockHolder):
+ (JSC::JSLockHolder::init):
+ (JSC::JSLockHolder::~JSLockHolder):
+ (JSC::JSLock::JSLock):
+ (JSC::JSLock::willDestroyGlobalData):
+ (JSC::JSLock::lock):
+ (JSC::JSLock::unlock):
+ (JSC::JSLock::DropAllLocks::DropAllLocks):
+ (JSC::JSLock::DropAllLocks::~DropAllLocks):
+ * runtime/JSLock.h:
+ (JSC):
+ (JSLockHolder):
+ (JSLock):
+ (JSC::JSLock::vm):
+ (DropAllLocks):
+ * runtime/JSNameScope.h:
+ (JSC::JSNameScope::createStructure):
+ (JSC::JSNameScope::finishCreation):
+ (JSC::JSNameScope::JSNameScope):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::JSNotAnObject):
+ (JSC::JSNotAnObject::create):
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSONObject.cpp:
+ (JSC::JSONObject::JSONObject):
+ (JSC::JSONObject::finishCreation):
+ (Holder):
+ (JSC::Stringifier::Stringifier):
+ (JSC::Stringifier::stringify):
+ (JSC::Stringifier::toJSON):
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Stringifier::Holder::Holder):
+ (JSC::Stringifier::Holder::appendNextProperty):
+ (JSC::Walker::Walker):
+ (JSC::Walker::walk):
+ (JSC::JSONProtoFuncParse):
+ (JSC::JSONProtoFuncStringify):
+ (JSC::JSONStringify):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::createStructure):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::put):
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+ (JSC::JSObject::enterDictionaryIndexingMode):
+ (JSC::JSObject::notifyPresenceOfIndexedAccessors):
+ (JSC::JSObject::createInitialIndexedStorage):
+ (JSC::JSObject::createInitialUndecided):
+ (JSC::JSObject::createInitialInt32):
+ (JSC::JSObject::createInitialDouble):
+ (JSC::JSObject::createInitialContiguous):
+ (JSC::JSObject::createArrayStorage):
+ (JSC::JSObject::createInitialArrayStorage):
+ (JSC::JSObject::convertUndecidedToInt32):
+ (JSC::JSObject::convertUndecidedToDouble):
+ (JSC::JSObject::convertUndecidedToContiguous):
+ (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
+ (JSC::JSObject::convertUndecidedToArrayStorage):
+ (JSC::JSObject::convertInt32ToDouble):
+ (JSC::JSObject::convertInt32ToContiguous):
+ (JSC::JSObject::convertInt32ToArrayStorage):
+ (JSC::JSObject::genericConvertDoubleToContiguous):
+ (JSC::JSObject::convertDoubleToContiguous):
+ (JSC::JSObject::rageConvertDoubleToContiguous):
+ (JSC::JSObject::convertDoubleToArrayStorage):
+ (JSC::JSObject::convertContiguousToArrayStorage):
+ (JSC::JSObject::convertUndecidedForValue):
+ (JSC::JSObject::convertInt32ForValue):
+ (JSC::JSObject::setIndexQuicklyToUndecided):
+ (JSC::JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex):
+ (JSC::JSObject::convertDoubleToContiguousWhilePerformingSetIndex):
+ (JSC::JSObject::ensureInt32Slow):
+ (JSC::JSObject::ensureDoubleSlow):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::rageEnsureContiguousSlow):
+ (JSC::JSObject::ensureArrayStorageSlow):
+ (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
+ (JSC::JSObject::switchToSlowPutArrayStorage):
+ (JSC::JSObject::putDirectVirtual):
+ (JSC::JSObject::setPrototype):
+ (JSC::JSObject::setPrototypeWithCycleCheck):
+ (JSC::JSObject::putDirectAccessor):
+ (JSC::JSObject::deleteProperty):
+ (JSC::JSObject::getPropertySpecificValue):
+ (JSC::JSObject::getOwnNonIndexPropertyNames):
+ (JSC::JSObject::seal):
+ (JSC::JSObject::freeze):
+ (JSC::JSObject::preventExtensions):
+ (JSC::JSObject::reifyStaticFunctionsForDelete):
+ (JSC::JSObject::removeDirect):
+ (JSC::JSObject::putIndexedDescriptor):
+ (JSC::JSObject::defineOwnIndexedProperty):
+ (JSC::JSObject::allocateSparseIndexMap):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage):
+ (JSC::JSObject::putByIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
+ (JSC::JSObject::putDirectIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectNativeFunction):
+ (JSC::JSObject::increaseVectorLength):
+ (JSC::JSObject::ensureLengthSlow):
+ (JSC::JSObject::growOutOfLineStorage):
+ (JSC::JSObject::getOwnPropertyDescriptor):
+ (JSC::putDescriptor):
+ (JSC::JSObject::putDirectMayBeIndex):
+ (JSC::DefineOwnPropertyScope::DefineOwnPropertyScope):
+ (JSC::DefineOwnPropertyScope::~DefineOwnPropertyScope):
+ (DefineOwnPropertyScope):
+ (JSC::JSObject::defineOwnNonIndexProperty):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC::JSObject::putByIndexInline):
+ (JSC::JSObject::putDirectIndex):
+ (JSC::JSObject::setIndexQuickly):
+ (JSC::JSObject::initializeIndex):
+ (JSC::JSObject::getDirect):
+ (JSC::JSObject::getDirectOffset):
+ (JSC::JSObject::putDirect):
+ (JSC::JSObject::isSealed):
+ (JSC::JSObject::isFrozen):
+ (JSC::JSObject::flattenDictionaryObject):
+ (JSC::JSObject::ensureInt32):
+ (JSC::JSObject::ensureDouble):
+ (JSC::JSObject::ensureContiguous):
+ (JSC::JSObject::rageEnsureContiguous):
+ (JSC::JSObject::ensureArrayStorage):
+ (JSC::JSObject::finishCreation):
+ (JSC::JSObject::createStructure):
+ (JSC::JSObject::ensureLength):
+ (JSC::JSNonFinalObject::createStructure):
+ (JSC::JSNonFinalObject::JSNonFinalObject):
+ (JSC::JSNonFinalObject::finishCreation):
+ (JSC::JSFinalObject::createStructure):
+ (JSC::JSFinalObject::finishCreation):
+ (JSC::JSFinalObject::JSFinalObject):
+ (JSC::JSFinalObject::create):
+ (JSC::JSObject::setButterfly):
+ (JSC::JSObject::JSObject):
+ (JSC::JSObject::inlineGetOwnPropertySlot):
+ (JSC::JSObject::putDirectInternal):
+ (JSC::JSObject::setStructureAndReallocateStorageIfNecessary):
+ (JSC::JSObject::putOwnDataProperty):
+ (JSC::JSObject::putDirectWithoutTransition):
+ (JSC):
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::JSPropertyNameIterator):
+ (JSC::JSPropertyNameIterator::create):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::createStructure):
+ (JSC::JSPropertyNameIterator::setCachedStructure):
+ (JSC::JSPropertyNameIterator::setCachedPrototypeChain):
+ (JSC::JSPropertyNameIterator::finishCreation):
+ (JSC::StructureRareData::setEnumerationCache):
+ * runtime/JSProxy.cpp:
+ (JSC::JSProxy::setTarget):
+ * runtime/JSProxy.h:
+ (JSC::JSProxy::create):
+ (JSC::JSProxy::createStructure):
+ (JSC::JSProxy::JSProxy):
+ (JSC::JSProxy::finishCreation):
+ (JSProxy):
+ * runtime/JSScope.cpp:
+ (JSC::executeResolveOperations):
+ (JSC::JSScope::resolveContainingScopeInternal):
+ (JSC::JSScope::resolveWithBase):
+ (JSC::JSScope::resolveWithThis):
+ (JSC::JSScope::resolvePut):
+ * runtime/JSScope.h:
+ (JSScope):
+ (JSC::JSScope::JSScope):
+ (JSC::JSScope::vm):
+ (JSC::ExecState::vm):
+ * runtime/JSSegmentedVariableObject.h:
+ (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject):
+ (JSC::JSSegmentedVariableObject::finishCreation):
+ * runtime/JSString.cpp:
+ (JSC::JSRopeString::RopeBuilder::expand):
+ (JSC::StringObject::create):
+ * runtime/JSString.h:
+ (JSC):
+ (JSString):
+ (JSC::JSString::JSString):
+ (JSC::JSString::finishCreation):
+ (JSC::JSString::create):
+ (JSC::JSString::createHasOtherOwner):
+ (JSC::JSString::createStructure):
+ (JSRopeString):
+ (JSC::JSRopeString::RopeBuilder::RopeBuilder):
+ (JSC::JSRopeString::RopeBuilder::append):
+ (RopeBuilder):
+ (JSC::JSRopeString::JSRopeString):
+ (JSC::JSRopeString::finishCreation):
+ (JSC::JSRopeString::append):
+ (JSC::JSRopeString::createNull):
+ (JSC::JSRopeString::create):
+ (JSC::jsEmptyString):
+ (JSC::jsSingleCharacterString):
+ (JSC::jsSingleCharacterSubstring):
+ (JSC::jsNontrivialString):
+ (JSC::jsString):
+ (JSC::jsSubstring):
+ (JSC::jsSubstring8):
+ (JSC::jsOwnedString):
+ (JSC::jsStringBuilder):
+ (JSC::inlineJSValueNotStringtoString):
+ * runtime/JSStringJoiner.cpp:
+ (JSC::JSStringJoiner::build):
+ * runtime/JSSymbolTableObject.h:
+ (JSC::JSSymbolTableObject::JSSymbolTableObject):
+ (JSC::JSSymbolTableObject::finishCreation):
+ (JSC::symbolTablePut):
+ (JSC::symbolTablePutWithAttributes):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::JSVariableObject):
+ * runtime/JSWithScope.h:
+ (JSC::JSWithScope::create):
+ (JSC::JSWithScope::createStructure):
+ (JSC::JSWithScope::JSWithScope):
+ * runtime/JSWrapperObject.h:
+ (JSWrapperObject):
+ (JSC::JSWrapperObject::createStructure):
+ (JSC::JSWrapperObject::JSWrapperObject):
+ (JSC::JSWrapperObject::setInternalValue):
+ * runtime/LiteralParser.cpp:
+ (JSC::::tryJSONPParse):
+ (JSC::::makeIdentifier):
+ (JSC::::parse):
+ * runtime/Lookup.cpp:
+ (JSC::HashTable::createTable):
+ (JSC::setUpStaticFunctionSlot):
+ * runtime/Lookup.h:
+ (JSC::HashTable::initializeIfNeeded):
+ (JSC::HashTable::entry):
+ (JSC::HashTable::begin):
+ (JSC::HashTable::end):
+ (HashTable):
+ (JSC::lookupPut):
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::MathObject):
+ (JSC::MathObject::finishCreation):
+ (JSC::mathProtoFuncSin):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/MemoryStatistics.cpp:
+ * runtime/MemoryStatistics.h:
+ * runtime/NameConstructor.cpp:
+ (JSC::NameConstructor::finishCreation):
+ (JSC::constructPrivateName):
+ * runtime/NameConstructor.h:
+ (JSC::NameConstructor::createStructure):
+ * runtime/NameInstance.cpp:
+ (JSC::NameInstance::NameInstance):
+ * runtime/NameInstance.h:
+ (JSC::NameInstance::createStructure):
+ (JSC::NameInstance::create):
+ (NameInstance):
+ (JSC::NameInstance::finishCreation):
+ * runtime/NamePrototype.cpp:
+ (JSC::NamePrototype::NamePrototype):
+ (JSC::NamePrototype::finishCreation):
+ * runtime/NamePrototype.h:
+ (JSC::NamePrototype::createStructure):
+ * runtime/NativeErrorConstructor.h:
+ (JSC::NativeErrorConstructor::createStructure):
+ (JSC::NativeErrorConstructor::finishCreation):
+ * runtime/NativeErrorPrototype.cpp:
+ (JSC::NativeErrorPrototype::finishCreation):
+ * runtime/NumberConstructor.cpp:
+ (JSC::NumberConstructor::finishCreation):
+ (JSC::constructWithNumberConstructor):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.cpp:
+ (JSC::NumberObject::NumberObject):
+ (JSC::NumberObject::finishCreation):
+ (JSC::constructNumber):
+ * runtime/NumberObject.h:
+ (NumberObject):
+ (JSC::NumberObject::create):
+ (JSC::NumberObject::createStructure):
+ * runtime/NumberPrototype.cpp:
+ (JSC::NumberPrototype::NumberPrototype):
+ (JSC::NumberPrototype::finishCreation):
+ (JSC::integerValueToString):
+ (JSC::numberProtoFuncToString):
+ * runtime/NumberPrototype.h:
+ (JSC::NumberPrototype::createStructure):
+ * runtime/ObjectConstructor.cpp:
+ (JSC::ObjectConstructor::finishCreation):
+ (JSC::objectConstructorGetOwnPropertyDescriptor):
+ (JSC::objectConstructorSeal):
+ (JSC::objectConstructorFreeze):
+ (JSC::objectConstructorPreventExtensions):
+ (JSC::objectConstructorIsSealed):
+ (JSC::objectConstructorIsFrozen):
+ * runtime/ObjectConstructor.h:
+ (JSC::ObjectConstructor::createStructure):
+ (JSC::constructEmptyObject):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::ObjectPrototype::ObjectPrototype):
+ (JSC::ObjectPrototype::finishCreation):
+ (JSC::objectProtoFuncToString):
+ * runtime/ObjectPrototype.h:
+ (JSC::ObjectPrototype::createStructure):
+ * runtime/Operations.cpp:
+ (JSC::jsTypeStringForValue):
+ * runtime/Operations.h:
+ (JSC):
+ (JSC::jsString):
+ (JSC::jsStringFromArguments):
+ (JSC::normalizePrototypeChainForChainAccess):
+ (JSC::normalizePrototypeChain):
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyMapEntry::PropertyMapEntry):
+ (JSC::PropertyTable::createStructure):
+ (PropertyTable):
+ (JSC::PropertyTable::copy):
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArray::PropertyNameArray):
+ (JSC::PropertyNameArray::vm):
+ (JSC::PropertyNameArray::addKnownUnique):
+ (PropertyNameArray):
+ * runtime/PropertyTable.cpp:
+ (JSC::PropertyTable::create):
+ (JSC::PropertyTable::clone):
+ (JSC::PropertyTable::PropertyTable):
+ * runtime/PrototypeMap.cpp:
+ (JSC::PrototypeMap::emptyObjectStructureForPrototype):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::finishCreation):
+ (JSC::RegExp::createWithoutCaching):
+ (JSC::RegExp::create):
+ (JSC::RegExp::compile):
+ (JSC::RegExp::compileIfNecessary):
+ (JSC::RegExp::match):
+ (JSC::RegExp::compileMatchOnly):
+ (JSC::RegExp::compileIfNecessaryMatchOnly):
+ * runtime/RegExp.h:
+ (JSC):
+ (RegExp):
+ (JSC::RegExp::createStructure):
+ * runtime/RegExpCache.cpp:
+ (JSC::RegExpCache::lookupOrCreate):
+ (JSC::RegExpCache::RegExpCache):
+ (JSC::RegExpCache::addToStrongCache):
+ * runtime/RegExpCache.h:
+ (RegExpCache):
+ * runtime/RegExpCachedResult.cpp:
+ (JSC::RegExpCachedResult::lastResult):
+ (JSC::RegExpCachedResult::setInput):
+ * runtime/RegExpCachedResult.h:
+ (JSC::RegExpCachedResult::RegExpCachedResult):
+ (JSC::RegExpCachedResult::record):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpConstructor::RegExpConstructor):
+ (JSC::RegExpConstructor::finishCreation):
+ (JSC::constructRegExp):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ (RegExpConstructor):
+ (JSC::RegExpConstructor::performMatch):
+ * runtime/RegExpMatchesArray.cpp:
+ (JSC::RegExpMatchesArray::RegExpMatchesArray):
+ (JSC::RegExpMatchesArray::create):
+ (JSC::RegExpMatchesArray::finishCreation):
+ (JSC::RegExpMatchesArray::reifyAllProperties):
+ * runtime/RegExpMatchesArray.h:
+ (RegExpMatchesArray):
+ (JSC::RegExpMatchesArray::createStructure):
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::RegExpObject):
+ (JSC::RegExpObject::finishCreation):
+ (JSC::RegExpObject::match):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::create):
+ (JSC::RegExpObject::setRegExp):
+ (JSC::RegExpObject::setLastIndex):
+ (JSC::RegExpObject::createStructure):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncCompile):
+ * runtime/RegExpPrototype.h:
+ (JSC::RegExpPrototype::createStructure):
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStrings::initializeCommonStrings):
+ (JSC::SmallStrings::createEmptyString):
+ (JSC::SmallStrings::createSingleCharacterString):
+ (JSC::SmallStrings::initialize):
+ * runtime/SmallStrings.h:
+ (JSC):
+ (JSC::SmallStrings::singleCharacterString):
+ (SmallStrings):
+ * runtime/SparseArrayValueMap.cpp:
+ (JSC::SparseArrayValueMap::SparseArrayValueMap):
+ (JSC::SparseArrayValueMap::finishCreation):
+ (JSC::SparseArrayValueMap::create):
+ (JSC::SparseArrayValueMap::createStructure):
+ (JSC::SparseArrayValueMap::putDirect):
+ (JSC::SparseArrayEntry::put):
+ * runtime/SparseArrayValueMap.h:
+ * runtime/StrictEvalActivation.cpp:
+ (JSC::StrictEvalActivation::StrictEvalActivation):
+ * runtime/StrictEvalActivation.h:
+ (JSC::StrictEvalActivation::create):
+ (JSC::StrictEvalActivation::createStructure):
+ * runtime/StringConstructor.cpp:
+ (JSC::StringConstructor::finishCreation):
+ * runtime/StringConstructor.h:
+ (JSC::StringConstructor::createStructure):
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::StringObject):
+ (JSC::StringObject::finishCreation):
+ (JSC::constructString):
+ * runtime/StringObject.h:
+ (JSC::StringObject::create):
+ (JSC::StringObject::createStructure):
+ (StringObject):
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::StringPrototype):
+ (JSC::StringPrototype::finishCreation):
+ (JSC::removeUsingRegExpSearch):
+ (JSC::replaceUsingRegExpSearch):
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ (JSC::stringProtoFuncSplit):
+ * runtime/StringPrototype.h:
+ (JSC::StringPrototype::createStructure):
+ * runtime/StringRecursionChecker.h:
+ (JSC::StringRecursionChecker::performCheck):
+ (JSC::StringRecursionChecker::~StringRecursionChecker):
+ * runtime/Structure.cpp:
+ (JSC::StructureTransitionTable::add):
+ (JSC::Structure::Structure):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::despecifyDictionaryFunction):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::removePropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::toCacheableDictionaryTransition):
+ (JSC::Structure::toUncacheableDictionaryTransition):
+ (JSC::Structure::sealTransition):
+ (JSC::Structure::freezeTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::takePropertyTableOrCloneIfPinned):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::isSealed):
+ (JSC::Structure::isFrozen):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::addPropertyWithoutTransition):
+ (JSC::Structure::removePropertyWithoutTransition):
+ (JSC::Structure::allocateRareData):
+ (JSC::Structure::cloneRareDataFrom):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::get):
+ (JSC::Structure::despecifyFunction):
+ (JSC::Structure::despecifyAllFunctions):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::createPropertyMap):
+ (JSC::Structure::getPropertyNamesFromStructure):
+ (JSC::Structure::prototypeChainMayInterceptStoreTo):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::finishCreation):
+ (JSC::Structure::setPrototypeWithoutTransition):
+ (JSC::Structure::setGlobalObject):
+ (JSC::Structure::setObjectToStringValue):
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+ (JSC::Structure::setPreviousID):
+ * runtime/StructureChain.cpp:
+ (JSC::StructureChain::StructureChain):
+ * runtime/StructureChain.h:
+ (JSC::StructureChain::create):
+ (JSC::StructureChain::createStructure):
+ (JSC::StructureChain::finishCreation):
+ (StructureChain):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::create):
+ (JSC::Structure::createStructure):
+ (JSC::Structure::get):
+ (JSC::Structure::setEnumerationCache):
+ (JSC::Structure::prototypeChain):
+ (JSC::Structure::propertyTable):
+ * runtime/StructureRareData.cpp:
+ (JSC::StructureRareData::createStructure):
+ (JSC::StructureRareData::create):
+ (JSC::StructureRareData::clone):
+ (JSC::StructureRareData::StructureRareData):
+ * runtime/StructureRareData.h:
+ (StructureRareData):
+ * runtime/StructureRareDataInlines.h:
+ (JSC::StructureRareData::setPreviousID):
+ (JSC::StructureRareData::setObjectToStringValue):
+ * runtime/StructureTransitionTable.h:
+ (StructureTransitionTable):
+ (JSC::StructureTransitionTable::setSingleTransition):
+ * runtime/SymbolTable.h:
+ (JSC::SharedSymbolTable::create):
+ (JSC::SharedSymbolTable::createStructure):
+ (JSC::SharedSymbolTable::SharedSymbolTable):
+ * runtime/VM.cpp: Copied from Source/JavaScriptCore/runtime/JSGlobalData.cpp.
+ (JSC::VM::VM):
+ (JSC::VM::~VM):
+ (JSC::VM::createContextGroup):
+ (JSC::VM::create):
+ (JSC::VM::createLeaked):
+ (JSC::VM::sharedInstanceExists):
+ (JSC::VM::sharedInstance):
+ (JSC::VM::sharedInstanceInternal):
+ (JSC::VM::getHostFunction):
+ (JSC::VM::ClientData::~ClientData):
+ (JSC::VM::resetDateCache):
+ (JSC::VM::startSampling):
+ (JSC::VM::stopSampling):
+ (JSC::VM::discardAllCode):
+ (JSC::VM::dumpSampleData):
+ (JSC::VM::addSourceProviderCache):
+ (JSC::VM::clearSourceProviderCaches):
+ (JSC::VM::releaseExecutableMemory):
+ (JSC::releaseExecutableMemory):
+ (JSC::VM::gatherConservativeRoots):
+ (JSC::VM::addRegExpToTrace):
+ (JSC::VM::dumpRegExpTrace):
+ * runtime/VM.h: Copied from Source/JavaScriptCore/runtime/JSGlobalData.h.
+ (VM):
+ (JSC::VM::isSharedInstance):
+ (JSC::VM::usingAPI):
+ (JSC::VM::isInitializingObject):
+ (JSC::VM::setInitializingObjectClass):
+ (JSC::WeakSet::heap):
+ * runtime/WriteBarrier.h:
+ (JSC):
+ (JSC::WriteBarrierBase::set):
+ (JSC::WriteBarrierBase::setMayBeNull):
+ (JSC::WriteBarrierBase::setEarlyValue):
+ (JSC::WriteBarrier::WriteBarrier):
+ * testRegExp.cpp:
+ (GlobalObject):
+ (GlobalObject::create):
+ (GlobalObject::createStructure):
+ (GlobalObject::finishCreation):
+ (main):
+ (testOneRegExp):
+ (parseRegExpLine):
+ (runFromFiles):
+ (realMain):
+ * yarr/YarrInterpreter.h:
+ (BytecodePattern):
+ * yarr/YarrJIT.cpp:
+ (YarrGenerator):
+ (JSC::Yarr::YarrGenerator::compile):
+ (JSC::Yarr::jitCompile):
+ * yarr/YarrJIT.h:
+ (JSC):
+
+2013-04-18 Xuefei Ren <xren@blackberry.com>
+
+ remove build warning(unused parameter)
+ https://bugs.webkit.org/show_bug.cgi?id=114670
+
+ Reviewed by Rob Buis.
+
+ remove warning in Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
+
+ * runtime/GCActivityCallbackBlackBerry.cpp:
+ (JSC::DefaultGCActivityCallback::didAllocate):
+
+2013-04-18 Jonathan Liu <net147@gmail.com>
+
+ Implement JIT for MinGW-w64 64-bit
+ https://bugs.webkit.org/show_bug.cgi?id=114580
+
+ Reviewed by Jocelyn Turcotte.
+
+ * jit/JITStubs.cpp:
+ (JSC):
+
+2013-04-17 Mark Lam <mark.lam@apple.com>
+
+ Avoid using a branch range that is too far for some CPU architectures.
+ https://bugs.webkit.org/show_bug.cgi?id=114782.
+
+ Reviewed by David Kilzer.
+
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2013-04-17 Julien Brianceau <jbrianceau@nds.com>
+
+ Fix SH4 build (broken since r148639).
+ https://bugs.webkit.org/show_bug.cgi?id=114773.
+
+ Allow longer displacements for specific branches in SH4 LLINT.
+
+ Reviewed by Oliver Hunt.
+
+ * offlineasm/sh4.rb:
+
+2013-04-14 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. More Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-14 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-17 Mark Lam <mark.lam@apple.com>
+
+ Fix broken build. Replaced a static const with a #define.
+ https://bugs.webkit.org/show_bug.cgi?id=114577.
+
+ Unreviewed.
+
+ * runtime/Watchdog.cpp:
+ (JSC::Watchdog::Watchdog):
+ (JSC::Watchdog::isEnabled):
+
+2013-04-17 Mark Lam <mark.lam@apple.com>
+
+ Add LLINT and baseline JIT support for timing out scripts.
+ https://bugs.webkit.org/show_bug.cgi?id=114577.
+
+ Reviewed by Geoffrey Garen.
+
+ Introduces the new Watchdog class which is used to track script
+ execution time, and initiate script termination if needed.
+
+ * API/JSContextRef.cpp:
+ (internalScriptTimeoutCallback):
+ (JSContextGroupSetExecutionTimeLimit):
+ (JSContextGroupClearExecutionTimeLimit):
+ * API/JSContextRefPrivate.h:
+ - Added new script execution time limit APIs.
+ * API/tests/testapi.c:
+ (currentCPUTime):
+ (shouldTerminateCallback):
+ (cancelTerminateCallback):
+ (extendTerminateCallback):
+ (main):
+ - Added new API tests for script execution time limit.
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitLoopHint):
+ - loop hints are needed for the llint as well. Hence, it will be
+ emitted unconditionally.
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::addStackTraceIfNecessary):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ - Added checks for script termination before entering script code.
+ * jit/JIT.cpp:
+ (JSC::JIT::emitWatchdogTimerCheck):
+ * jit/JIT.h:
+ (JSC::JIT::emit_op_loop_hint):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)):
+ * jit/JITStubs.h:
+ * llint/LLIntExceptions.cpp:
+ (JSC::LLInt::doThrow):
+ - Factored out some common code from returnToThrow() and callToThrow().
+ (JSC::LLInt::returnToThrow):
+ (JSC::LLInt::callToThrow):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)):
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::throwTerminatedExecutionException):
+ - Also removed the now unused InterruptedExecutionException.
+ * runtime/ExceptionHelpers.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ - Added watchdog, and removed the now obsolete Terminator.
+ * runtime/Terminator.h: Removed.
+ * runtime/Watchdog.cpp: Added.
+ (JSC::Watchdog::Watchdog):
+ (JSC::Watchdog::~Watchdog):
+ (JSC::Watchdog::setTimeLimit):
+ (JSC::Watchdog::didFire):
+ (JSC::Watchdog::isEnabled):
+ (JSC::Watchdog::fire):
+ (JSC::Watchdog::arm):
+ (JSC::Watchdog::disarm):
+ (JSC::Watchdog::startCountdownIfNeeded):
+ (JSC::Watchdog::startCountdown):
+ (JSC::Watchdog::stopCountdown):
+ (JSC::Watchdog::Scope::Scope):
+ (JSC::Watchdog::Scope::~Scope):
+ * runtime/Watchdog.h: Added.
+ (Watchdog):
+ (JSC::Watchdog::didFire):
+ (JSC::Watchdog::timerDidFireAddress):
+ (JSC::Watchdog::isArmed):
+ (Watchdog::Scope):
+ * runtime/WatchdogMac.cpp: Added.
+ (JSC::Watchdog::initTimer):
+ (JSC::Watchdog::destroyTimer):
+ (JSC::Watchdog::startTimer):
+ (JSC::Watchdog::stopTimer):
+ * runtime/WatchdogNone.cpp: Added.
+ (JSC::Watchdog::initTimer):
+ (JSC::Watchdog::destroyTimer):
+ (JSC::Watchdog::startTimer):
+ (JSC::Watchdog::stopTimer):
+
+2013-04-14 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. VS2010 Windows build fix.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorPostBuild.cmd:
+
+2013-04-14 Roger Fong <roger_fong@apple.com>
+
+ Copy make-file-export-generator script to the the Source folders of the projects that use it.
+ <rdar://problem/13675604>
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorBuildCmd.cmd:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/make-export-file-generator: Copied from Source/WebCore/make-export-file-generator.
+
+2013-04-17 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows, WinCairo] Stop individually building WTF files in JSC.
+ https://bugs.webkit.org/show_bug.cgi?id=114705
+
+ Reviewed by Anders Carlsson.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ Export additional String/fastMalloc symbols needed by JSC program.
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj: Don't manually build
+ WTF implementation files (a second time!) in this project.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ Export additional String/fastMalloc symbols needed by JSC program.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj: Don't manually
+ build WTF implementation files (a second time!) in this project.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters: Ditto.
+
+2013-04-17 Mark Lam <mark.lam@apple.com>
+
+ releaseExecutableMemory() should canonicalize cell liveness data before
+ it scans the GC roots.
+ https://bugs.webkit.org/show_bug.cgi?id=114733.
+
+ Reviewed by Mark Hahnenberg.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::canonicalizeCellLivenessData):
+ * heap/Heap.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::releaseExecutableMemory):
+
+2013-04-16 Commit Queue <rniwa@webkit.org>
+
+ Unreviewed, rolling out r148576.
+ http://trac.webkit.org/changeset/148576
+ https://bugs.webkit.org/show_bug.cgi?id=114714
+
+ WebCore is building some of these same files (Requested by
+ bfulgham on #webkit).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj:
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters:
+
+2013-04-16 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows, WinCairo] Stop individually building WTF files in JSC.
+ https://bugs.webkit.org/show_bug.cgi?id=114705
+
+ Reviewed by Anders Carlsson.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ Export additional String/fastMalloc symbols needed by JSC program.
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj: Don't manually build
+ WTF implementation files (a second time!) in this project.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ Export additional String/fastMalloc symbols needed by JSC program.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj: Don't manually
+ build WTF implementation files (a second time!) in this project.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters: Ditto.
+
+2013-04-16 Patrick Gansterer <paroga@webkit.org>
+
+ [CMake] Do not use JAVASCRIPTCORE_DIR in add_custom_command() of JavaScriptCore project
+ https://bugs.webkit.org/show_bug.cgi?id=114265
+
+ Reviewed by Brent Fulgham.
+
+ Use CMAKE_CURRENT_SOURCE_DIR instead, since it provides the same value and is more
+ understandable. Also move the GENERATE_HASH_LUT macro into the CMakeLists.txt
+ of JavaScriptCore to avoid the usage of JAVASCRIPTCORE_DIR there too.
+
+ * CMakeLists.txt:
+
+2013-04-16 Anders Carlsson <andersca@apple.com>
+
+ Another Windows build fix attempt.
+
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+
+2013-04-16 Anders Carlsson <andersca@apple.com>
+
+ Try to fix the Windows build.
+
+ * runtime/JSGlobalData.h:
+
+2013-04-16 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows] Unreviewed VS2010 build correction.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorCommon.props:
+ Specify proper link library to avoid mixture of ICU 4.0 and 4.6
+ symbols during link.
+
+2013-04-15 Ryosuke Niwa <rniwa@webkit.org>
+
+ Windows clean build fix after r148479.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-15 Anders Carlsson <andersca@apple.com>
+
+ ScriptWrappable subclasses shouldn't have to include WeakInlines.h
+ https://bugs.webkit.org/show_bug.cgi?id=114641
+
+ Reviewed by Alexey Proskuryakov.
+
+ Move back the Weak constructor, destructor and clear() to Weak.h. Add a new weakClearSlowCase function
+ and put it in Weak.cpp.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * heap/Weak.cpp: Added.
+ * heap/Weak.h:
+ * heap/WeakInlines.h:
+ * heap/WeakSetInlines.h:
+
+2013-04-15 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ HeapTimer lifetime should be less complicated
+ https://bugs.webkit.org/show_bug.cgi?id=114529
+
+ Reviewed by Oliver Hunt.
+
+ Right now our HeapTimer lifetime is rather complicated. HeapTimers are "owned" by the JSGlobalData,
+ but there's an issue in that there can be races between a thread that is trying to tear down a JSGlobalData
+ and the HeapTimer's fire function. Our current code for tearing down HeapTimers is an intricate and delicate
+ dance which probably contains subtle bugs.
+
+ We can make our lives easier by changing things around a bit.
+
+ 1) We should free the API lock from being solely owned by the JSGlobalData so we don't have to worry about
+ grabbing the lock out of invalid memory when our HeapTimer callback fires.
+
+ 2) We should also make it so that we deref the JSGlobalData first, then unlock the API lock so that when we
+ have the lock, the JSGlobalData is in one of two states: fully valid or completely destroyed, and we know exactly which one.
+
+ 3) The JSLock can tell us this information by keeping a back pointer to the JSGlobalData. When the JSGlobalData's
+ destructor is called, it clears this pointer in the JSLock. Other clients of the API lock can then check
+ this pointer to determine whether or not the JSGlobalData is still around.
+
+ 4) The CFRunLoopTimer will use the API lock as its context rather than the HeapTimer itself. The only way
+ the HeapTimer's callback can get to the HeapTimer is through the API lock's JSGlobalData pointer.
+
+ 5) The CFRunLoopTimerContext struct has two fields for retain and release callbacks for the context's info field.
+ We'll provide these callbacks to ref() and deref() the JSLock as necessary. Thus, the timer becomes the other
+ owner of the JSLock apart from the JSGlobalData.
+
+ * API/APIShims.h: Remove the cruft that was required by the previous design, such as RefGlobalDataTag.
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (APIEntryShimWithoutLock):
+ (JSC::APIEntryShim::APIEntryShim):
+ (JSC::APIEntryShim::~APIEntryShim): Protect the API lock with a RefPtr, deref the JSGlobalData, which could destroy it,
+ then unlock the API lock. This ordering prevents others from obtaining the API lock while the JSGlobalData is in the
+ middle of being torn down.
+ (JSC::APIEntryShim::init): We now take the lock, then ref the JSGlobalData, which is the opposite order of when we
+ tear down the shim.
+ * heap/Heap.cpp:
+ (JSC::Heap::setActivityCallback): Use PassOwnPtr now.
+ (JSC::Heap::activityCallback): Ditto.
+ (JSC::Heap::sweeper): Ditto.
+ (JSC):
+ * heap/Heap.h:
+ (Heap):
+ * heap/HeapTimer.cpp:
+ (JSC::retainAPILock): Retain callback for CFRunLoopTimerContext struct.
+ (JSC::releaseAPILock): Release callback for the CFRunLoopTimerContext struct.
+ (JSC::HeapTimer::HeapTimer): Use the API lock as the context's info field rather than the HeapTimer.
+ (JSC::HeapTimer::timerDidFire): Grab the API lock. Return early if the JSGlobalData has already been destroyed.
+ Otherwise, figure out which kind of HeapTimer we are based on the CFRunLoopTimerRef passed to the callback and
+ call the HeapTimer's callback.
+ * heap/HeapTimer.h:
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::create): PassOwnPtr all the things.
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * jsc.cpp:
+ (jscmain): We use an APIEntryShim instead of a RefPtr for the JSGlobalData because we need to
+ tear down the JSGlobalData while we still hold the lock, which the APIEntryShim handles correctly.
+ * runtime/GCActivityCallback.h:
+ (DefaultGCActivityCallback):
+ (JSC::DefaultGCActivityCallback::create):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData): Notify the API lock that the JSGlobalData is being torn down.
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ (JSC::JSGlobalData::apiLock):
+ * runtime/JSLock.cpp:
+ (JSC::JSLockHolder::JSLockHolder): Ref, then lock (just like the API shim).
+ (JSC):
+ (JSC::JSLock::willDestroyGlobalData):
+ (JSC::JSLockHolder::init):
+ (JSC::JSLockHolder::~JSLockHolder): Protect, deref, then unlock (just like the API shim).
+ (JSC::JSLock::JSLock):
+ * runtime/JSLock.h: Add back pointer to the JSGlobalData and a callback for when the JSGlobalData is being
+ torn down that clears this pointer to notify other clients (i.e. timer callbacks) that the JSGlobalData is no
+ longer valid.
+ (JSLockHolder):
+ (JSLock):
+ (JSC::JSLock::globalData):
+ * testRegExp.cpp:
+ (realMain): We use an APIEntryShim instead of a RefPtr for the JSGlobalData because we need to
+ tear down the JSGlobalData while we still hold the lock, which the APIEntryShim handles correctly.
+
+2013-04-15 Julien Brianceau <jbrianceau@nds.com>
+
+ LLInt SH4 backend implementation
+ https://bugs.webkit.org/show_bug.cgi?id=112886
+
+ Reviewed by Oliver Hunt.
+
+ * dfg/DFGOperations.cpp:
+ (JSC):
+ * jit/JITStubs.cpp:
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * offlineasm/arm.rb:
+ * offlineasm/ast.rb:
+ * offlineasm/backends.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/mips.rb:
+ * offlineasm/risc.rb:
+ * offlineasm/sh4.rb: Added.
+
+2013-04-15 Patrick Gansterer <paroga@webkit.org>
+
+ [CMake] Add WTF_USE_*_UNICODE variables
+ https://bugs.webkit.org/show_bug.cgi?id=114556
+
+ Reviewed by Brent Fulgham.
+
+ WTF_USE_ICU_UNICODE and WTF_USE_WCHAR_UNICODE are used to
+ reduce duplication in the platform specific CMake files.
+
+ * CMakeLists.txt:
+ * PlatformEfl.cmake:
+
+2013-04-13 Patrick Gansterer <paroga@webkit.org>
+
+ Add missing export macro to SymbolTableEntry::freeFatEntrySlow()
+
+ * runtime/SymbolTable.h:
+ (SymbolTableEntry):
+
+2013-04-12 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Block freeing thread should call Region::destroy instead of delete
+ https://bugs.webkit.org/show_bug.cgi?id=114544
+
+ Reviewed by Oliver Hunt.
+
+ Since Region doesn't have a virtual destructor, calling delete will not properly clean up all of
+ the state of the Region. We should call destroy() instead.
+
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::releaseFreeRegions):
+ (JSC::BlockAllocator::blockFreeingThreadMain):
+
+2013-04-11 Benjamin Poulain <bpoulain@apple.com>
+
+ Merge CharacterClassTable into CharacterClass
+ https://bugs.webkit.org/show_bug.cgi?id=114409
+
+ Reviewed by Darin Adler.
+
+ CharacterClassTable is only a pointer and a boolean.
+ It is a little overkill to make a separate allocation
+ for that.
+
+ * create_regex_tables:
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::matchCharacterClass):
+ * yarr/YarrPattern.cpp:
+ (JSC::Yarr::CharacterClassConstructor::charClass):
+ * yarr/YarrPattern.h:
+ (CharacterClass):
+ (JSC::Yarr::CharacterClass::CharacterClass):
+
+2013-04-11 Michael Saboff <msaboff@apple.com>
+
+ Added UNLIKELY() suggested in https://bugs.webkit.org/show_bug.cgi?id=114366
+ after checking in the original change.
+
+ Rubber-stamped by Jessie Berlin.
+
+ * dfg/DFGOperations.cpp:
+
+2013-04-10 Benjamin Poulain <benjamin@webkit.org>
+
+ Unify JSC Parser's error and error message
+ https://bugs.webkit.org/show_bug.cgi?id=114363
+
+ Reviewed by Geoffrey Garen.
+
+ The parser kept the error state over two attributes:
+ error and errorMessage. They were changed in sync,
+ but had some discrepancy (for example, the error message
+ was always defined to something).
+
+ This patch unifies the two. There is an error if
+ if the error message is non-null or if the parsing finished
+ before the end.
+
+ This also gets rid of the allocation of the error message
+ when instantiating a parser.
+
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ (JSC::::parseInner):
+ (JSC::::parseSourceElements):
+ (JSC::::parseVarDeclaration):
+ (JSC::::parseConstDeclaration):
+ (JSC::::parseForStatement):
+ (JSC::::parseSwitchStatement):
+ (JSC::::parsePrimaryExpression):
+ * parser/Parser.h:
+ (JSC::Parser::updateErrorMessage):
+ (JSC::Parser::updateErrorWithNameAndMessage):
+ (JSC::Parser::hasError):
+ (Parser):
+
+2013-04-10 Oliver Hunt <oliver@apple.com>
+
+ Set trap is not being called for API objects
+ https://bugs.webkit.org/show_bug.cgi?id=114403
+
+ Reviewed by Anders Carlsson.
+
+ Intercept putByIndex on the callback object and add tests
+ to make sure we don't regress in future.
+
+ * API/JSCallbackObject.h:
+ (JSCallbackObject):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::putByIndex):
+ (JSC):
+ * API/tests/testapi.c:
+ (PropertyCatchalls_setProperty):
+ * API/tests/testapi.js:
+
+2013-04-10 Benjamin Poulain <bpoulain@apple.com>
+
+ Mass remove all the empty directories
+
+ Rubberstamped by Ryosuke Niwa.
+
+ * qt/api: Removed.
+ * qt/benchmarks/qscriptengine: Removed.
+ * qt/benchmarks/qscriptvalue: Removed.
+ * qt/tests/qscriptengine: Removed.
+ * qt/tests/qscriptstring: Removed.
+ * qt/tests/qscriptvalue: Removed.
+ * qt/tests/qscriptvalueiterator: Removed.
+
+2013-04-10 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ JSObject::getOwnNonIndexPropertyNames calculates numCacheableSlots incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=114235
+
+ Reviewed by Filip Pizlo.
+
+ If the object doesn't have any properties but the prototype does, we'll assume those prototype properties are
+ accessible in the base object's backing store, which is bad.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getPropertyNames):
+ (JSC::JSObject::getOwnNonIndexPropertyNames):
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArray::PropertyNameArray):
+ (JSC::PropertyNameArray::setNumCacheableSlotsForObject):
+ (JSC::PropertyNameArray::setBaseObject):
+ (PropertyNameArray):
+
+2013-04-10 Patrick Gansterer <paroga@webkit.org>
+
+ Remove code duplicates from MacroAssemblerARM
+ https://bugs.webkit.org/show_bug.cgi?id=104457
+
+ Reviewed by Oliver Hunt.
+
+ Reuse some existing methods to avoid duplicated code.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::store8):
+ (JSC::MacroAssemblerARM::store32):
+ (JSC::MacroAssemblerARM::swap):
+ (JSC::MacroAssemblerARM::add32):
+ (JSC::MacroAssemblerARM::sub32):
+
+2013-04-10 Michael Saboff <msaboff@apple.com>
+
+ DFG: Negative size for new Array() interpreted as large unsigned int
+ https://bugs.webkit.org/show_bug.cgi?id=114366
+
+ Reviewed by Oliver Hunt.
+
+ Added new check in operationNewArrayWithSize() for a negative
+ size. If size is negative throw a "RangeError: Array size is not a
+ small enough positive integer" exception.
+
+ * dfg/DFGOperations.cpp:
+
+2013-04-10 peavo@outlook.com <peavo@outlook.com>
+
+ WinCairo build fails to link.
+ https://bugs.webkit.org/show_bug.cgi?id=114358
+
+ Reviewed by Brent Fulgham.
+
+ Export the symbol WTF::MD5::checksum().
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-08 Anders Carlsson <andersca@apple.com>
+
+ Remove unneeded headers from FrameLoader.h
+ https://bugs.webkit.org/show_bug.cgi?id=114223
+
+ Reviewed by Geoffrey Garen.
+
+ Update for WTF changes.
+
+ * bytecode/SpeculatedType.h:
+ * runtime/JSCJSValue.h:
+
+2013-04-09 Geoffrey Garen <ggaren@apple.com>
+
+ Removed bitrotted TimeoutChecker code
+ https://bugs.webkit.org/show_bug.cgi?id=114336
+
+ Reviewed by Alexey Proskuryakov.
+
+ This mechanism hasn't worked for a while.
+
+ MarkL is working on a new version of this feature with a distinct
+ implementation.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShim::~APIEntryShim):
+ (JSC::APIEntryShim::init):
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGGPRInfo.h:
+ * jit/JIT.cpp:
+ * jit/JIT.h:
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+ * jit/JSInterfaceJIT.h:
+ (JSInterfaceJIT):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::appendStringifiedValue):
+ (JSC::Walker::walk):
+ * runtime/TimeoutChecker.cpp: Removed.
+ * runtime/TimeoutChecker.h: Removed.
+
+2013-04-10 Oliver Hunt <oliver@apple.com>
+
+ REGRESSION (r148073): WebKit Nightly r148082 crashes on launch in JSObjectSetPrivate
+ https://bugs.webkit.org/show_bug.cgi?id=114341
+
+ Reviewed by Alexey Proskuryakov.
+
+ Make JSObjectSetPrivate use uncheckedToJS as some clients
+ clear their private data during finalization for some reason.
+
+ * API/JSObjectRef.cpp:
+ (JSObjectSetPrivate):
+
+2013-04-09 Oliver Hunt <oliver@apple.com>
+
+ Add liveness tests to JSC API entry points
+ https://bugs.webkit.org/show_bug.cgi?id=114318
+
+ Reviewed by Geoffrey Garen.
+
+ Add simple checks for the existence of a method table on any
+ JSCells passed across the API. This in turn forces a structure
+ validity test.
+
+ * API/APICast.h:
+ (toJS):
+ (toJSForGC):
+ (unsafeToJS):
+ * API/JSObjectRef.cpp:
+ (JSObjectGetPrivate):
+
+2013-04-09 Oliver Hunt <oliver@apple.com>
+
+ Rollout last patch as it destroyed everything
+
+ * API/APICast.h:
+ (toJS):
+ (toJSForGC):
+
+2013-04-09 Oliver Hunt <oliver@apple.com>
+
+ Add liveness tests to JSC API entry points
+ https://bugs.webkit.org/show_bug.cgi?id=114318
+
+ Reviewed by Filip Pizlo.
+
+ Add simple checks for the existence of a method table on any
+ JSCells passed across the API. This in turn forces a structure
+ validity test.
+
+ * API/APICast.h:
+ (toJS):
+ (toJSForGC):
+
+2013-04-09 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ LLInt conditional branch compilation fault on MIPS.
+ https://bugs.webkit.org/show_bug.cgi?id=114264
+
+ Reviewed by Filip Pizlo.
+
+ Fix conditional branch compilation in LLInt offlineasm.
+
+ * offlineasm/mips.rb:
+
+2013-04-08 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ JSObject::getOwnNonIndexPropertyNames calculates numCacheableSlots incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=114235
+
+ Reviewed by Geoffrey Garen.
+
+ Due to the way that numCacheableSlots is currently calculated, checking an object's prototype for enumerable
+ properties causes us not to cache any properties at all. We should only cache properties on the object itself
+ since we currently don't take advantage of any sort of name caching for properties in the prototype chain.
+ This fix undoes a ~2% SunSpider regression caused by http://trac.webkit.org/changeset/147570.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getOwnNonIndexPropertyNames):
+
+2013-04-09 Ryosuke Niwa <rniwa@webkit.org>
+
+ Remove yarr.gyp
+ https://bugs.webkit.org/show_bug.cgi?id=114247
+
+ Reviewed by Benjamin Poulain.
+
+ * yarr/yarr.gyp: Removed.
+
+2013-04-08 Ryosuke Niwa <rniwa@webkit.org>
+
+ Remove JavaScriptCore.gyp/gypi
+ https://bugs.webkit.org/show_bug.cgi?id=114238
+
+ Reviewed by Benjamin Poulain.
+
+ * JavaScriptCore.gyp: Removed.
+ * JavaScriptCore.gyp/.gitignore: Removed.
+ * JavaScriptCore.gypi: Removed.
+
+2013-04-08 Vahag Vardanyan <vaag@ispras.ru>
+
+ Adds fromCharCode intrinsic support.
+ https://bugs.webkit.org/show_bug.cgi?id=104807
+
+ Reviewed by Oliver Hunt.
+
+ Switch to using fromCharCode intrinsic instead of call operation in some cases.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileFromCharCode):
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/StringConstructor.cpp:
+ (JSC::stringFromCharCode):
+ (JSC):
+ * runtime/StringConstructor.h:
+ (JSC):
+
+2013-04-08 Benjamin Poulain <benjamin@webkit.org>
+
+ Remove HTML Notification
+ https://bugs.webkit.org/show_bug.cgi?id=114231
+
+ Reviewed by Ryosuke Niwa.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-04-05 Roger Fong <roger_fong@apple.com>
+
+ Build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should be able to inline string equality comparisons
+ https://bugs.webkit.org/show_bug.cgi?id=114224
+
+ Reviewed by Oliver Hunt.
+
+ Inline 8-bit string equality, go to slow path for 16-bit strings. 2x speed-up for string equality
+ comparisons on 8-bit strings. 20-50% speed-up on JSRegress/HashMap tests. 30% speed-up on
+ string-fasta. 2% speed-up on SunSpider overall. Some small speed-ups elsewhere.
+
+ This is a gnarly change but we have loads of test coverage already between the HashMap tests and
+ preexisting DFG string equality tests (which appear to have been designed to test OSR exits, but
+ also give us good overall coverage on string equality behavior).
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::compare):
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ (JSC::DFG::SpeculativeJIT::compileStringEquality):
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2013-04-08 Geoffrey Garen <ggaren@apple.com>
+
+ Stop #include-ing all of JavaScriptCore in every DOM-related file
+ https://bugs.webkit.org/show_bug.cgi?id=114220
+
+ Reviewed by Sam Weinig.
+
+ I separated WeakInlines.h from Weak.h so WebCore data types that need
+ to declare a Weak<T> data member don't have to #include all of the
+ infrastructure for accessing that data member.
+
+ This also required separating Weak<T> from PassWeak<T> by removing the
+ WeakImplAccessor class template and pushing code down into its subclasses.
+
+ * API/JSWeakObjectMapRefPrivate.cpp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/UnlinkedCodeBlock.h:
+ * heap/PassWeak.h:
+ (JSC):
+ (PassWeak):
+ (JSC::::PassWeak):
+ (JSC::::operator):
+ (JSC::::get):
+ * heap/SlotVisitorInlines.h:
+ * heap/Weak.h:
+ (JSC):
+ (Weak):
+ * heap/WeakInlines.h: Copied from Source/JavaScriptCore/heap/Weak.h.
+ (JSC):
+ (JSC::::Weak):
+ (JSC::::operator):
+ (JSC::::get):
+ (JSC::::was):
+ (JSC::weakClear):
+ * jit/JITThunks.h:
+ * runtime/RegExpCache.h:
+ * runtime/Structure.h:
+ * runtime/WeakGCMap.h:
+
+2013-04-05 Roger Fong <roger_fong@apple.com>
+
+ Windows build fix fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-04-05 Roger Fong <roger_fong@apple.com>
+
+ Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-08 Oliver Hunt <oliver@apple.com>
+
+ Make resolve more robust in the face of lookup misses
+ https://bugs.webkit.org/show_bug.cgi?id=114211
+
+ Reviewed by Filip Pizlo.
+
+ This simply short circuits the resolve operations in the
+ event that we don't find a path to a property. There's no
+ repro case for this happening unfortunately.
+
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
+2013-04-08 Oliver Hunt <oliver@apple.com>
+
+ Build fix.
+
+ * assembler/ARMv7Assembler.h:
+ (ARMv7Assembler):
+
+2013-04-08 Justin Haygood <jhaygood@reaktix.com>
+
+ Allow KeywordLookupGenerator.py to work on Windows with Windows style line endings
+ https://bugs.webkit.org/show_bug.cgi?id=63234
+
+ Reviewed by Oliver Hunt.
+
+ * KeywordLookupGenerator.py:
+ (parseKeywords):
+
+2013-04-08 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION(r146669): Assertion hit in JSC::DFG::SpeculativeJIT::fillSpeculateCell() running webgl tests
+ https://bugs.webkit.org/show_bug.cgi?id=114129
+ <rdar://problem/13594898>
+
+ Reviewed by Darin Adler.
+
+ The check to see if we need a cell check when simplifying a GetById or PutById needs to be hoisted to
+ above where we abstractly execute the instruction, since after we abstracting execute it, it will
+ seem like it no longer needs the cell check.
+
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2013-04-07 Oliver Hunt <oliver@apple.com>
+
+ Add bounds checking for WTF::Vector::operator[]
+ https://bugs.webkit.org/show_bug.cgi?id=89600
+
+ Reviewed by Filip Pizlo.
+
+ Make a few JSC classes opt-out of release mode bounds checking.
+
+ * assembler/AssemblerBuffer.h:
+ (AssemblerBuffer):
+ * assembler/AssemblerBufferWithConstantPool.h:
+ (AssemblerBufferWithConstantPool):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::bytecodeOffset):
+ (JSC):
+ (JSC::replaceExistingEntries):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::bytecodeOffsetForCallAtIndex):
+ (JSC::CodeBlock::callReturnIndexVector):
+ (JSC::CodeBlock::codeOrigins):
+ (RareData):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedEvalCodeBlock::adoptVariables):
+ (UnlinkedEvalCodeBlock):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitNewArray):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitConstruct):
+ * bytecompiler/BytecodeGenerator.h:
+ (CallArguments):
+ (JSC::BytecodeGenerator::instructions):
+ (BytecodeGenerator):
+ * bytecompiler/StaticPropertyAnalysis.h:
+ (JSC::StaticPropertyAnalysis::create):
+ (JSC::StaticPropertyAnalysis::StaticPropertyAnalysis):
+ (StaticPropertyAnalysis):
+ * bytecompiler/StaticPropertyAnalyzer.h:
+ (StaticPropertyAnalyzer):
+ (JSC::StaticPropertyAnalyzer::StaticPropertyAnalyzer):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ * runtime/ArgList.h:
+ (MarkedArgumentBuffer):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSort):
+
+2013-04-07 Benjamin Poulain <benjamin@webkit.org>
+
+ Use Vector::reserveInitialCapacity() when possible in JavaScriptCore runtime
+ https://bugs.webkit.org/show_bug.cgi?id=114111
+
+ Reviewed by Andreas Kling.
+
+ Almost all the code was already using Vector::reserveInitialCapacity()
+ and Vector::uncheckedAppend(). Fix the remaining parts.
+
+ * runtime/ArgList.h:
+ (MarkedArgumentBuffer): The type VectorType is unused.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSort):
+ Move the variable closer to where it is needed.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::setLengthWithArrayStorage):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getOwnPropertyNames):
+
+2013-04-07 Patrick Gansterer <paroga@webkit.org>
+
+ Remove references to Skia and V8 from CMake files
+ https://bugs.webkit.org/show_bug.cgi?id=114130
+
+ Reviewed by Geoffrey Garen.
+
+ * shell/PlatformBlackBerry.cmake:
+
+2013-04-07 David Kilzer <ddkilzer@apple.com>
+
+ Remove the rest of SVG_DOM_OBJC_BINDINGS
+ <http://webkit.org/b/114112>
+
+ Reviewed by Geoffrey Garen.
+
+ * Configurations/FeatureDefines.xcconfig:
+ - Remove ENABLE_SVG_DOM_OBJC_BINDINGS macro.
+
+2013-04-07 Oliver Hunt <oliver@apple.com>
+
+ Inspector should display information about non-object exceptions
+ https://bugs.webkit.org/show_bug.cgi?id=114123
+
+ Reviewed by Adele Peterson.
+
+ Make sure we store the right stack information, even when throwing
+ a primitive.
+
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::clearSupplementaryExceptionInfo):
+ (ExecState):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::addStackTraceIfNecessary):
+ (JSC::Interpreter::throwException):
+
+2013-04-06 Oliver Hunt <oliver@apple.com>
+
+ Unify the many and varied stack trace mechanisms, and make the result sane.
+ https://bugs.webkit.org/show_bug.cgi?id=114072
+
+ Reviewed by Filip Pizlo.
+
+ Makes JSC::StackFrame record the bytecode offset and other necessary data
+ rather than requiring us to perform eager evaluation of the line number, etc.
+ Then remove most of the users of retrieveLastCaller, as most of them were
+ using it to create a stack trace in a fairly incomplete and inefficient way.
+
+ StackFrame now also has a couple of helpers to get the line and column info.
+
+ * API/JSContextRef.cpp:
+ (JSContextCreateBacktrace):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::getBytecodeOffsetForCallFrame):
+ (JSC::getCallerInfo):
+ (JSC::StackFrame::line):
+ (JSC::StackFrame::column):
+ (JSC::StackFrame::expressionInfo):
+ (JSC::StackFrame::toString):
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::addStackTraceIfNecessary):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ * interpreter/Interpreter.h:
+ (StackFrame):
+ (Interpreter):
+ * runtime/Error.cpp:
+ (JSC::throwError):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+
+2013-04-06 Geoffrey Garen <ggaren@apple.com>
+
+ Removed v8 bindings hooks from IDL files
+ https://bugs.webkit.org/show_bug.cgi?id=114091
+
+ Reviewed by Anders Carlsson and Sam Weinig.
+
+ * heap/HeapStatistics.h:
+
+2013-04-03 Roger Fong <roger_fong@apple.com>
+
+ Windows VS2010 build fix.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-06 Zan Dobersek <zdobersek@igalia.com>
+
+ Remove the remaining PLATFORM(CHROMIUM) guard in JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=114082
+
+ Reviewed by Ryosuke Niwa.
+
+ * runtime/JSExportMacros.h: Remove the remaining PLATFORM(CHROMIUM) guard.
+
+2013-04-06 Ed Bartosh <bartosh@gmail.com>
+
+ --minimal build fails with error: control reaches end of non-void function
+ https://bugs.webkit.org/show_bug.cgi?id=114085
+
+ Reviewed by Oliver Hunt.
+
+ * interpreter/Interpreter.cpp: return 0 if JIT is not enabled
+ (JSC::getBytecodeOffsetForCallFrame):
+
+2013-04-06 Geoffrey Garen <ggaren@apple.com>
+
+ Try to fix the Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ Added back a symbol that is exported.
+
+2013-04-06 Geoffrey Garen <ggaren@apple.com>
+
+ Try to fix the Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ Removed symbols that aren't exported.
+
+2013-04-06 Geoffrey Garen <ggaren@apple.com>
+
+ Rolled out 147820 and 147818 because they caused plugins tests to ASSERT
+ https://bugs.webkit.org/show_bug.cgi?id=114094
+
+ Reviewed by Anders Carlsson.
+
+ * API/JSContextRef.cpp:
+ (JSContextCreateBacktrace):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::getLineNumberForCallFrame):
+ (JSC::getCallerInfo):
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::addStackTraceIfNecessary):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ * interpreter/Interpreter.h:
+ (StackFrame):
+ (JSC::StackFrame::toString):
+ (JSC::StackFrame::friendlyLineNumber):
+ (Interpreter):
+ * runtime/Error.cpp:
+ (JSC::throwError):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+
+2013-04-06 Patrick Gansterer <paroga@webkit.org>
+
+ Unreviewed build fix after r146932.
+
+ * profiler/ProfilerDatabase.cpp:
+ (Profiler):
+
+2013-04-06 Patrick Gansterer <paroga@webkit.org>
+
+ Do not call getenv() on Windows CE where it does not exist.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+2013-04-05 Benjamin Poulain <benjamin@webkit.org>
+
+ Second attempt to fix the Windows bot
+
+ Unreviewed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-05 Benjamin Poulain <bpoulain@apple.com>
+
+ Attempt to fix the Windows bot
+
+ Unreviewed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ r147825 removed the symbol for nullptr_t. Add it back.
+
+2013-04-02 Roger Fong <roger_fong@apple.com>
+
+ Build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-05 Oliver Hunt <oliver@apple.com>
+
+ Build fix.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getBytecodeOffsetForCallFrame):
+
+2013-04-05 Oliver Hunt <oliver@apple.com>
+
+ Unify the many and varied stack trace mechanisms, and make the result sane.
+ https://bugs.webkit.org/show_bug.cgi?id=114072
+
+ Reviewed by Filip Pizlo.
+
+ Makes JSC::StackFrame record the bytecode offset and other necessary data
+ rather than requiring us to perform eager evaluation of the line number, etc.
+ Then remove most of the users of retrieveLastCaller, as most of them were
+ using it to create a stack trace in a fairly incomplete and inefficient way.
+
+ StackFrame now also has a couple of helpers to get the line and column info.
+
+ * API/JSContextRef.cpp:
+ (JSContextCreateBacktrace):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::getBytecodeOffsetForCallFrame):
+ (JSC::getCallerInfo):
+ (JSC::StackFrame::line):
+ (JSC::StackFrame::column):
+ (JSC::StackFrame::expressionInfo):
+ (JSC::StackFrame::toString):
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::addStackTraceIfNecessary):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+ * interpreter/Interpreter.h:
+ (StackFrame):
+ (Interpreter):
+ * runtime/Error.cpp:
+ (JSC::throwError):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+
+2013-04-05 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ tryCacheGetByID sets StructureStubInfo accessType to an incorrect value
+ https://bugs.webkit.org/show_bug.cgi?id=114068
+
+ Reviewed by Geoffrey Garen.
+
+ In the case where we have a non-Value cacheable property, we set the StructureStubInfo accessType to
+ get_by_id_self, but then we don't patch self and instead patch in a get_by_id_self_fail. This leads to
+ incorrect profiling data so when the DFG compiles the function, it uses a GetByOffset rather than a GetById,
+ which leads to loading a GetterSetter directly out of an object.
+
+ * jit/JITStubs.cpp:
+ (JSC::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2013-04-05 Filip Pizlo <fpizlo@apple.com>
+
+ If CallFrame::trueCallFrame() knows that it's about to read garbage instead of a valid CodeOrigin/InlineCallFrame, then it should give up and return 0 and all callers should be robust against this
+ https://bugs.webkit.org/show_bug.cgi?id=114062
+
+ Reviewed by Oliver Hunt.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::canGetCodeOrigin):
+ (CodeBlock):
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::trueCallFrame):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::getStackTrace):
+
+2013-04-05 Geoffrey Garen <ggaren@apple.com>
+
+ Made USE(JSC) unconditional
+ https://bugs.webkit.org/show_bug.cgi?id=114058
+
+ Reviewed by Anders Carlsson.
+
+ * config.h:
+
+2013-04-05 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, rolling out http://trac.webkit.org/changeset/147729
+
+ It's causing a bunch of breakage on some more strict compilers:
+ <inline asm>:1267:2: error: ambiguous instructions require an explicit suffix (could be 'ficomps', or 'ficompl')
+
+ * offlineasm/x86.rb:
+
+2013-04-05 Roger Fong <roger_fong@apple.com>
+
+ More VS2010 solution makefile fixes.
+ <rdar://problem/13588964>
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.make:
+
+2013-04-05 Allan Sandfeld Jensen <allan.jensen@digia.com>
+
+ LLint should be able to use x87 instead of SSE for floating pointer
+
+ https://bugs.webkit.org/show_bug.cgi?id=112239
+
+ Reviewed by Filip Pizlo.
+
+ Implements LLInt floating point operations in x87, to ensure we support
+ x86 without SSE2.
+
+ X86 (except 64bit) now defaults to using x87 instructions in order to
+ support all 32bit x86 back to i686. The implementation uses the fucomi
+ instruction from i686 which sets the new minimum.
+
+ * offlineasm/x86.rb:
+
+2013-04-04 Christophe Dumez <ch.dumez@sisa.samsung.com>
+
+ Unreviewed EFL build fix.
+
+ We had undefined reference to `JSC::CodeOrigin::maximumBytecodeIndex'.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::findClosureCallForReturnPC):
+ (JSC::CodeBlock::bytecodeOffset):
+
+2013-04-04 Geoffrey Garen <ggaren@apple.com>
+
+ Stop pretending that statements return a value
+ https://bugs.webkit.org/show_bug.cgi?id=113969
+
+ Reviewed by Oliver Hunt.
+
+ Expressions have an intrinsic value, which they return to their parent
+ in the AST.
+
+ Statements just execute for effect in sequence.
+
+ This patch moves emitBytecode into the ExpressionNode and StatementNode
+ subclasses, and changes the SatementNode subclass to return void. This
+ eliminates some cruft where we used to return 0, or try to save a bogus
+ register and return it, as if a statement had a consuming parent in the
+ AST.
+
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitNode):
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitNodeInConditionContext):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::BlockNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::CaseClauseNode::emitBytecode):
+ (JSC::CaseBlockNode::emitBytecodeForBlock):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::ScopeNode::emitStatementsBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ (JSC::FuncDeclNode::emitBytecode):
+ * parser/NodeConstructors.h:
+ (JSC::PropertyListNode::PropertyListNode):
+ (JSC::ArgumentListNode::ArgumentListNode):
+ * parser/Nodes.h:
+ (Node):
+ (ExpressionNode):
+ (StatementNode):
+ (ConstStatementNode):
+ (BlockNode):
+ (EmptyStatementNode):
+ (DebuggerStatementNode):
+ (ExprStatementNode):
+ (VarStatementNode):
+ (IfNode):
+ (IfElseNode):
+ (DoWhileNode):
+ (WhileNode):
+ (ForNode):
+ (ForInNode):
+ (ContinueNode):
+ (BreakNode):
+ (ReturnNode):
+ (WithNode):
+ (LabelNode):
+ (ThrowNode):
+ (TryNode):
+ (ProgramNode):
+ (EvalNode):
+ (FunctionBodyNode):
+ (FuncDeclNode):
+ (CaseBlockNode):
+ (SwitchNode):
+
+2013-04-04 Oliver Hunt <oliver@apple.com>
+
+ Exception stack unwinding doesn't handle inline callframes correctly
+ https://bugs.webkit.org/show_bug.cgi?id=113952
+
+ Reviewed by Geoffrey Garen.
+
+ The basic problem here is that the exception stack unwinding was
+ attempting to be "clever" and avoid doing a correct stack walk
+ as it "knew" inline callframes couldn't have exception handlers.
+
+ This used to be safe as the exception handling machinery was
+ designed to fail gently and just claim that no handler existed.
+ This was "safe" and even "correct" inasmuch as we currently
+ don't run any code with exception handlers through the dfg.
+
+ This patch fixes the logic by simply making everything uniformly
+ use the safe stack walking machinery, and making the correct
+ boundary checks occur everywhere that they should.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::findClosureCallForReturnPC):
+ (JSC::CodeBlock::bytecodeOffset):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::getCallerInfo):
+ (JSC::Interpreter::getStackTrace):
+ (JSC::Interpreter::retrieveCallerFromVMCode):
+
+2013-04-04 Geoffrey Garen <ggaren@apple.com>
+
+ Removed a defunct comment
+ https://bugs.webkit.org/show_bug.cgi?id=113948
+
+ Reviewed by Oliver Hunt.
+
+ This is also a convenient way to test the EWS.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC):
+
+2013-04-04 Martin Robinson <mrobinson@igalia.com>
+
+ [GTK] Remove the gyp build
+ https://bugs.webkit.org/show_bug.cgi?id=113942
+
+ Reviewed by Gustavo Noronha Silva.
+
+ * JavaScriptCore.gyp/JavaScriptCoreGTK.gyp: Removed.
+ * JavaScriptCore.gyp/redirect-stdout.sh: Removed.
+
+2013-04-04 Geoffrey Garen <ggaren@apple.com>
+
+ Simplified bytecode generation by merging prefix and postfix nodes
+ https://bugs.webkit.org/show_bug.cgi?id=113925
+
+ Reviewed by Filip Pizlo.
+
+ PostfixNode now inherits from PrefixNode, so when we detect that we're
+ in a context where postifx and prefix are equivalent, PostFixNode can
+ just call through to PrefixNode codegen, instead of duplicating the
+ logic.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PostfixNode::emitBracket):
+ (JSC::PostfixNode::emitDot):
+ * parser/NodeConstructors.h:
+ (JSC::PostfixNode::PostfixNode):
+ * parser/Nodes.h:
+ (JSC):
+ (PrefixNode):
+ (PostfixNode):
+
+2013-04-04 Andras Becsi <andras.becsi@digia.com>
+
+ Fix the build with GCC 4.8
+ https://bugs.webkit.org/show_bug.cgi?id=113147
+
+ Reviewed by Allan Sandfeld Jensen.
+
+ Initialize JSObject* exception to suppress warnings that make
+ the build fail because of -Werror=maybe-uninitialized.
+
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+
+2013-04-02 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ get_by_pname can become confused when iterating over objects with static properties
+ https://bugs.webkit.org/show_bug.cgi?id=113831
+
+ Reviewed by Geoffrey Garen.
+
+ get_by_pname doesn't take static properties into account when using a JSPropertyNameIterator to directly
+ access an object's backing store. One way to fix this is to not cache any properties when iterating over
+ objects with static properties. This patch fixes the bug that was originally reported on swisscom.ch.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getOwnNonIndexPropertyNames):
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::create):
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArray::PropertyNameArray):
+ (JSC::PropertyNameArray::numCacheableSlots):
+ (JSC::PropertyNameArray::setNumCacheableSlots):
+ (PropertyNameArray):
+
+2013-04-02 Geoffrey Garen <ggaren@apple.com>
+
+ DFG should compile a little sooner
+ https://bugs.webkit.org/show_bug.cgi?id=113835
+
+ Unreviewed.
+
+ Rolled out r147511 because it was based on incorrect performance
+ measurement.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::optimizationThresholdScalingFactor):
+
+2013-04-02 Geoffrey Garen <ggaren@apple.com>
+
+ DFG should compile a little sooner
+ https://bugs.webkit.org/show_bug.cgi?id=113835
+
+ Reviewed by Michael Saboff.
+
+ 2% speedup on SunSpider.
+
+ 2% speedup on JSRegress.
+
+ Neutral on Octane, v8, and Kraken.
+
+ The worst-hit single sub-test is kraken-stanford-crypto-ccm.js, which gets
+ 18% slower. Since Kraken is neutral overall in its preferred mean, I
+ think that's OK for now.
+
+ (Our array indexing speculation fails pathologically on
+ kraken-stanford-crypto-ccm.js. Compiling sooner is a regression because
+ it triggers those failures sooner. I'm going to file some follow-up bugs
+ explaining how to fix our speculations on this sub-test, at which point
+ compiling earlier should become a slight speedup on Kraken overall.)
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::optimizationThresholdScalingFactor): I experimented
+ with a few different options, including reducing the coefficient 'a'.
+ A simple linear reduction on instruction count worked best.
+
+2013-04-01 Benjamin Poulain <benjamin@webkit.org>
+
+ Use Vector::reserveInitialCapacity and Vector::uncheckedAppend for JSC's APIs
+ https://bugs.webkit.org/show_bug.cgi?id=113651
+
+ Reviewed by Andreas Kling.
+
+ This removes a bunch of branches on initialization and when
+ filling the vector.
+
+ * API/JSCallbackConstructor.cpp:
+ (JSC::constructJSCallback):
+ * API/JSCallbackFunction.cpp:
+ (JSC::JSCallbackFunction::call):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::construct):
+ (JSC::::call):
+ * API/JSObjectRef.cpp:
+ (JSObjectCopyPropertyNames):
+
+2013-04-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Fixing borked VS 2010 project file
+
+ Unreviewed bot greening.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2013-04-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ One more Windows build fix
+
+ Unreviewed.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-04-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ More build fallout fixes.
+
+ Unreviewed build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def: Add new export symbols.
+ * heap/SuperRegion.cpp: Windows didn't like "LLU".
+
+2013-04-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ r147324 broke the world
+ https://bugs.webkit.org/show_bug.cgi?id=113704
+
+ Unreviewed build fix.
+
+ Remove a bunch of unused variables and use the correctly sized types for 32-bit platforms.
+
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::BlockAllocator):
+ * heap/BlockAllocator.h:
+ (BlockAllocator):
+ * heap/Heap.cpp:
+ (JSC::Heap::Heap):
+ * heap/SuperRegion.cpp:
+ (JSC::SuperRegion::SuperRegion):
+ * heap/SuperRegion.h:
+ (SuperRegion):
+
+2013-04-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ 32-bit Windows build fix
+
+ Unreviewed build fix.
+
+ * heap/SuperRegion.cpp:
+ * heap/SuperRegion.h: Use uint64_t instead of size_t.
+ (SuperRegion):
+
+2013-04-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ EFL build fix
+
+ Unreviewed build fix.
+
+ * CMakeLists.txt:
+
+2013-03-31 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Regions should be allocated from the same contiguous segment of virtual memory
+ https://bugs.webkit.org/show_bug.cgi?id=113662
+
+ Reviewed by Filip Pizlo.
+
+ Instead of letting the OS spread our Regions all over the place, we should allocate them all within
+ some range of each other. This change will open the door to some other optimizations, e.g. doing simple
+ range checks for our write barriers and compressing JSCell pointers to 32-bits.
+
+ Added new SuperRegion class that encapsulates allocating Regions from a contiguous reserved chunk of
+ virtual address space. It functions very similarly to the FixedVMPoolExecutableAllocator class used by the JIT.
+
+ Also added two new subclasses of Region, NormalRegion and ExcessRegion.
+
+ NormalRegion is the type of Region that is normally allocated when there is available space remaining
+ in the SuperRegion. If we ever run out of space in the SuperRegion, we fall back to allocating
+ ExcessRegions, which are identical to how Regions have behaved up until now, i.e. they contain a
+ PageAllocationAligned.
+
+ We only use the SuperRegion (and NormalRegions) on 64-bit systems, since it doesn't make sense to reserve the
+ entire 4 GB address space on 32-bit systems just for the JS heap.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::BlockAllocator):
+ * heap/BlockAllocator.h:
+ (JSC):
+ (BlockAllocator):
+ (JSC::BlockAllocator::allocate):
+ (JSC::BlockAllocator::allocateCustomSize):
+ (JSC::BlockAllocator::deallocateCustomSize):
+ * heap/Heap.cpp:
+ (JSC::Heap::Heap):
+ (JSC):
+ (JSC::Heap::didExceedFixedHeapSizeLimit):
+ * heap/Heap.h:
+ (Heap):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::create):
+ * heap/Region.h:
+ (Region):
+ (JSC):
+ (NormalRegion):
+ (JSC::NormalRegion::base):
+ (JSC::NormalRegion::size):
+ (ExcessRegion):
+ (JSC::ExcessRegion::base):
+ (JSC::ExcessRegion::size):
+ (JSC::NormalRegion::NormalRegion):
+ (JSC::NormalRegion::tryCreate):
+ (JSC::NormalRegion::tryCreateCustomSize):
+ (JSC::NormalRegion::reset):
+ (JSC::ExcessRegion::ExcessRegion):
+ (JSC::ExcessRegion::~ExcessRegion):
+ (JSC::ExcessRegion::create):
+ (JSC::ExcessRegion::createCustomSize):
+ (JSC::ExcessRegion::reset):
+ (JSC::Region::Region):
+ (JSC::Region::initializeBlockList):
+ (JSC::Region::create):
+ (JSC::Region::createCustomSize):
+ (JSC::Region::~Region):
+ (JSC::Region::destroy):
+ (JSC::Region::reset):
+ (JSC::Region::deallocate):
+ (JSC::Region::base):
+ (JSC::Region::size):
+ * heap/SuperRegion.cpp: Added.
+ (JSC):
+ (JSC::SuperRegion::SuperRegion):
+ (JSC::SuperRegion::getAlignedBase):
+ (JSC::SuperRegion::allocateNewSpace):
+ (JSC::SuperRegion::notifyNeedPage):
+ (JSC::SuperRegion::notifyPageIsFree):
+ * heap/SuperRegion.h: Added.
+ (JSC):
+ (SuperRegion):
+
+2013-04-01 Benjamin Poulain <benjamin@webkit.org>
+
+ Remove an unused variable from the ARMv7 Assembler
+ https://bugs.webkit.org/show_bug.cgi?id=113653
+
+ Reviewed by Andreas Kling.
+
+ * assembler/ARMv7Assembler.h:
+ (ARMv7Assembler):
+
+2013-03-31 Adam Barth <abarth@webkit.org>
+
+ [Chromium] Yarr should build using a separate GYP file from JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=113652
+
+ Reviewed by Nico Weber.
+
+ This patch moves JavaScriptCore.gyp to yarr.gyp because Chromium only
+ uses this GYP file to build yarr.
+
+ * JavaScriptCore.gyp/JavaScriptCoreGTK.gyp:
+ * JavaScriptCore.gypi:
+ * yarr/yarr.gyp: Renamed from Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp.
+
+2013-03-31 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix a comment. While thinking about TBAA for array accesses,
+ I realized that we have to be super careful about aliasing of typed arrays.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+
+2013-03-30 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Move Region into its own header
+ https://bugs.webkit.org/show_bug.cgi?id=113617
+
+ Reviewed by Geoffrey Garen.
+
+ BlockAllocator.h is getting a little crowded. We should move the Region class into its own
+ header, since it's pretty independent from the BlockAllocator.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * heap/BlockAllocator.h:
+ (JSC):
+ * heap/Region.h: Added.
+ (JSC):
+ (DeadBlock):
+ (JSC::DeadBlock::DeadBlock):
+ (Region):
+ (JSC::Region::blockSize):
+ (JSC::Region::isFull):
+ (JSC::Region::isEmpty):
+ (JSC::Region::isCustomSize):
+ (JSC::Region::create):
+ (JSC::Region::createCustomSize):
+ (JSC::Region::Region):
+ (JSC::Region::~Region):
+ (JSC::Region::reset):
+ (JSC::Region::allocate):
+ (JSC::Region::deallocate):
+
+2013-03-29 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Remove -[JSManagedValue managedValueWithValue:owner:]
+ https://bugs.webkit.org/show_bug.cgi?id=113602
+
+ Reviewed by Geoffrey Garen.
+
+ Since we put the primary way of keeping track of external object graphs (i.e. "managed" references)
+ in JSVirtualMachine, there is some overlap in the functionality of that interface and JSManagedValue.
+ Specifically, we no longer need the methods that include an owner, since ownership is now tracked
+ by JSVirtualMachine. These JSManagedValues will become weak pointers unless they are used
+ with [JSVirtualMachine addManagedReference:withOwner:], in which case their lifetime is tied to that
+ of their owner.
+
+ * API/JSManagedValue.h:
+ * API/JSManagedValue.mm:
+ (-[JSManagedValue init]):
+ (-[JSManagedValue initWithValue:]):
+ (JSManagedValueHandleOwner::isReachableFromOpaqueRoots):
+ * API/JSVirtualMachine.mm:
+ (getInternalObjcObject):
+ * API/tests/testapi.mm:
+ (-[TextXYZ setOnclick:]):
+ (-[TextXYZ dealloc]):
+
+2013-03-29 Geoffrey Garen <ggaren@apple.com>
+
+ Simplified bytecode generation by unforking "condition context" codegen
+ https://bugs.webkit.org/show_bug.cgi?id=113554
+
+ Reviewed by Mark Hahnenberg.
+
+ Now, a node that establishes a condition context can always ask its child
+ nodes to generate into that context.
+
+ This has a few advantages:
+
+ (*) Removes a bunch of code;
+
+ (*) Optimizes a few missed cases like "if (!(x < 2))", "if (!!x)", and
+ "if (!x || !y)";
+
+ (*) Paves the way to removing more opcodes.
+
+ * bytecode/Opcode.h:
+ (JSC): Separated out the branching opcodes for clarity.
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ExpressionNode::emitBytecodeInConditionContext): All expressions
+ can be emitted in a condition context now -- the default behavior is
+ to branch based on the expression's value.
+
+ (JSC::LogicalNotNode::emitBytecodeInConditionContext):
+ (JSC::LogicalOpNode::emitBytecodeInConditionContext):
+ (JSC::ConditionalNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::isSubtract):
+ (ExpressionNode):
+ (LogicalNotNode):
+ (LogicalOpNode): Removed lots of code for handling expressions
+ that couldn't generate into a condition context because all expressions
+ can now.
+
+2013-03-28 Geoffrey Garen <ggaren@apple.com>
+
+ Simplified the bytecode by removing op_loop and op_loop_if_*
+ https://bugs.webkit.org/show_bug.cgi?id=113548
+
+ Reviewed by Filip Pizlo.
+
+ Regular jumps will suffice.
+
+ These opcodes are identical to branches, except they also do timeout
+ checking. That style of timeout checking has been broken for a long
+ time, and when we add back timeout checking, it won't use these opcodes.
+
+ * JavaScriptCore.order:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/PreciseJumpTargets.cpp:
+ (JSC::computePreciseJumpTargets):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitJump):
+ (JSC::BytecodeGenerator::emitJumpIfTrue):
+ (JSC::BytecodeGenerator::emitJumpIfFalse):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ (JSC):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2013-03-28 Geoffrey Garen <ggaren@apple.com>
+
+ Simplified the bytecode by removing op_jmp_scopes
+ https://bugs.webkit.org/show_bug.cgi?id=113545
+
+ Reviewed by Filip Pizlo.
+
+ We already have op_pop_scope and op_jmp, so we don't need op_jmp_scopes.
+ Using op_jmp_scopes was also adding a "jump to self" to codegen for
+ return statements, which was pretty silly.
+
+ * JavaScriptCore.order:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/Opcode.h:
+ (JSC::padOpcodeName):
+ * bytecode/PreciseJumpTargets.cpp:
+ (JSC::computePreciseJumpTargets):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitComplexPopScopes):
+ (JSC::BytecodeGenerator::emitPopScopes):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ * jit/JITOpcodes32_64.cpp:
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ * llint/LLIntSlowPaths.h:
+ * llint/LowLevelInterpreter.asm:
+
+2013-03-28 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Safari hangs during test262 run in CodeCache::pruneSlowCase
+ https://bugs.webkit.org/show_bug.cgi?id=113469
+
+ Reviewed by Geoffrey Garen.
+
+ We can end up hanging for quite some time if we add a lot of small keys to the CodeCache.
+ By the time we get around to pruning the cache, we have a potentially tens or hundreds of
+ thousands of small entries, which can cause a noticeable hang when pruning them.
+
+ To fix this issue we added a hard cap to the number of entries in the cache because we
+ could potentially have to remove every element in the map.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCacheMap::pruneSlowCase): We need to prune until we're both under the hard cap and the
+ capacity in bytes.
+ * runtime/CodeCache.h:
+ (CodeCacheMap):
+ (JSC::CodeCacheMap::numberOfEntries): Convenience accessor function to the number of entries in
+ the map that does the cast to size_t of m_map.size() for us.
+ (JSC::CodeCacheMap::canPruneQuickly): Checks that the total number is under the hard cap. We put this
+ check inside a function to more accurately describe why we're doing the check and to abstract out
+ the actual calculation in case we want to coalesce calls to pruneSlowCase in the future.
+ (JSC::CodeCacheMap::prune): Check the number of entries against our hard cap. If it's greater than
+ the cap then we need to drop down to pruneSlowCase.
+
+2013-03-28 Zan Dobersek <zdobersek@igalia.com>
+
+ Unreviewed build fix for the EFL and GTK ports.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCacheMap::pruneSlowCase): Pass a 0 casted to the int64_t type instead of 0LL
+ to the std::max call so the arguments' types match.
+
+2013-03-27 Geoffrey Garen <ggaren@apple.com>
+
+ Unreviewed build fix: Removed a dead field.
+
+ Pointed out by Mark Lam.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::ByteCodeParser):
+ (ByteCodeParser):
+
+2013-03-27 Geoffrey Garen <ggaren@apple.com>
+
+ Unreviewed build fix: Removed a dead field.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::ByteCodeParser):
+ (ByteCodeParser):
+
+2013-03-27 Geoffrey Garen <ggaren@apple.com>
+
+ Removed some dead code in the DFG bytecode parser
+ https://bugs.webkit.org/show_bug.cgi?id=113472
+
+ Reviewed by Sam Weinig.
+
+ Now that Phi creation and liveness analysis are separate passes, we can
+ remove the vestiges of code that used to do that in the bytecode
+ parser.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (JSC::DFG::ByteCodeParser::parse):
+
+2013-03-27 Filip Pizlo <fpizlo@apple.com>
+
+ JIT and DFG should NaN-check loads from Float32 arrays
+ https://bugs.webkit.org/show_bug.cgi?id=113462
+ <rdar://problem/13490804>
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitFloatTypedArrayGetByVal):
+
+2013-03-27 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ CodeCache::m_capacity can becoming negative, producing undefined results in pruneSlowCase
+ https://bugs.webkit.org/show_bug.cgi?id=113453
+
+ Reviewed by Geoffrey Garen.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCacheMap::pruneSlowCase): We make sure that m_minCapacity doesn't drop below zero now.
+ This prevents m_capacity from doing the same.
+
+2013-03-27 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should use CheckStructure for typed array checks whenever possible
+ https://bugs.webkit.org/show_bug.cgi?id=113374
+
+ Reviewed by Geoffrey Garen.
+
+ We used to do the right thing, but it appears that this regressed at some point. Since the
+ FixupPhase now has the ability to outright remove spurious CheckStructures on array
+ operations, it is profitable for the ByteCodeParser to insert CheckStructures whenver there
+ is a chance that it might be profitable, and when the profiling tells us what structure to
+ check.
+
+ Also added some code for doing ArrayProfile debugging.
+
+ This is a slightly speed-up. Maybe 3% on Mandreel.
+
+ * bytecode/ArrayProfile.cpp:
+ (JSC::ArrayProfile::computeUpdatedPrediction):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::benefitsFromStructureCheck):
+
+2013-03-27 Zeno Albisser <zeno@webkit.org>
+
+ [Qt] Remove Qt specific WorkQueueItem definitions.
+ https://bugs.webkit.org/show_bug.cgi?id=112891
+
+ This patch is preparation work for removing
+ WorkQueue related code from TestRunnerQt and
+ replacing it with generic TestRunner code.
+
+ Reviewed by Benjamin Poulain.
+
+ * API/JSStringRefQt.cpp:
+ (JSStringCreateWithQString):
+ Adding a convenience function to create a
+ JSStringRef from a QString.
+ * API/JSStringRefQt.h:
+
+2013-03-26 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION: Sometimes, operations on proven strings ignore changes to the string prototype
+ https://bugs.webkit.org/show_bug.cgi?id=113353
+ <rdar://problem/13510778>
+
+ Reviewed by Mark Hahnenberg and Geoffrey Garen.
+
+ ToString should call speculateStringObject() even if you know that it's a string object, since
+ it calls it to also get the watchpoint. Note that even with this change, if you do
+ Phantom(Check:StringObject:@a), it might get eliminated just because we proved that @a is a
+ string object (thereby eliminating the prototype watchpoint); that's fine since ToString is
+ MustGenerate and never decays to Phantom.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+ (JSC::DFG::SpeculativeJIT::speculateStringObject):
+ (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+
+2013-03-26 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ REGRESSION(r144131): It made fast/js/regress/string-repeat-arith.html assert on 32 bit
+ https://bugs.webkit.org/show_bug.cgi?id=112106
+
+ Rubber stamped by Filip Pizlo.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32): Get rid of the case for constants because
+ we would have done constant folding anyways on a ValueToInt32.
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): Fixed a random compile error with this flag enabled.
+
+2013-03-26 Filip Pizlo <fpizlo@apple.com>
+
+ JSC_enableProfiler=true should also cause JSGlobalData to save the profiler output somewhere
+ https://bugs.webkit.org/show_bug.cgi?id=113144
+
+ Reviewed by Geoffrey Garen.
+
+ Forgot to include Geoff's requested change in the original commit.
+
+ * profiler/ProfilerDatabase.cpp:
+ (Profiler):
+
+2013-03-25 Filip Pizlo <fpizlo@apple.com>
+
+ JSC_enableProfiler=true should also cause JSGlobalData to save the profiler output somewhere
+ https://bugs.webkit.org/show_bug.cgi?id=113144
+
+ Reviewed by Geoffrey Garen.
+
+ Added the ability to save profiler output with JSC_enableProfiler=true. It will save it
+ to the current directory, or JSC_PROFILER_PATH if the latter was specified.
+
+ This works by saving the Profiler::Database either when it is destroyed or atexit(),
+ whichever happens first.
+
+ This allows use of the profiler from any WebKit client.
+
+ * jsc.cpp:
+ (jscmain):
+ * profiler/ProfilerDatabase.cpp:
+ (Profiler):
+ (JSC::Profiler::Database::Database):
+ (JSC::Profiler::Database::~Database):
+ (JSC::Profiler::Database::registerToSaveAtExit):
+ (JSC::Profiler::Database::addDatabaseToAtExit):
+ (JSC::Profiler::Database::removeDatabaseFromAtExit):
+ (JSC::Profiler::Database::performAtExitSave):
+ (JSC::Profiler::Database::removeFirstAtExitDatabase):
+ (JSC::Profiler::Database::atExitCallback):
+ * profiler/ProfilerDatabase.h:
+ (JSC::Profiler::Database::databaseID):
+ (Database):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+2013-03-25 Filip Pizlo <fpizlo@apple.com>
+
+ ArrayMode should not consider SpecOther when refining the base
+ https://bugs.webkit.org/show_bug.cgi?id=113271
+
+ Reviewed by Geoffrey Garen.
+
+ 9% speed-up on Octane/pdfjs.
+
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::refine):
+
+2013-03-26 Csaba Osztrogonác <ossy@webkit.org>
+
+ Fix unused parameter warnings in JITInlines.h
+ https://bugs.webkit.org/show_bug.cgi?id=112560
+
+ Reviewed by Zoltan Herczeg.
+
+ * jit/JITInlines.h:
+ (JSC::JIT::beginUninterruptedSequence):
+ (JSC::JIT::endUninterruptedSequence):
+ (JSC):
+
+2013-03-25 Kent Tamura <tkent@chromium.org>
+
+ Rename ENABLE_INPUT_TYPE_DATETIME
+ https://bugs.webkit.org/show_bug.cgi?id=113254
+
+ Reviewed by Kentaro Hara.
+
+ Rename ENABLE_INPUT_TYPE_DATETIME to ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE.
+ Actually I'd like to remove the code, but we shouldn't remove it yet
+ because we shipped products with it on some platforms.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-03-25 Mark Lam <mark.lam@apple.com>
+
+ Offlineasm cloop backend compiles op+branch incorrectly.
+ https://bugs.webkit.org/show_bug.cgi?id=113146.
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGRepatch.h:
+ (JSC::DFG::dfgResetGetByID):
+ (JSC::DFG::dfgResetPutByID):
+ - These functions never return when the DFG is dsiabled, not just when
+ asserts are enabled. Changing the attribute from NO_RETURN_DUE_TO_ASSERT
+ to NO_RETURN.
+ * llint/LLIntOfflineAsmConfig.h:
+ - Added some #defines needed to get the cloop building again.
+ * offlineasm/cloop.rb:
+ - Fix cloopEmitOpAndBranchIfOverflow() and cloopEmitOpAndBranch() to
+ emit code that unconditionally executes the specified operation before
+ doing the conditional branch.
+
+2013-03-25 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ JSObject::enterDictionaryIndexingMode doesn't have a case for ALL_BLANK_INDEXING_TYPES
+ https://bugs.webkit.org/show_bug.cgi?id=113236
+
+ Reviewed by Geoffrey Garen.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::enterDictionaryIndexingMode): We forgot blank indexing types.
+
+2013-03-23 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ HandleSet should use HeapBlocks for storing handles
+ https://bugs.webkit.org/show_bug.cgi?id=113145
+
+ Reviewed by Geoffrey Garen.
+
+ * GNUmakefile.list.am: Build project changes.
+ * JavaScriptCore.gypi: Ditto.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Ditto.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * heap/BlockAllocator.cpp: Rename the RegionSet to m_fourKBBlockRegionSet because there are
+ too many block types to include them all in the name now.
+ (JSC::BlockAllocator::BlockAllocator):
+ * heap/BlockAllocator.h:
+ (BlockAllocator): Add the appropriate override for regionSetFor.
+ (JSC::WeakBlock):
+ (JSC::MarkStackSegment):
+ (JSC::HandleBlock):
+ * heap/HandleBlock.h: Added.
+ (HandleBlock): New class for HandleBlocks.
+ (JSC::HandleBlock::blockFor): Static method to get the block of the given HandleNode pointer. Allows
+ us to quickly figure out which HandleSet the HandleNode belongs to without storing the pointer to it
+ in the HandleNode.
+ (JSC::HandleBlock::handleSet): Getter.
+ * heap/HandleBlockInlines.h: Added.
+ (JSC::HandleBlock::create):
+ (JSC::HandleBlock::HandleBlock):
+ (JSC::HandleBlock::payloadEnd):
+ (JSC::HandleBlock::payload):
+ (JSC::HandleBlock::nodes):
+ (JSC::HandleBlock::nodeAtIndex):
+ (JSC::HandleBlock::nodeCapacity):
+ * heap/HandleSet.cpp:
+ (JSC::HandleSet::~HandleSet):
+ (JSC::HandleSet::grow):
+ * heap/HandleSet.h:
+ (HandleNode): Move the internal Node class from HandleSet to be its own public class so it can be
+ used by HandleBlock.
+ (HandleSet): Add a typedef so that Node refers to the new HandleNode class.
+ (JSC::HandleSet::toHandle):
+ (JSC::HandleSet::toNode):
+ (JSC::HandleSet::allocate):
+ (JSC::HandleSet::deallocate):
+ (JSC::HandleNode::HandleNode):
+ (JSC::HandleNode::slot):
+ (JSC::HandleNode::handleSet): Use the new blockFor static function to get the right HandleBlock and lookup
+ the HandleSet.
+ (JSC::HandleNode::setPrev):
+ (JSC::HandleNode::prev):
+ (JSC::HandleNode::setNext):
+ (JSC::HandleNode::next):
+ (JSC::HandleSet::forEachStrongHandle):
+ * heap/Heap.h: Friend HandleSet so that it can access the BlockAllocator when allocating HandleBlocks.
+
+2013-03-22 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX (r145119): Make JSValue* properties default to (assign)
+ <rdar://problem/13380794>
+
+ Reviewed by Mark Hahnenberg.
+
+ Fixes the following build failures:
+
+ Source/JavaScriptCore/API/tests/testapi.mm:106:1: error: no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed [-Werror,-Wobjc-property-no-attribute]
+ @property JSValue *onclick;
+ ^
+ Source/JavaScriptCore/API/tests/testapi.mm:106:1: error: default property attrib ute 'assign' not appropriate for non-GC object [-Werror,-Wobjc-property-no-attribute]
+ Source/JavaScriptCore/API/tests/testapi.mm:107:1: error: no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed [-Werror,-Wobjc-property-no-attribute]
+ @property JSValue *weakOnclick;
+ ^
+ Source/JavaScriptCore/API/tests/testapi.mm:107:1: error: default property attribute 'assign' not appropriate for non-GC object [-Werror,-Wobjc-property-no-attribute]
+ 4 errors generated.
+
+ * API/tests/testapi.mm: Default to (assign) for JSValue*
+ properties.
+
+2013-03-22 Ryosuke Niwa <rniwa@webkit.org>
+
+ testLeakingPrototypesAcrossContexts added in r146682 doesn't compile on Win and fails on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=113125
+
+ Reviewed by Mark Hahnenberg
+
+ Remove the test added in r146682 as it's now failing on Mac.
+ This is the test that was causing a compilation failure on Windows.
+
+ * API/tests/testapi.c:
+ (main):
+
+2013-03-22 Ryosuke Niwa <rniwa@webkit.org>
+
+ Fix the typo: WIN -> WINDOWS.
+
+ * API/tests/testapi.c:
+ (main):
+
+2013-03-22 Ryosuke Niwa <rniwa@webkit.org>
+
+ I really can't figure out what's wrong with this one.
+ Temporarily disable the test added by r146682 on Windows since it doesn't compile.
+
+ * API/tests/testapi.c:
+ (main):
+
+2013-03-22 Ryosuke Niwa <rniwa@webkit.org>
+
+ Another build fix (after r146693) for r146682.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-03-22 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. AppleWin build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd:
+ * JavaScriptCore.vcxproj/copy-files.cmd:
+
+2013-03-22 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ -[TinyDOMNode dealloc] should call [super dealloc] when ARC is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=113054
+
+ Reviewed by Geoffrey Garen.
+
+ * API/tests/testapi.mm:
+ (-[TinyDOMNode dealloc]):
+
+2013-03-22 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ opaqueJSClassData should be cached on JSGlobalObject, not the JSGlobalData
+ https://bugs.webkit.org/show_bug.cgi?id=113086
+
+ Reviewed by Geoffrey Garen.
+
+ opaqueJSClassData stores cached prototypes for JSClassRefs in the C API. It doesn't make sense to
+ share these prototypes within a JSGlobalData across JSGlobalObjects, and in fact doing so will cause
+ a leak of the original JSGlobalObject that these prototypes were created in. Therefore we should move
+ this cache to JSGlobalObject where it belongs and where it won't cause memory leaks.
+
+ * API/JSBase.cpp: Needed to add an extern "C" so that testapi.c can use the super secret GC function.
+ * API/JSClassRef.cpp: We now grab the cached context data from the global object rather than the global data.
+ (OpaqueJSClass::contextData):
+ * API/JSClassRef.h: Remove this header because it's unnecessary and causes circular dependencies.
+ * API/tests/testapi.c: Added a new test that makes sure that using the same JSClassRef in two different contexts
+ doesn't cause leaks of the original global object.
+ (leakFinalize):
+ (nestedAllocateObject): This is a hack to bypass the conservative scan of the GC, which was unnecessarily marking
+ objects and keeping them alive, ruining the test result.
+ (testLeakingPrototypesAcrossContexts):
+ (main):
+ * API/tests/testapi.mm: extern "C" this so we can continue using it here.
+ * runtime/JSGlobalData.cpp: Remove JSClassRef related stuff.
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSGlobalObject.h: Add the stuff that JSGlobalData had. We add it to JSGlobalObjectRareData so that
+ clients who don't use the C API don't have to pay the memory cost of this extra HashMap.
+ (JSGlobalObject):
+ (JSGlobalObjectRareData):
+ (JSC::JSGlobalObject::opaqueJSClassData):
+
+2013-03-19 Martin Robinson <mrobinson@igalia.com>
+
+ [GTK] Add support for building the WebCore bindings to the gyp build
+ https://bugs.webkit.org/show_bug.cgi?id=112638
+
+ Reviewed by Nico Weber.
+
+ * JavaScriptCore.gyp/JavaScriptCoreGTK.gyp: Export all include directories to direct
+ dependents and fix the indentation of the libjavascriptcore target.
+
+2013-03-21 Filip Pizlo <fpizlo@apple.com>
+
+ Fix some minor issues in the DFG's profiling of heap accesses
+ https://bugs.webkit.org/show_bug.cgi?id=113010
+
+ Reviewed by Goeffrey Garen.
+
+ 1) If a CodeBlock gets jettisoned by GC, we should count the exit sites.
+
+ 2) If a CodeBlock clears a structure stub during GC, it should record this, and
+ the DFG should prefer to not inline that access (i.e. treat it as if it had an
+ exit site).
+
+ 3) If a PutById was seen by the baseline JIT, and the JIT attempted to cache it,
+ but it chose not to, then assume that it will take slow path.
+
+ 4) If we frequently exited because of a structure check on a weak constant,
+ don't try to inline that access in the future.
+
+ 5) Treat all exits that were counted as being frequent.
+
+ 81% speed-up on Octane/gbemu. Small speed-ups elsewhere, and no regressions.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC):
+ (JSC::CodeBlock::resetStubDuringGCInternal):
+ (JSC::CodeBlock::reoptimize):
+ (JSC::CodeBlock::jettison):
+ (JSC::ProgramCodeBlock::jettisonImpl):
+ (JSC::EvalCodeBlock::jettisonImpl):
+ (JSC::FunctionCodeBlock::jettisonImpl):
+ (JSC::CodeBlock::tallyFrequentExitSites):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::tallyFrequentExitSites):
+ (ProgramCodeBlock):
+ (EvalCodeBlock):
+ (FunctionCodeBlock):
+ * bytecode/GetByIdStatus.cpp:
+ (JSC::GetByIdStatus::computeFor):
+ * bytecode/PutByIdStatus.cpp:
+ (JSC::PutByIdStatus::computeFor):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::StructureStubInfo):
+ (StructureStubInfo):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
+ * dfg/DFGOSRExit.h:
+ (JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
+ (OSRExit):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Options.h:
+ (JSC):
+
+2013-03-22 Filip Pizlo <fpizlo@apple.com>
+
+ DFG folding of PutById to SimpleReplace should consider the specialized function case
+ https://bugs.webkit.org/show_bug.cgi?id=113093
+
+ Reviewed by Geoffrey Garen and Mark Hahnenberg.
+
+ * bytecode/PutByIdStatus.cpp:
+ (JSC::PutByIdStatus::computeFor):
+
+2013-03-22 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX (r146558): Build testapi.mm with ARC enabled for armv7s
+ <http://webkit.org/b/112608>
+
+ Fixes the following build failure:
+
+ Source/JavaScriptCore/API/tests/testapi.mm:205:1: error: method possibly missing a [super dealloc] call [-Werror,-Wobjc-missing-super-calls]
+ }
+ ^
+ 1 error generated.
+
+ * Configurations/ToolExecutable.xcconfig: Enable ARC for armv7s
+ architecture.
+
+2013-03-22 David Kilzer <ddkilzer@apple.com>
+
+ Revert "BUILD FIX (r146558): Call [super dealloc] from -[TinyDOMNode dealloc]"
+
+ This fixes a build failure introduced by this change:
+
+ Source/JavaScriptCore/API/tests/testapi.mm:206:6: error: ARC forbids explicit message send of 'dealloc'
+ [super dealloc];
+ ^ ~~~~~~~
+ 1 error generated.
+
+ Not sure why this didn't fail locally on my Mac Pro.
+
+ * API/tests/testapi.mm:
+ (-[TinyDOMNode dealloc]): Remove call to [super dealloc].
+
+2013-03-22 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX (r146558): Call [super dealloc] from -[TinyDOMNode dealloc]
+ <http://webkit.org/b/112608>
+
+ Fixes the following build failure:
+
+ Source/JavaScriptCore/API/tests/testapi.mm:205:1: error: method possibly missing a [super dealloc] call [-Werror,-Wobjc-missing-super-calls]
+ }
+ ^
+ 1 error generated.
+
+ * API/tests/testapi.mm:
+ (-[TinyDOMNode dealloc]): Call [super dealloc].
+
+2013-03-22 Ryosuke Niwa <rniwa@webkit.org>
+
+ Leak bots erroneously report JSC::WatchpointSet as leaking
+ https://bugs.webkit.org/show_bug.cgi?id=107781
+
+ Reviewed by Filip Pizlo.
+
+ Since leaks doesn't support tagged pointers, avoid using it by flipping the bit flag to indicate
+ the entry is "fat". We set the flag when the entry is NOT fat; i.e. slim.
+
+ Replaced FatFlag by SlimFlag and initialized m_bits with this flag to indicate that the entry is
+ initially "slim".
+
+ * runtime/SymbolTable.cpp:
+ (JSC::SymbolTableEntry::copySlow): Don't set FatFlag since it has been replaced by SlimFlag.
+ (JSC::SymbolTableEntry::inflateSlow): Ditto.
+
+ * runtime/SymbolTable.h:
+ (JSC::SymbolTableEntry::Fast::Fast): Set SlimFlag by default.
+ (JSC::SymbolTableEntry::Fast::isNull): Ignore SlimFlag.
+ (JSC::SymbolTableEntry::Fast::isFat): An entry is fat when m_bits is not entirely zero and SlimFlag
+ is not set.
+
+ (JSC::SymbolTableEntry::SymbolTableEntry): Set SlimFlag by default.
+ (JSC::SymbolTableEntry::SymbolTableEntry::getFast): Set SlimFlag when creating Fast from a fat entry.
+ (JSC::SymbolTableEntry::isNull): Ignore SlimFlag.
+ (JSC::SymbolTableEntry::FatEntry::FatEntry): Strip SlimFlag.
+ (JSC::SymbolTableEntry::isFat): An entry is fat when m_bits is not entirely zero and SlimFlag is unset.
+ (JSC::SymbolTableEntry::fatEntry): Don't strip FatFlag as this flag doesn't exist anymore.
+ (JSC::SymbolTableEntry::pack): Preserve SlimFlag.
+
+ (JSC::SymbolTableIndexHashTraits): empty value is no longer zero so don't set emptyValueIsZero true.
+
+2013-03-21 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Need a good way to preserve custom properties on JS wrappers
+ https://bugs.webkit.org/show_bug.cgi?id=112608
+
+ Reviewed by Geoffrey Garen.
+
+ Currently, we just use a weak map, which means that garbage collection can cause a wrapper to
+ disappear if it isn't directly exported to JavaScript.
+
+ The most straightforward and safe way (with respect to garbage collection and concurrency) is to have
+ clients add and remove their external references along with their owners. Effectively, the client is
+ recording the structure of the external object graph so that the garbage collector can make sure to
+ mark any wrappers that are reachable through either the JS object graph of the external Obj-C object
+ graph. By keeping these wrappers alive, this has the effect that custom properties on these wrappers
+ will also remain alive.
+
+ The rule for if an object needs to be tracked by the runtime (and therefore whether the client should report it) is as follows:
+ For a particular object, its references to its children should be added if:
+ 1. The child is referenced from JavaScript.
+ 2. The child contains references to other objects for which (1) or (2) are true.
+
+ * API/JSAPIWrapperObject.mm:
+ (JSAPIWrapperObjectHandleOwner::finalize):
+ (JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots): A wrapper object is kept alive only if its JSGlobalObject
+ is marked and its corresponding Objective-C object was added to the set of opaque roots.
+ (JSC::JSAPIWrapperObject::visitChildren): We now call out to scanExternalObjectGraph, which handles adding all Objective-C
+ objects to the set of opaque roots.
+ * API/JSAPIWrapperObject.h:
+ (JSAPIWrapperObject):
+ * API/JSContext.mm: Moved dealloc to its proper place in the main implementation.
+ (-[JSContext dealloc]):
+ * API/JSVirtualMachine.h:
+ * API/JSVirtualMachine.mm:
+ (-[JSVirtualMachine initWithContextGroupRef:]):
+ (-[JSVirtualMachine dealloc]):
+ (getInternalObjcObject): Helper funciton to get the Objective-C object out of JSManagedValues or JSValues if there is one.
+ (-[JSVirtualMachine addManagedReference:withOwner:]): Adds the Objective-C object to the set of objects
+ owned by the owner object in that particular virtual machine.
+ (-[JSVirtualMachine removeManagedReference:withOwner:]): Removes the relationship between the two objects.
+ (-[JSVirtualMachine externalObjectGraph]):
+ (scanExternalObjectGraph): Does a depth-first search of the external object graph in a particular virtual machine starting at
+ the specified root. Each new object it encounters it adds to the set of opaque roots. These opaque roots will keep their
+ corresponding wrapper objects alive if they have them.
+ * API/JSManagedReferenceInternal.h: Added.
+ * API/JSVirtualMachine.mm: Added the per-JSVirtualMachine map between objects and the objects they own, which is more formally
+ known as that virtual machine's external object graph.
+ * API/JSWrapperMap.mm:
+ (-[JSWrapperMap dealloc]): We were leaking this before :-(
+ (-[JSVirtualMachine initWithContextGroupRef:]):
+ (-[JSVirtualMachine dealloc]):
+ (-[JSVirtualMachine externalObjectGraph]):
+ * API/JSVirtualMachineInternal.h:
+ * API/tests/testapi.mm: Added two new tests using the TinyDOMNode class. The first tests that a custom property added to a wrapper
+ doesn't vanish after GC, even though that wrapper isn't directly accessible to the JS garbage collector but is accessible through
+ the external Objective-C object graph. The second test makes sure that adding an object to the external object graph with the same
+ owner doesn't cause any sort of problems.
+ (+[TinyDOMNode sharedVirtualMachine]):
+ (-[TinyDOMNode init]):
+ (-[TinyDOMNode dealloc]):
+ (-[TinyDOMNode appendChild:]):
+ (-[TinyDOMNode numberOfChildren]):
+ (-[TinyDOMNode childAtIndex:]):
+ (-[TinyDOMNode removeChildAtIndex:]):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * heap/SlotVisitor.h:
+ (SlotVisitor):
+ * heap/SlotVisitorInlines.h:
+ (JSC::SlotVisitor::containsOpaqueRootTriState): Added a new method to SlotVisitor to allow scanExternalObjectGraph to have a
+ thread-safe view of opaque roots during parallel marking. The set of opaque roots available to any one SlotVisitor isn't guaranteed
+ to be 100% correct, but that just results in a small duplication of work in scanExternalObjectGraph. To indicate this change for
+ false negatives we return a TriState that's either true or mixed, but never false.
+
+2013-03-21 Mark Lam <mark.lam@apple.com>
+
+ Fix O(n^2) op_debug bytecode charPosition to column computation.
+ https://bugs.webkit.org/show_bug.cgi?id=112957.
+
+ Reviewed by Geoffrey Garen.
+
+ The previous algorithm does a linear reverse scan of the source string
+ to find the line start for any given char position. This results in a
+ O(n^2) algortithm when the source string has no line breaks.
+
+ The new algorithm computes a line start column table for a
+ SourceProvider on first use. This line start table is used to fix up
+ op_debug's charPosition operand into a column operand when an
+ UnlinkedCodeBlock is linked into a CodeBlock. The initialization of
+ the line start table is O(n), and the CodeBlock column fix up is
+ O(log(n)).
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock): - do column fix up.
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::debug): - no need to do column fixup anymore.
+ * interpreter/Interpreter.h:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * parser/SourceProvider.cpp:
+ (JSC::SourceProvider::lineStarts):
+ (JSC::charPositionExtractor):
+ (JSC::SourceProvider::charPositionToColumnNumber):
+ - initialize line start column table if needed.
+ - look up line start for the given char position.
+ * parser/SourceProvider.h:
+
+2013-03-21 Filip Pizlo <fpizlo@apple.com>
+
+ JSC profiler should have an at-a-glance report of the success of DFG optimization
+ https://bugs.webkit.org/show_bug.cgi?id=112988
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * profiler/ProfilerCompilation.cpp:
+ (JSC::Profiler::Compilation::Compilation):
+ (JSC::Profiler::Compilation::toJS):
+ * profiler/ProfilerCompilation.h:
+ (JSC::Profiler::Compilation::noticeInlinedGetById):
+ (JSC::Profiler::Compilation::noticeInlinedPutById):
+ (JSC::Profiler::Compilation::noticeInlinedCall):
+ (Compilation):
+ * runtime/CommonIdentifiers.h:
+
+2013-03-21 Mark Lam <mark.lam@apple.com>
+
+ Fix lexer charPosition computation when "rewind"ing the lexer.
+ https://bugs.webkit.org/show_bug.cgi?id=112952.
+
+ Reviewed by Michael Saboff.
+
+ Changed the Lexer to no longer keep a m_charPosition. Instead, we compute
+ currentCharPosition() from m_code and m_codeStartPlusOffset, where
+ m_codeStartPlusOffset is the SourceProvider m_codeStart + the SourceCode
+ start offset. This ensures that the charPosition is always in sync with
+ m_code.
+
+ * parser/Lexer.cpp:
+ (JSC::::setCode):
+ (JSC::::internalShift):
+ (JSC::::shift):
+ (JSC::::lex):
+ * parser/Lexer.h:
+ (JSC::Lexer::currentCharPosition):
+ (JSC::::lexExpectIdentifier):
+
+2013-03-21 Alberto Garcia <agarcia@igalia.com>
+
+ [BlackBerry] GCActivityCallback: replace JSLock with JSLockHolder
+ https://bugs.webkit.org/show_bug.cgi?id=112448
+
+ Reviewed by Xan Lopez.
+
+ This changed in r121381.
+
+ * runtime/GCActivityCallbackBlackBerry.cpp:
+ (JSC::DefaultGCActivityCallback::doWork):
+
+2013-03-21 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: wrapperClass holds a static JSClassRef, which causes JSGlobalObjects to leak
+ https://bugs.webkit.org/show_bug.cgi?id=112856
+
+ Reviewed by Geoffrey Garen.
+
+ Through a very convoluted path that involves the caching of prototypes on the JSClassRef, we can leak
+ JSGlobalObjects when inserting an Objective-C object into multiple independent JSContexts.
+
+ * API/JSAPIWrapperObject.cpp: Removed.
+ * API/JSAPIWrapperObject.h:
+ (JSAPIWrapperObject):
+ * API/JSAPIWrapperObject.mm: Copied from Source/JavaScriptCore/API/JSAPIWrapperObject.cpp. Made this an
+ Objective-C++ file so that we can call release on the wrappedObject. Also added a WeakHandleOwner for
+ JSAPIWrapperObjects. This will also be used in a future patch for https://bugs.webkit.org/show_bug.cgi?id=112608.
+ (JSAPIWrapperObjectHandleOwner):
+ (jsAPIWrapperObjectHandleOwner):
+ (JSAPIWrapperObjectHandleOwner::finalize): This finalize replaces the old finalize that was done through
+ the C API.
+ (JSC::JSAPIWrapperObject::finishCreation): Allocate the WeakImpl. Balanced in finalize.
+ (JSC::JSAPIWrapperObject::setWrappedObject): We now do the retain of the wrappedObject here rather than in random
+ places scattered around JSWrapperMap.mm
+ * API/JSObjectRef.cpp: Added some ifdefs for platforms that don't support the Obj-C API.
+ (JSObjectGetPrivate): Ditto.
+ (JSObjectSetPrivate): Ditto.
+ (JSObjectGetPrivateProperty): Ditto.
+ (JSObjectSetPrivateProperty): Ditto.
+ (JSObjectDeletePrivateProperty): Ditto.
+ * API/JSValueRef.cpp: Ditto.
+ (JSValueIsObjectOfClass): Ditto.
+ * API/JSWrapperMap.mm: Remove wrapperClass().
+ (objectWithCustomBrand): Change to no longer use a parent class, which was only used to give the ability to
+ finalize wrapper objects.
+ (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]): Change to no longer use wrapperClass().
+ (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]): Ditto.
+ (tryUnwrapObjcObject): We now check if the object inherits from JSAPIWrapperObject.
+ * API/tests/testapi.mm: Added a test that exports an Objective-C object to two different JSContexts and makes
+ sure that the first one is collected properly by using a weak JSManagedValue for the wrapper in the first JSContext.
+ * CMakeLists.txt: Build file modifications.
+ * GNUmakefile.list.am: Ditto.
+ * JavaScriptCore.gypi: Ditto.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Ditto.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * runtime/JSGlobalObject.cpp: More ifdefs for unsupported platforms.
+ (JSC::JSGlobalObject::reset): Ditto.
+ (JSC::JSGlobalObject::visitChildren): Ditto.
+ * runtime/JSGlobalObject.h: Ditto.
+ (JSGlobalObject): Ditto.
+ (JSC::JSGlobalObject::objcCallbackFunctionStructure): Ditto.
+
+2013-03-21 Anton Muhin <antonm@chromium.org>
+
+ Unreviewed, rolling out r146483.
+ http://trac.webkit.org/changeset/146483
+ https://bugs.webkit.org/show_bug.cgi?id=111695
+
+ Breaks debug builds.
+
+ * bytecode/GlobalResolveInfo.h: Removed property svn:mergeinfo.
+
+2013-03-21 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ Implement LLInt for CPU(ARM_TRADITIONAL)
+ https://bugs.webkit.org/show_bug.cgi?id=97589
+
+ Reviewed by Zoltan Herczeg.
+
+ Enable LLInt for ARMv5 and ARMv7 traditional as well.
+
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * offlineasm/arm.rb:
+ * offlineasm/backends.rb:
+ * offlineasm/instructions.rb:
+
+2013-03-20 Cosmin Truta <ctruta@blackberry.com>
+
+ [QNX][ARM] REGRESSION(r135330): Various failures in Octane
+ https://bugs.webkit.org/show_bug.cgi?id=112863
+
+ Reviewed by Yong Li.
+
+ This was fixed in http://trac.webkit.org/changeset/146396 on Linux only.
+ Enable this fix on QNX.
+
+ * assembler/ARMv7Assembler.h:
+ (ARMv7Assembler):
+ (JSC::ARMv7Assembler::replaceWithJump):
+ (JSC::ARMv7Assembler::maxJumpReplacementSize):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::revertJumpReplacementToBranchPtrWithPatch):
+
+2013-03-20 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of JSString.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/JSString.h:
+
+2013-03-20 Filip Pizlo <fpizlo@apple.com>
+
+ "" + x where x is not a string should be optimized by the DFG to some manner of ToString conversion
+ https://bugs.webkit.org/show_bug.cgi?id=112845
+
+ Reviewed by Mark Hahnenberg.
+
+ I like to do "" + x. So I decided to make DFG recognize it, and related idioms.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixupToPrimitive):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::fixupToString):
+ (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::resultOfToPrimitive):
+ (DFG):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGPredictionPropagationPhase.h:
+ (DFG):
+
+2013-03-20 Zoltan Herczeg <zherczeg@webkit.org>
+
+ ARMv7 replaceWithJump ASSERT failure after r135330.
+ https://bugs.webkit.org/show_bug.cgi?id=103146
+
+ Reviewed by Filip Pizlo.
+
+ On Linux, the 24 bit distance range of jumps sometimes does not
+ enough to cover all targets addresses. This patch supports jumps
+ outside of this range using a mov/movt/bx 10 byte long sequence.
+
+ * assembler/ARMv7Assembler.h:
+ (ARMv7Assembler):
+ (JSC::ARMv7Assembler::revertJumpTo_movT3movtcmpT2):
+ (JSC::ARMv7Assembler::nopw):
+ (JSC::ARMv7Assembler::label):
+ (JSC::ARMv7Assembler::replaceWithJump):
+ (JSC::ARMv7Assembler::maxJumpReplacementSize):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::revertJumpReplacementToBranchPtrWithPatch):
+
+2013-03-20 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Fix over-releasing in allocateConstructorAndPrototypeWithSuperClassInfo:
+ https://bugs.webkit.org/show_bug.cgi?id=112832
+
+ Reviewed by Geoffrey Garen.
+
+ If either the m_constructor or m_prototype (but not both) is collected, we will call
+ allocateConstructorAndPrototypeWithSuperClassInfo, which will create a new object to replace the one
+ that was collected, but at the end of the method we call release on both of them.
+ This is incorrect since we autorelease the JSValue in the case that the object doesn't need to be
+ reallocated. Thus we'll end up overreleasing later during the drain of the autorelease pool.
+
+ * API/JSWrapperMap.mm:
+ (objectWithCustomBrand): We no longer alloc here. We instead call the JSValue valueWithValue class method,
+ which autoreleases for us.
+ (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]): We no longer call release on the
+ constructor or prototype JSValues.
+ * API/tests/testapi.mm: Added a new test that crashes on ToT due to over-releasing.
+
+2013-03-19 Filip Pizlo <fpizlo@apple.com>
+
+ It's called "Hash Consing" not "Hash Consting"
+ https://bugs.webkit.org/show_bug.cgi?id=112768
+
+ Rubber stamped by Mark Hahnenberg.
+
+ See http://en.wikipedia.org/wiki/Hash_consing
+
+ * heap/GCThreadSharedData.cpp:
+ (JSC::GCThreadSharedData::GCThreadSharedData):
+ (JSC::GCThreadSharedData::reset):
+ * heap/GCThreadSharedData.h:
+ (GCThreadSharedData):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::SlotVisitor):
+ (JSC::SlotVisitor::setup):
+ (JSC::SlotVisitor::reset):
+ (JSC::JSString::tryHashConsLock):
+ (JSC::JSString::releaseHashConsLock):
+ (JSC::JSString::shouldTryHashCons):
+ (JSC::SlotVisitor::internalAppend):
+ * heap/SlotVisitor.h:
+ (SlotVisitor):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ (JSC::JSGlobalData::haveEnoughNewStringsToHashCons):
+ (JSC::JSGlobalData::resetNewStringsSinceLastHashCons):
+ * runtime/JSString.h:
+ (JSC::JSString::finishCreation):
+ (JSString):
+ (JSC::JSString::isHashConsSingleton):
+ (JSC::JSString::clearHashConsSingleton):
+ (JSC::JSString::setHashConsSingleton):
+
+2013-03-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG implementation of op_strcat should inline rope allocations
+ https://bugs.webkit.org/show_bug.cgi?id=112780
+
+ Reviewed by Oliver Hunt.
+
+ This gets rid of the StrCat node and adds a MakeRope node. The MakeRope node can
+ take either two or three operands, and allocates a rope string with either two or
+ three fibers. (The magic choice of three children for non-VarArg nodes happens to
+ match exactly with the magic choice of three fibers for rope strings.)
+
+ ValueAdd on KnownString is replaced with MakeRope with two children.
+
+ StrCat gets replaced by an appropriate sequence of MakeRope's.
+
+ MakeRope does not do the dynamic check to see if its children are empty strings.
+ This is replaced by a static check, instead. The downside is that we may use more
+ memory if the strings passed to MakeRope turn out to dynamically be empty. The
+ upside is that we do fewer checks in the cases where either the strings are not
+ empty, or where the strings are statically known to be empty. I suspect both of
+ those cases are more common, than the case where the string is dynamically empty.
+
+ This also results in some badness for X86. MakeRope needs six registers if it is
+ allocating a three-rope. We don't have six registers to spare on X86. Currently,
+ the code side-steps this problem by just never usign three-ropes in optimized
+ code on X86. All other architectures, including X86_64, don't have this problem.
+
+ This is a shocking speed-up. 9% progressions on both V8/splay and
+ SunSpider/date-format-xparb. 1% progression on V8v7 overall, and ~0.5% progression
+ on SunSpider. 2x speed-up on microbenchmarks that test op_strcat.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGAdjacencyList.h:
+ (AdjacencyList):
+ (JSC::DFG::AdjacencyList::removeEdge):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
+ * dfg/DFGBackwardsPropagationPhase.cpp:
+ (JSC::DFG::BackwardsPropagationPhase::propagate):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGDCEPhase.cpp:
+ (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::createToString):
+ (JSC::DFG::FixupPhase::attemptToForceStringArrayModeByToStringConversion):
+ (JSC::DFG::FixupPhase::convertStringAddUse):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::convertToMakeRope):
+ (JSC::DFG::FixupPhase::fixupMakeRope):
+ (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileAdd):
+ (JSC::DFG::SpeculativeJIT::compileMakeRope):
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::~SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::gpr):
+ (JSC::DFG::SpeculateCellOperand::use):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/JSString.h:
+ (JSRopeString):
+
+2013-03-20 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Implement and32 on MIPS platform
+ https://bugs.webkit.org/show_bug.cgi?id=112665
+
+ Reviewed by Zoltan Herczeg.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::and32): Added missing method.
+ (MacroAssemblerMIPS):
+
+2013-03-20 Mark Lam <mark.lam@apple.com>
+
+ Fix incorrect debugger column number value.
+ https://bugs.webkit.org/show_bug.cgi?id=112741.
+
+ Reviewed by Oliver Hunt.
+
+ 1. In lexer, parser, and debugger code, renamed column to charPosition.
+ 2. Convert the charPosition to the equivalent column number before
+ passing it to the debugger.
+ 3. Changed ScopeNodes to take both a startLocation and an endLocation.
+ This allows FunctionBodyNodes, ProgramNodes, and EvalNodess to emit
+ correct debug hooks with correct starting line and column numbers.
+ 4. Fixed the Lexer to not reset the charPosition (previously
+ columnNumber) in Lexer::lex().
+
+ * JavaScriptCore.order:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitExpressionInfo):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ArrayNode::toArgumentList):
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::debug):
+ - convert charPosition to column for the debugger.
+ * interpreter/Interpreter.h:
+ * jit/JITStubs.cpp:
+ (DEFINE_STUB_FUNCTION(void, op_debug)):
+ * llint/LLIntSlowPaths.cpp:
+ (LLINT_SLOW_PATH_DECL(slow_op_debug)):
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createFunctionExpr):
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::createGetterOrSetterProperty):
+ (JSC::ASTBuilder::createFuncDeclStatement):
+ (JSC::ASTBuilder::createBlockStatement):
+ (JSC::ASTBuilder::createExprStatement):
+ (JSC::ASTBuilder::createIfStatement):
+ (JSC::ASTBuilder::createForLoop):
+ (JSC::ASTBuilder::createForInLoop):
+ (JSC::ASTBuilder::createVarStatement):
+ (JSC::ASTBuilder::createReturnStatement):
+ (JSC::ASTBuilder::createBreakStatement):
+ (JSC::ASTBuilder::createContinueStatement):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createSwitchStatement):
+ (JSC::ASTBuilder::createWhileStatement):
+ (JSC::ASTBuilder::createDoWhileStatement):
+ (JSC::ASTBuilder::createWithStatement):
+ (JSC::ASTBuilder::createThrowStatement):
+ (JSC::ASTBuilder::createDebugger):
+ (JSC::ASTBuilder::createConstStatement):
+ * parser/Lexer.cpp:
+ (JSC::::setCode):
+ (JSC::::internalShift):
+ (JSC::::shift):
+ (JSC::::lex):
+ * parser/Lexer.h:
+ (JSC::Lexer::currentCharPosition):
+ (Lexer):
+ (JSC::::lexExpectIdentifier):
+ * parser/NodeConstructors.h:
+ (JSC::Node::Node):
+ * parser/Nodes.cpp:
+ (JSC::StatementNode::setLoc):
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (JSC::Node::charPosition):
+ (Node):
+ (StatementNode):
+ (JSC::StatementNode::lastLine):
+ (ScopeNode):
+ (JSC::ScopeNode::startLine):
+ (JSC::ScopeNode::startCharPosition):
+ (ProgramNode):
+ (EvalNode):
+ (FunctionBodyNode):
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ (JSC::::parseFunctionBody):
+ (JSC::::parseFunctionInfo):
+ * parser/Parser.h:
+ (JSC::::parse):
+ * parser/ParserTokens.h:
+ (JSC::JSTokenLocation::JSTokenLocation):
+ (JSTokenLocation):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::createFunctionBody):
+
+2013-03-20 Csaba Osztrogonác <ossy@webkit.org>
+
+ REGRESSION(r146089): It broke 20 sputnik tests on ARM traditional and Thumb2
+ https://bugs.webkit.org/show_bug.cgi?id=112676
+
+ Rubber-stamped by Filip Pizlo.
+
+ Add one more EABI_32BIT_DUMMY_ARG to make DFG JIT ARM EABI compatible
+ again after r146089 similar to https://bugs.webkit.org/show_bug.cgi?id=84449
+
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+
+2013-03-19 Michael Saboff <msaboff@apple.com>
+
+ Crash when loading http://www.jqchart.com/jquery/gauges/RadialGauge/LiveData
+ https://bugs.webkit.org/show_bug.cgi?id=112694
+
+ Reviewed by Filip Pizlo.
+
+ We were trying to convert an NewArray to a Phantom, but convertToPhantom doesn't handle
+ nodes with variable arguments. Added code to insert a Phantom node in front of all the
+ live children of a var args node. Added ASSERT not var args for convertToPhantom to
+ catch any other similar cases. Added a new convertToPhantomUnchecked() for converting
+ var arg nodes.
+
+ * dfg/DFGDCEPhase.cpp:
+ (JSC::DFG::DCEPhase::run):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::setOpAndDefaultNonExitFlags): Added ASSERT(!(m_flags & NodeHasVarArgs))
+ (JSC::DFG::Node::setOpAndDefaultNonExitFlagsUnchecked):
+ (JSC::DFG::Node::convertToPhantomUnchecked):
+
+2013-03-19 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Crash in SpeculativeJIT::fillSpeculateIntInternal<false> on http://bellard.org/jslinux
+ https://bugs.webkit.org/show_bug.cgi?id=112738
+
+ Reviewed by Filip Pizlo.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixIntEdge): We shouldn't be killing this node because it could be
+ referenced by other people.
+
+2013-03-19 Oliver Hunt <oliver@apple.com>
+
+ RELEASE_ASSERT fires in exception handler lookup
+
+ RS=Geoff Garen.
+
+ Temporarily switch this RELEASE_ASSERT into a regular ASSERT
+ as currently this is producing fairly bad crashiness.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::handlerForBytecodeOffset):
+
+2013-03-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should optimize StringObject.length and StringOrStringObject.length
+ https://bugs.webkit.org/show_bug.cgi?id=112658
+
+ Reviewed by Mark Hahnenberg.
+
+ Implemented by injecting a ToString(StringObject:@a) or ToString(StringOrStringObject:@a) prior
+ to GetArrayLength with ArrayMode(Array::String) if @a is predicted StringObject or
+ StringOrStringObject.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::createToString):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::attemptToForceStringArrayModeByToStringConversion):
+ (JSC::DFG::FixupPhase::convertStringAddUse):
+
+2013-03-19 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ Implement and32 on ARMv7 and ARM traditional platforms
+ https://bugs.webkit.org/show_bug.cgi?id=112663
+
+ Reviewed by Zoltan Herczeg.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::and32): Add missing method.
+ (MacroAssemblerARM):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::and32): Add missing method.
+ (MacroAssemblerARMv7):
+
+2013-03-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG ToString generic cases should work correctly
+ https://bugs.webkit.org/show_bug.cgi?id=112654
+ <rdar://problem/13447250>
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-18 Michael Saboff <msaboff@apple.com>
+
+ Unreviewed build fix for 32 bit builds.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-18 Michael Saboff <msaboff@apple.com>
+
+ EFL: Unsafe branch detected in compilePutByValForFloatTypedArray()
+ https://bugs.webkit.org/show_bug.cgi?id=112609
+
+ Reviewed by Geoffrey Garen.
+
+ Created local valueFPR and scratchFPR and filled them with valueOp.fpr() and scratch.fpr()
+ respectively so that if valueOp.fpr() causes a spill during allocation, it occurs before the
+ branch and also to follow convention. Added register allocation checks to FPRTemporary.
+ Cleaned up a couple of other places to follow the "AllocatVirtualRegType foo, get machine
+ reg from foo" pattern.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::fprAllocate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::convertToDouble):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should inline binary string concatenations (i.e. ValueAdd with string children)
+ https://bugs.webkit.org/show_bug.cgi?id=112599
+
+ Reviewed by Oliver Hunt.
+
+ This does as advertised: if you do x + y where x and y are strings, you'll get
+ a fast inlined JSRopeString allocation (along with whatever checks are necessary).
+ It also does good things if either x or y (or both) are StringObjects, or some
+ other thing like StringOrStringObject. It also lays the groundwork for making this
+ fast if either x or y are numbers, or some other reasonably-cheap-to-convert
+ value.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::isStringObjectUse):
+ (JSC::DFG::FixupPhase::convertStringAddUse):
+ (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileAdd):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSCell):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
+ * runtime/JSString.h:
+ (JSC::JSString::offsetOfFlags):
+ (JSString):
+ (JSRopeString):
+ (JSC::JSRopeString::offsetOfFibers):
+
+2013-03-18 Filip Pizlo <fpizlo@apple.com>
+
+ JSC_NATIVE_FUNCTION() takes an identifier for the name and then uses #name, which is unsafe if name was already #define'd to something else
+ https://bugs.webkit.org/show_bug.cgi?id=112639
+
+ Reviewed by Michael Saboff.
+
+ Change it to take a string instead.
+
+ * runtime/JSObject.h:
+ (JSC):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::ObjectPrototype::finishCreation):
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::finishCreation):
+
+2013-03-18 Brent Fulgham <bfulgham@webkit.org>
+
+ [WinCairo] Get build working under VS2010.
+ https://bugs.webkit.org/show_bug.cgi?id=112604
+
+ Reviewed by Tim Horton.
+
+ * JavaScriptCore.vcxproj/testapi/testapi.vcxproj: Use CFLite-specific
+ build target (standard version links against CoreFoundation.lib
+ instead of CFLite.lib).
+ * JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiDebugCFLite.props: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiReleaseCFLite.props: Added.
+
+2013-03-18 Roger Fong <roger_fong@apple.com>
+
+ AppleWin VS2010 Debug configuration build fix..
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+
+2013-03-18 Brent Fulgham <bfulgham@webkit.org>
+
+ [WinCairo] Get build working under VS2010.
+ https://bugs.webkit.org/show_bug.cgi?id=112604
+
+ Reviewed by Tim Horton.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Add build targets for
+ Debug_WinCairo and Release_WinCairo using CFLite.
+ * JavaScriptCore.vcxproj/JavaScriptCoreCFLite.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreDebugCFLite.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj:
+ Add Debug_WinCairo and Release_WinCairo build targets to
+ make sure headers are copied to proper build folder.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj: Ditto.
+ * JavaScriptCore.vcxproj/JavaScriptCoreReleaseCFLite.props: Added.
+ * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj:
+ Add Debug_WinCairo and Release_WinCairo build targets to
+ make sure headers are copied to proper build folder.
+ * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj:
+ Ditto.
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj:
+ Ditto.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj: Ditto.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj: Ditto.
+ * JavaScriptCore.vcxproj/testapi/testapi.vcxproj: Ditto.
+
+2013-03-18 Michael Saboff <msaboff@apple.com>
+
+ Potentially unsafe register allocations in DFG code generation
+ https://bugs.webkit.org/show_bug.cgi?id=112477
+
+ Reviewed by Geoffrey Garen.
+
+ Moved allocation of temporary GPRs to be before any generated branches in the functions below.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+
+2013-03-15 Filip Pizlo <fpizlo@apple.com>
+
+ DFG string conversions and allocations should be inlined
+ https://bugs.webkit.org/show_bug.cgi?id=112376
+
+ Reviewed by Geoffrey Garen.
+
+ This turns new String(), String(), String.prototype.valueOf(), and
+ String.prototype.toString() into intrinsics. It gives the DFG the ability to handle
+ conversions from StringObject to JSString and vice-versa, and also gives it the
+ ability to handle cases where a variable may be either a StringObject or a JSString.
+ To do this, I added StringObject to value profiling (and removed the stale
+ distinction between Myarguments and Foreignarguments). I also cleaned up ToPrimitive
+ handling, using some of the new functionality but also taking advantage of the
+ existence of Identity(String:@a).
+
+ This is a 2% SunSpider speed-up. Also there are some speed-ups on V8v7 and Kraken.
+ On microbenchmarks that stress new String() this is a 14x speed-up.
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * DerivedSources.pri:
+ * GNUmakefile.list.am:
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::hasExitSite):
+ (JSC):
+ * bytecode/DFGExitProfile.cpp:
+ (JSC::DFG::ExitProfile::hasExitSite):
+ (DFG):
+ * bytecode/DFGExitProfile.h:
+ (ExitProfile):
+ (JSC::DFG::ExitProfile::hasExitSite):
+ * bytecode/ExitKind.cpp:
+ (JSC::exitKindToString):
+ * bytecode/ExitKind.h:
+ * bytecode/SpeculatedType.cpp:
+ (JSC::dumpSpeculation):
+ (JSC::speculationToAbbreviatedString):
+ (JSC::speculationFromClassInfo):
+ * bytecode/SpeculatedType.h:
+ (JSC):
+ (JSC::isStringObjectSpeculation):
+ (JSC::isStringOrStringObjectSpeculation):
+ * create_hash_table:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGAbstractState.h:
+ (JSC::DFG::AbstractState::filterEdgeByUse):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::emitArgumentPhantoms):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ * dfg/DFGEdge.h:
+ (JSC::DFG::Edge::shift):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::isStringPrototypeMethodSane):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+ (JSC::DFG::FixupPhase::observeUseKindOnNode):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::hasGlobalExitSite):
+ (Graph):
+ (JSC::DFG::Graph::hasExitSite):
+ (JSC::DFG::Graph::clobbersWorld):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::convertToToString):
+ (Node):
+ (JSC::DFG::Node::hasStructure):
+ (JSC::DFG::Node::shouldSpeculateStringObject):
+ (JSC::DFG::Node::shouldSpeculateStringOrStringObject):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileNewStringObject):
+ (JSC::DFG::SpeculativeJIT::speculateObject):
+ (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+ (JSC::DFG::SpeculativeJIT::speculateString):
+ (JSC::DFG::SpeculativeJIT::speculateStringObject):
+ (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
+ (JSC::DFG::SpeculativeJIT::speculate):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGUseKind.cpp:
+ (WTF::printInternal):
+ * dfg/DFGUseKind.h:
+ (JSC::DFG::typeFilterFor):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::regExpPrototypeTable):
+ * runtime/CommonIdentifiers.h:
+ * runtime/Intrinsic.h:
+ * runtime/JSDestructibleObject.h:
+ (JSDestructibleObject):
+ (JSC::JSDestructibleObject::classInfoOffset):
+ * runtime/JSGlobalData.cpp:
+ (JSC):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSObject.cpp:
+ * runtime/JSObject.h:
+ (JSC):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::allocationSize):
+ (JSWrapperObject):
+ (JSC::JSWrapperObject::internalValueOffset):
+ (JSC::JSWrapperObject::internalValueCellOffset):
+ * runtime/StringPrototype.cpp:
+ (JSC):
+ (JSC::StringPrototype::finishCreation):
+ (JSC::StringPrototype::create):
+ * runtime/StringPrototype.h:
+ (StringPrototype):
+
+2013-03-18 Filip Pizlo <fpizlo@apple.com>
+
+ ObjectPrototype properties should be eagerly created rather than lazily via static tables
+ https://bugs.webkit.org/show_bug.cgi?id=112539
+
+ Reviewed by Oliver Hunt.
+
+ This is the first part of https://bugs.webkit.org/show_bug.cgi?id=112233. Rolling this
+ in first since it's the less-likely-to-be-broken part.
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * DerivedSources.pri:
+ * GNUmakefile.list.am:
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::objectConstructorTable):
+ * runtime/CommonIdentifiers.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putDirectNativeFunction):
+ (JSC):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC):
+ * runtime/Lookup.cpp:
+ (JSC::setUpStaticFunctionSlot):
+ * runtime/ObjectPrototype.cpp:
+ (JSC):
+ (JSC::ObjectPrototype::finishCreation):
+ (JSC::ObjectPrototype::create):
+ * runtime/ObjectPrototype.h:
+ (ObjectPrototype):
+
+2013-03-16 Pratik Solanki <psolanki@apple.com>
+
+ Disable High DPI Canvas on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=112511
+
+ Reviewed by Joseph Pecoraro.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-03-15 Andreas Kling <akling@apple.com>
+
+ Don't also clone StructureRareData when cloning Structure.
+ <http://webkit.org/b/111672>
+
+ Reviewed by Mark Hahnenberg.
+
+ We were cloning a lot of StructureRareData with only the previousID pointer set since
+ the enumerationCache is not shared between clones.
+
+ Let the Structure copy constructor decide whether it wants to clone the rare data.
+ The decision is made by StructureRareData::needsCloning() and will currently always
+ return false, since StructureRareData only holds on to caches at present.
+ This may change in the future as more members are added to StructureRareData.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC::Structure::cloneRareDataFrom):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::create):
+
+2013-03-15 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Roll out r145838
+ https://bugs.webkit.org/show_bug.cgi?id=112458
+
+ Unreviewed. Requested by Filip Pizlo.
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * DerivedSources.pri:
+ * GNUmakefile.list.am:
+ * dfg/DFGOperations.cpp:
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::objectPrototypeTable):
+ * jit/JITStubs.cpp:
+ (JSC::getByVal):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::getByVal):
+ * runtime/CommonIdentifiers.h:
+ * runtime/JSCell.cpp:
+ (JSC):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSCellInlines.h:
+ (JSC):
+ (JSC::JSCell::fastGetOwnProperty):
+ * runtime/JSGlobalData.cpp:
+ (JSC):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSObject.cpp:
+ (JSC):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC):
+ * runtime/Lookup.cpp:
+ (JSC::setUpStaticFunctionSlot):
+ * runtime/ObjectPrototype.cpp:
+ (JSC):
+ (JSC::ObjectPrototype::finishCreation):
+ (JSC::ObjectPrototype::getOwnPropertySlot):
+ (JSC::ObjectPrototype::getOwnPropertyDescriptor):
+ * runtime/ObjectPrototype.h:
+ (JSC::ObjectPrototype::create):
+ (ObjectPrototype):
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyTable::findWithString):
+ * runtime/Structure.h:
+ (Structure):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::get):
+
+2013-03-15 Michael Saboff <msaboff@apple.com>
+
+ Cleanup of DFG and Baseline JIT debugging code
+ https://bugs.webkit.org/show_bug.cgi?id=111871
+
+ Reviewed by Geoffrey Garen.
+
+ Fixed various debug related issue in baseline and DFG JITs. See below.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::dfgLinkClosureCall): Used pointerDump() to handle when calleeCodeBlock is NULL.
+ * dfg/DFGScratchRegisterAllocator.h: Now use ScratchBuffer::activeLengthPtr() to get
+ pointer to scratch register length.
+ (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer):
+ (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkConsistency): Added missing case labels for DataFormatOSRMarker,
+ DataFormatDead, and DataFormatArguments and made them RELEASE_ASSERT_NOT_REACHED();
+ * jit/JITCall.cpp:
+ (JSC::JIT::privateCompileClosureCall): Used pointerDump() to handle when calleeCodeBlock is NULL.
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::privateCompileClosureCall): Used pointerDump() to handle when calleeCodeBlock is NULL.
+ * runtime/JSGlobalData.h:
+ (JSC::ScratchBuffer::ScratchBuffer): Fixed buffer allocation alignment to
+ be on a double boundary.
+ (JSC::ScratchBuffer::setActiveLength):
+ (JSC::ScratchBuffer::activeLength):
+ (JSC::ScratchBuffer::activeLengthPtr):
+
+2013-03-15 Michael Saboff <msaboff@apple.com>
+
+ Add runtime check for improper register allocations in DFG
+ https://bugs.webkit.org/show_bug.cgi?id=112380
+
+ Reviewed by Geoffrey Garen.
+
+ Added framework to check for register allocation within a branch source - target range. All register allocations
+ are saved using the offset in the code stream where the allocation occurred. Later when a jump is linked, the
+ currently saved register allocations are checked to make sure that they didn't occur in the range of code that was
+ jumped over. This protects against the case where an allocation could have spilled register contents to free up
+ a register and that spill only occurs on one path of a many through the code. A subsequent fill of the spilled
+ register may load garbage. See https://bugs.webkit.org/show_bug.cgi?id=111777 for one such bug.
+ This code is protected by the compile time check of #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION).
+ The check is only done during the processing of SpeculativeJIT::compile(Node* node) and its callees.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Jump::link): Invoke register allocation checks using source and target of link.
+ (JSC::AbstractMacroAssembler::Jump::linkTo): Invoke register allocation checks using source and target of link.
+ (AbstractMacroAssembler):
+ (RegisterAllocationOffset): New helper class to store the instruction stream offset and compare against a
+ jump range.
+ (JSC::AbstractMacroAssembler::RegisterAllocationOffset::RegisterAllocationOffset):
+ (JSC::AbstractMacroAssembler::RegisterAllocationOffset::check):
+ (JSC::AbstractMacroAssembler::addRegisterAllocationAtOffset):
+ (JSC::AbstractMacroAssembler::clearRegisterAllocationOffsets):
+ (JSC::AbstractMacroAssembler::checkRegisterAllocationAgainstBranchRange):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::allocate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-14 Oliver Hunt <oliver@apple.com>
+
+ REGRESSION(r145000): Crash loading arstechnica.com when Safari Web Inspector is open
+ https://bugs.webkit.org/show_bug.cgi?id=111868
+
+ Reviewed by Antti Koivisto.
+
+ Don't allow non-local property lookup when the debugger is enabled.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::resolve):
+
+2013-03-11 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Objective-C functions exposed to JavaScript have the wrong type (object instead of function)
+ https://bugs.webkit.org/show_bug.cgi?id=105892
+
+ Reviewed by Geoffrey Garen.
+
+ Changed ObjCCallbackFunction to subclass JSCallbackFunction which already has all of the machinery to call
+ functions using the C API. Since ObjCCallbackFunction is now a JSCell, we changed the old implementation of
+ ObjCCallbackFunction to be the internal implementation and keep track of all the proper data so that we
+ don't have to put all of that in the header, which will now be included from C++ files (e.g. JSGlobalObject.cpp).
+
+ * API/JSCallbackFunction.cpp: Change JSCallbackFunction to allow subclassing. Originally it was internally
+ passing its own Structure up the chain of constructors, but we now want to be able to pass other Structures as well.
+ (JSC::JSCallbackFunction::JSCallbackFunction):
+ (JSC::JSCallbackFunction::create):
+ * API/JSCallbackFunction.h:
+ (JSCallbackFunction):
+ * API/JSWrapperMap.mm: Changed interface to tryUnwrapBlock.
+ (tryUnwrapObjcObject):
+ * API/ObjCCallbackFunction.h:
+ (ObjCCallbackFunction): Moved into the JSC namespace, just like JSCallbackFunction.
+ (JSC::ObjCCallbackFunction::createStructure): Overridden so that the correct ClassInfo gets used since we have
+ a destructor.
+ (JSC::ObjCCallbackFunction::impl): Getter for the internal impl.
+ * API/ObjCCallbackFunction.mm:
+ (JSC::ObjCCallbackFunctionImpl::ObjCCallbackFunctionImpl): What used to be ObjCCallbackFunction is now
+ ObjCCallbackFunctionImpl. It handles the Objective-C specific parts of managing callback functions.
+ (JSC::ObjCCallbackFunctionImpl::~ObjCCallbackFunctionImpl):
+ (JSC::objCCallbackFunctionCallAsFunction): Same as the old one, but now it casts to ObjCCallbackFunction and grabs the impl
+ rather than using JSObjectGetPrivate.
+ (JSC::ObjCCallbackFunction::ObjCCallbackFunction): New bits to allow being part of the JSCell hierarchy.
+ (JSC::ObjCCallbackFunction::create):
+ (JSC::ObjCCallbackFunction::destroy):
+ (JSC::ObjCCallbackFunctionImpl::call): Handles the actual invocation, just like it used to.
+ (objCCallbackFunctionForInvocation):
+ (tryUnwrapBlock): Changed to check the ClassInfo for inheritance directly, rather than going through the C API call.
+ * API/tests/testapi.mm: Added new test to make sure that doing Function.prototype.toString.call(f) won't result in
+ an error when f is an Objective-C method or block underneath the covers.
+ * runtime/JSGlobalObject.cpp: Added new Structure for ObjCCallbackFunction.
+ (JSC::JSGlobalObject::reset):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::objcCallbackFunctionStructure):
+
+2013-03-14 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Nested dictionaries are not converted properly in the Objective-C binding
+ https://bugs.webkit.org/show_bug.cgi?id=112377
+
+ Reviewed by Oliver Hunt.
+
+ Accidental reassignment of the root task in the container conversion logic was causing the last
+ array or dictionary processed to be returned in the case of nested containers.
+
+ * API/JSValue.mm:
+ (containerValueToObject):
+ * API/tests/testapi.mm:
+
+2013-03-13 Filip Pizlo <fpizlo@apple.com>
+
+ JSObject fast by-string access optimizations should work even on the prototype chain, and even when the result is undefined
+ https://bugs.webkit.org/show_bug.cgi?id=112233
+
+ Reviewed by Oliver Hunt.
+
+ Extended the existing fast access path for String keys to work over the entire prototype chain,
+ not just the self access case. This will fail as soon as it sees an object that intercepts
+ getOwnPropertySlot, so this patch also ensures that ObjectPrototype does not fall into that
+ category. This is accomplished by making ObjectPrototype eagerly reify all of its properties.
+ This is safe for ObjectPrototype because it's so common and we expect all of its properties to
+ be reified for any interesting programs anyway. A new idiom for adding native functions to
+ prototypes is introduced, which ought to work well for any other prototypes that we wish to do
+ this conversion for.
+
+ This is a >60% speed-up in the case that you frequently do by-string lookups that "miss", i.e.
+ they don't turn up anything.
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * DerivedSources.pri:
+ * GNUmakefile.list.am:
+ * dfg/DFGOperations.cpp:
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::objectConstructorTable):
+ * jit/JITStubs.cpp:
+ (JSC::getByVal):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::getByVal):
+ * runtime/CommonIdentifiers.h:
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::getByStringSlow):
+ (JSC):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSCellInlines.h:
+ (JSC):
+ (JSC::JSCell::getByStringAndKey):
+ (JSC::JSCell::getByString):
+ * runtime/JSGlobalData.cpp:
+ (JSC):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putDirectNativeFunction):
+ (JSC):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC):
+ * runtime/Lookup.cpp:
+ (JSC::setUpStaticFunctionSlot):
+ * runtime/ObjectPrototype.cpp:
+ (JSC):
+ (JSC::ObjectPrototype::finishCreation):
+ (JSC::ObjectPrototype::create):
+ * runtime/ObjectPrototype.h:
+ (ObjectPrototype):
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyTable::findWithString):
+ * runtime/Structure.h:
+ (Structure):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::get):
+ (JSC):
+
+2013-03-13 Filip Pizlo <fpizlo@apple.com>
+
+ DFG bytecode parser is too aggressive about getting rid of GetLocals on captured variables
+ https://bugs.webkit.org/show_bug.cgi?id=112287
+ <rdar://problem/13342340>
+
+ Reviewed by Oliver Hunt.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getLocal):
+
+2013-03-13 Ryosuke Niwa <rniwa@webkit.org>
+
+ Threaded HTML Parser is missing feature define flags in all but Chromium port's build files
+ https://bugs.webkit.org/show_bug.cgi?id=112277
+
+ Reviewed by Adam Barth.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-03-13 Csaba Osztrogonác <ossy@webkit.org>
+
+ LLINT C loop warning fix for GCC
+ https://bugs.webkit.org/show_bug.cgi?id=112145
+
+ Reviewed by Filip Pizlo.
+
+ * llint/LowLevelInterpreter.cpp:
+ (JSC::CLoop::execute):
+
+2013-02-13 Simon Hausmann <simon.hausmann@digia.com>
+
+ Add support for convenient conversion from JSStringRef to QString
+ https://bugs.webkit.org/show_bug.cgi?id=109694
+
+ Reviewed by Allan Sandfeld Jensen.
+
+ Add JSStringCopyQString helper function that allows for the convenient
+ extraction of a QString out of a JSStringRef.
+
+ * API/JSStringRefQt.cpp: Added.
+ (JSStringCopyQString):
+ * API/JSStringRefQt.h: Added.
+ * API/OpaqueJSString.h:
+ (OpaqueJSString):
+ (OpaqueJSString::qString):
+ (OpaqueJSString::OpaqueJSString):
+ * Target.pri:
+
+2013-03-13 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Token 'not' is ignored in the offlineasm.
+ https://bugs.webkit.org/show_bug.cgi?id=111568
+
+ Reviewed by Filip Pizlo.
+
+ * offlineasm/parser.rb: Build the Not AST node if the 'not' token is found.
+
+2013-03-12 Tim Horton <timothy_horton@apple.com>
+
+ WTF uses macros for exports. Try to fix the Windows build. Unreviewed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-03-12 Filip Pizlo <fpizlo@apple.com>
+
+ Array.prototype.sort should at least try to be PTIME even when the array is in some bizarre mode
+ https://bugs.webkit.org/show_bug.cgi?id=112187
+ <rdar://problem/13393550>
+
+ Reviewed by Michael Saboff and Gavin Barraclough.
+
+ If we have an array-like object in crazy mode passed into Array.prototype.sort, and its length is large,
+ then first copy all elements into a separate, compact, un-holy array and sort that. Then copy back.
+ This means that sorting will be at worst O(n^2) in the actual number of things in the array, rather than
+ O(n^2) in the array's length.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::attemptFastSort):
+ (JSC::performSlowSort):
+ (JSC):
+ (JSC::arrayProtoFuncSort):
+
+2013-03-12 Tim Horton <timothy_horton@apple.com>
+
+ Try to fix the Windows build.
+
+ Not reviewed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-03-12 Geoffrey Garen <ggaren@apple.com>
+
+ Try to fix the Windows build.
+
+ Not reviewed.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ Export a thing.
+
+2013-03-11 Oliver Hunt <oliver@apple.com>
+
+ Harden JSStringJoiner
+ https://bugs.webkit.org/show_bug.cgi?id=112093
+
+ Reviewed by Filip Pizlo.
+
+ Harden JSStringJoiner, make it use our CheckedArithmetic
+ class to simplify everything.
+
+ * runtime/JSStringJoiner.cpp:
+ (JSC::JSStringJoiner::build):
+ * runtime/JSStringJoiner.h:
+ (JSStringJoiner):
+ (JSC::JSStringJoiner::JSStringJoiner):
+ (JSC::JSStringJoiner::append):
+
+2013-03-12 Filip Pizlo <fpizlo@apple.com>
+
+ DFG generic array access cases should not be guarded by CheckStructure even of the profiling tells us that it could be
+ https://bugs.webkit.org/show_bug.cgi?id=112183
+
+ Reviewed by Oliver Hunt.
+
+ Slight speed-up on string-unpack-code.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::findAndRemoveUnnecessaryStructureCheck):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+
+2013-03-12 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ https://bugs.webkit.org/show_bug.cgi?id=112141
+ LLInt CLoop backend misses Double2Ints() on 32bit architectures
+
+ Reviewed by Filip Pizlo.
+
+ Implement Double2Ints() in CLoop backend of LLInt on 32bit architectures.
+
+ * llint/LowLevelInterpreter.cpp:
+ (LLInt):
+ (JSC::LLInt::Double2Ints):
+ * offlineasm/cloop.rb:
+
+2013-03-12 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ Making more sophisticated cache flush on ARM Linux platform
+ https://bugs.webkit.org/show_bug.cgi?id=111854
+
+ Reviewed by Zoltan Herczeg.
+
+ The cache flush on ARM Linux invalidates whole pages
+ instead of just the required area.
+
+ * assembler/ARMAssembler.h:
+ (ARMAssembler):
+ (JSC::ARMAssembler::linuxPageFlush):
+ (JSC::ARMAssembler::cacheFlush):
+ * assembler/ARMv7Assembler.h:
+ (ARMv7Assembler):
+ (JSC::ARMv7Assembler::linuxPageFlush):
+ (JSC::ARMv7Assembler::cacheFlush):
+
+2013-03-12 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ Renaming the armv7.rb LLINT backend to arm.rb
+ https://bugs.webkit.org/show_bug.cgi?id=110565
+
+ Reviewed by Zoltan Herczeg.
+
+ This is the first step of a unified ARM backend for
+ all ARM 32 bit architectures in LLInt.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * LLIntOffsetsExtractor.pro:
+ * offlineasm/arm.rb: Copied from Source/JavaScriptCore/offlineasm/armv7.rb.
+ * offlineasm/armv7.rb: Removed.
+ * offlineasm/backends.rb:
+ * offlineasm/risc.rb:
+
+2013-03-12 Csaba Osztrogonác <ossy@webkit.org>
+
+ REGRESSION(r145482): It broke 33 jsc tests and zillion layout tests on all platform
+ https://bugs.webkit.org/show_bug.cgi?id=112112
+
+ Reviewed by Oliver Hunt.
+
+ Rolling out https://trac.webkit.org/changeset/145482 to unbreak the bots.
+
+ * runtime/JSStringJoiner.cpp:
+ (JSC::JSStringJoiner::build):
+ * runtime/JSStringJoiner.h:
+ (JSStringJoiner):
+ (JSC::JSStringJoiner::JSStringJoiner):
+ (JSC::JSStringJoiner::append):
+
+2013-03-12 Filip Pizlo <fpizlo@apple.com>
+
+ DFG prediction propagation phase should not rerun forward propagation if double voting has already converged
+ https://bugs.webkit.org/show_bug.cgi?id=111920
+
+ Reviewed by Oliver Hunt.
+
+ I don't know why we weren't exiting early after double voting if !m_changed.
+
+ This change also removes backwards propagation from the voting fixpoint, since at that
+ point short-circuiting loops is probably not particularly profitable. Profiling shows
+ that this reduces the time spent in prediction propagation even further.
+
+ This change appears to be a 1% SunSpider speed-up.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::run):
+
+2013-03-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG overflow check elimination is too smart for its own good
+ https://bugs.webkit.org/show_bug.cgi?id=111832
+
+ Reviewed by Oliver Hunt and Gavin Barraclough.
+
+ Rolling this back in after fixing accidental misuse of JSValue. The code was doing value < someInt
+ rather than value.asInt32() < someInt. This "worked" when isWithinPowerOfTwo wasn't templatized.
+ It worked by always being false and always disabling the relvant optimization.
+
+ This improves overflow check elimination in three ways:
+
+ 1) It reduces the amount of time the compiler will spend doing it.
+
+ 2) It fixes bugs where overflow check elimination was overzealous. Precisely, for a binary operation
+ over @a and @b where both @a and @b will type check that their inputs (@a->children, @b->children)
+ are int32's and then perform a possibly-overflowing operation, we must be careful not to assume
+ that @a's non-int32 parts don't matter if at the point that @a runs we have as yet not proved that
+ @b->children are int32's and that hence @b might produce a large enough result that doubles would
+ start chopping low bits. The specific implication of this is that for a binary operation to not
+ propagate that it cares about non-int32 parts (NodeUsedAsNumber), we must prove that at least one
+ of the inputs is guaranteed to produce a result within 2^32 and that there won't be a tower of such
+ operations large enough to ultimately produce a double greater than 2^52 (roughly). We achieve the
+ latter by disabling this optimization for very large basic blocks. It's noteworthy that blocks that
+ large won't even make it into the DFG currently.
+
+ 3) It makes the overflow check elimination more precise for cases where the inputs to an Add or Sub
+ are the outputs of a bit-op. For example in (@a + (@b | 0)) | 0, we don't need to propagate
+ NodeUsedAsNumber to either @a or @b.
+
+ This is neutral on V8v7 and a slight speed-up on compile time benchmarks.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::refine):
+ * dfg/DFGBackwardsPropagationPhase.cpp: Added.
+ (DFG):
+ (BackwardsPropagationPhase):
+ (JSC::DFG::BackwardsPropagationPhase::BackwardsPropagationPhase):
+ (JSC::DFG::BackwardsPropagationPhase::run):
+ (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
+ (JSC::DFG::BackwardsPropagationPhase::isNotZero):
+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoNonRecursive):
+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
+ (JSC::DFG::BackwardsPropagationPhase::mergeDefaultFlags):
+ (JSC::DFG::BackwardsPropagationPhase::propagate):
+ (JSC::DFG::performBackwardsPropagation):
+ * dfg/DFGBackwardsPropagationPhase.h: Added.
+ (DFG):
+ * dfg/DFGCPSRethreadingPhase.cpp:
+ (JSC::DFG::CPSRethreadingPhase::run):
+ (JSC::DFG::CPSRethreadingPhase::clearIsLoadedFrom):
+ (CPSRethreadingPhase):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::dumpNodeFlags):
+ (DFG):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGUnificationPhase.cpp:
+ (JSC::DFG::UnificationPhase::run):
+ * dfg/DFGVariableAccessData.h:
+ (JSC::DFG::VariableAccessData::VariableAccessData):
+ (JSC::DFG::VariableAccessData::mergeIsLoadedFrom):
+ (VariableAccessData):
+ (JSC::DFG::VariableAccessData::setIsLoadedFrom):
+ (JSC::DFG::VariableAccessData::isLoadedFrom):
+
+2013-03-11 Oliver Hunt <oliver@apple.com>
+
+ Harden JSStringJoiner
+ https://bugs.webkit.org/show_bug.cgi?id=112093
+
+ Reviewed by Filip Pizlo.
+
+ Harden JSStringJoiner, make it use our CheckedArithmetic
+ class to simplify everything.
+
+ * runtime/JSStringJoiner.cpp:
+ (JSC::JSStringJoiner::build):
+ * runtime/JSStringJoiner.h:
+ (JSStringJoiner):
+ (JSC::JSStringJoiner::JSStringJoiner):
+ (JSC::JSStringJoiner::append):
+
+2013-03-11 Michael Saboff <msaboff@apple.com>
+
+ Crash beneath operationCreateInlinedArguments running fast/js/dfg-create-inlined-arguments-in-closure-inline.html (32-bit only)
+ https://bugs.webkit.org/show_bug.cgi?id=112067
+
+ Reviewed by Geoffrey Garen.
+
+ We weren't setting the tag in SetCallee. Therefore set it to CellTag.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-11 Oliver Hunt <oliver@apple.com>
+
+ Make SegmentedVector Noncopyable
+ https://bugs.webkit.org/show_bug.cgi?id=112059
+
+ Reviewed by Geoffrey Garen.
+
+ Copying a SegmentedVector is very expensive, and really shouldn't
+ be necessary. So I've taken the one place where we currently copy
+ and replaced it with a regular Vector, and replaced the address
+ dependent logic with a indexing ref instead.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::newLabelScope):
+ (JSC::BytecodeGenerator::emitComplexJumpScopes):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/LabelScope.h:
+ (JSC):
+ (JSC::LabelScopePtr::LabelScopePtr):
+ (LabelScopePtr):
+ (JSC::LabelScopePtr::operator=):
+ (JSC::LabelScopePtr::~LabelScopePtr):
+ (JSC::LabelScopePtr::operator*):
+ (JSC::LabelScopePtr::operator->):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+
+2013-03-10 Andreas Kling <akling@apple.com>
+
+ SpeculativeJIT should use OwnPtr<SlowPathGenerator>.
+ <http://webkit.org/b/111942>
+
+ Reviewed by Anders Carlsson.
+
+ There's no need to include DFGSlowPathGenerator.h from the header as long as the destructor is out-of-line,
+ so let's use OwnPtr instead of raw pointers + deleteAllValues().
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::~SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::addSlowPathGenerator):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2013-03-09 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r145299.
+ http://trac.webkit.org/changeset/145299
+ https://bugs.webkit.org/show_bug.cgi?id=111928
+
+ compilation failure with recent clang
+ (DFGBackwardsPropagationPhase.cpp:132:35: error: comparison of
+ constant 10 with expression of type 'bool' is always false)
+ (Requested by thorton on #webkit).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::refine):
+ * dfg/DFGBackwardsPropagationPhase.cpp: Removed.
+ * dfg/DFGBackwardsPropagationPhase.h: Removed.
+ * dfg/DFGCPSRethreadingPhase.cpp:
+ (JSC::DFG::CPSRethreadingPhase::run):
+ (CPSRethreadingPhase):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::nodeFlagsAsString):
+ (DFG):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::isNotNegZero):
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::isNotZero):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoForConstant):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoNonRecursive):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwo):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags):
+ * dfg/DFGUnificationPhase.cpp:
+ (JSC::DFG::UnificationPhase::run):
+ * dfg/DFGVariableAccessData.h:
+ (JSC::DFG::VariableAccessData::VariableAccessData):
+ (VariableAccessData):
+
+2013-03-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG overflow check elimination is too smart for its own good
+ https://bugs.webkit.org/show_bug.cgi?id=111832
+
+ Reviewed by Oliver Hunt and Gavin Barraclough.
+
+ This improves overflow check elimination in three ways:
+
+ 1) It reduces the amount of time the compiler will spend doing it.
+
+ 2) It fixes bugs where overflow check elimination was overzealous. Precisely, for a binary operation
+ over @a and @b where both @a and @b will type check that their inputs (@a->children, @b->children)
+ are int32's and then perform a possibly-overflowing operation, we must be careful not to assume
+ that @a's non-int32 parts don't matter if at the point that @a runs we have as yet not proved that
+ @b->children are int32's and that hence @b might produce a large enough result that doubles would
+ start chopping low bits. The specific implication of this is that for a binary operation to not
+ propagate that it cares about non-int32 parts (NodeUsedAsNumber), we must prove that at least one
+ of the inputs is guaranteed to produce a result within 2^32 and that there won't be a tower of such
+ operations large enough to ultimately produce a double greater than 2^52 (roughly). We achieve the
+ latter by disabling this optimization for very large basic blocks. It's noteworthy that blocks that
+ large won't even make it into the DFG currently.
+
+ 3) It makes the overflow check elimination more precise for cases where the inputs to an Add or Sub
+ are the outputs of a bit-op. For example in (@a + (@b | 0)) | 0, we don't need to propagate
+ NodeUsedAsNumber to either @a or @b.
+
+ This is neutral on V8v7 and a slight speed-up on compile time benchmarks.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::refine):
+ * dfg/DFGBackwardsPropagationPhase.cpp: Added.
+ (DFG):
+ (BackwardsPropagationPhase):
+ (JSC::DFG::BackwardsPropagationPhase::BackwardsPropagationPhase):
+ (JSC::DFG::BackwardsPropagationPhase::run):
+ (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
+ (JSC::DFG::BackwardsPropagationPhase::isNotZero):
+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoForConstant):
+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwoNonRecursive):
+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo):
+ (JSC::DFG::BackwardsPropagationPhase::mergeDefaultFlags):
+ (JSC::DFG::BackwardsPropagationPhase::propagate):
+ (JSC::DFG::performBackwardsPropagation):
+ * dfg/DFGBackwardsPropagationPhase.h: Added.
+ (DFG):
+ * dfg/DFGCPSRethreadingPhase.cpp:
+ (JSC::DFG::CPSRethreadingPhase::run):
+ (JSC::DFG::CPSRethreadingPhase::clearIsLoadedFrom):
+ (CPSRethreadingPhase):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::dumpNodeFlags):
+ (DFG):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGUnificationPhase.cpp:
+ (JSC::DFG::UnificationPhase::run):
+ * dfg/DFGVariableAccessData.h:
+ (JSC::DFG::VariableAccessData::VariableAccessData):
+ (JSC::DFG::VariableAccessData::mergeIsLoadedFrom):
+ (VariableAccessData):
+ (JSC::DFG::VariableAccessData::setIsLoadedFrom):
+ (JSC::DFG::VariableAccessData::isLoadedFrom):
+
+2013-03-08 Roger Fong <roger_fong@apple.com>
+
+ Makefile fixes.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.make:
+
+2013-03-08 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ Cache flush problem on ARMv7 JSC
+ https://bugs.webkit.org/show_bug.cgi?id=111441
+
+ Reviewed by Zoltan Herczeg.
+
+ Not proper cache flush causing random crashes on ARMv7 Linux with V8 tests.
+ The problem is similar to https://bugs.webkit.org/show_bug.cgi?id=77712.
+ Change the cache fulsh mechanism similar to ARM traditinal and revert the
+ temporary fix.
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::cacheFlush):
+
+2013-03-07 Geoffrey Garen <ggaren@apple.com>
+
+ REGRESSION (r143759): 40% JSBench regression, 20% Octane/closure regression, 40% Octane/jquery regression, 2% Octane regression
+ https://bugs.webkit.org/show_bug.cgi?id=111797
+
+ Reviewed by Oliver Hunt.
+
+ The bot's testing configuration stresses the cache's starting guess
+ of 1MB.
+
+ This patch removes any starting guess, and just uses wall clock time
+ to discover the initial working set size of an app, in code size.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCacheMap::pruneSlowCase): Update our timer as we go.
+
+ Also fixed a bug where pruning from 0 to 0 would hang -- that case is
+ a possibility now that we start with a capacity of 0.
+
+ * runtime/CodeCache.h:
+ (CodeCacheMap):
+ (JSC::CodeCacheMap::CodeCacheMap):
+ (JSC::CodeCacheMap::add):
+ (JSC::CodeCacheMap::prune): Don't prune if we're in the middle of
+ discovering the working set size of an app, in code size.
+
+2013-03-07 Michael Saboff <msaboff@apple.com>
+
+ Crash when updating predictions below JSC::arrayProtoFuncForEach on tuaw.com article
+ https://bugs.webkit.org/show_bug.cgi?id=111777
+
+ Reviewed by Filip Pizlo.
+
+ Moved register allocations to be above any generated control flow so that any
+ resulting spill would be visible to all subsequently generated code.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-07 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not get corrupted IR in the case of code that is dead, unreachable, and contains a chain of nodes that use each other in an untyped way
+ https://bugs.webkit.org/show_bug.cgi?id=111783
+
+ Reviewed by Mark Hahnenberg.
+
+ Unreachable code is not touched by CFA and so thinks that even untyped uses are checked.
+ But dead untyped uses don't need checks and hence don't need to be Phantom'd. The DCE knew
+ this in findTypeCheckRoot() but not in eliminateIrrelevantPhantomChildren(), leading to a
+ Phantom node that had another Phantom node as one of its kids.
+
+ * dfg/DFGDCEPhase.cpp:
+ (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
+
+2013-03-07 Filip Pizlo <fpizlo@apple.com>
+
+ The DFG fixpoint is not strictly profitable, and should be straight-lined
+ https://bugs.webkit.org/show_bug.cgi?id=111764
+
+ Reviewed by Oliver Hunt and Geoffrey Garen.
+
+ The DFG previously ran optimizations to fixpoint because there exists a circular dependency:
+
+ CSE depends on CFG simplification: CFG simplification merges blocks, and CSE is block-local.
+
+ CFG simplification depends on CFA and constant folding: constant folding reveals branches on
+ constants.
+
+ CFA depends on CSE: CSE reveals must-alias relationships by proving that two operations
+ always produce identical values.
+
+ Arguments simplification also depends on CSE, but it ought not depend on anything else.
+
+ Hence we get a cycle like: CFA -> folding -> CFG -> CSE -> CFA.
+
+ Note that before we had sparse conditional CFA, we also had CFA depending on CFG. This ought
+ not be the case anymore: CFG simplification should not by itself lead to better CFA results.
+
+ My guess is that the weakest link in this cycle is CFG -> CSE. CSE cuts both ways: if you
+ CSE too much then you increase register pressure. Hence it's not clear that you always want
+ to CSE after simplifying control flow. This leads to an order of optimization as follows:
+
+ CSE -> arguments -> CFA -> folding -> CFG
+
+ This is a 2.5% speed-up on SunSpider, a 4% speed-up on V8Spider, a possible 0.3% slow-down
+ on V8v7, nothing on Kraken, and 1.2% speed-up in the JSRegress geomean. I'll take a 2.5%
+ speed-up over a 0.3% V8v7 speed-up.
+
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+
+2013-03-07 Roger Fong <roger_fong@apple.com>
+
+ Build fix for AppleWin VS2010.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2013-03-05 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Need a good way to reference event handlers without causing cycles
+ https://bugs.webkit.org/show_bug.cgi?id=111088
+
+ Reviewed by Geoffrey Garen.
+
+ JSManagedValue is like a special kind of weak value. When you create a JSManagedValue, you can
+ supply an Objective-C object as its "owner". As long as the Objective-C owner object remains
+ alive and its wrapper remains accessible to the JSC garbage collector (e.g. by being marked by
+ the global object), the reference to the JavaScript value is strong. As soon as the Objective-C
+ owner is deallocated or its wrapper becomes inaccessible to the garbage collector, the reference
+ becomes weak.
+
+ If you do not supply an owner or you use the weakValueWithValue: convenience class method, the
+ returned JSManagedValue behaves as a normal weak reference.
+
+ This new class allows clients to maintain references to JavaScript values in the Objective-C
+ heap without creating reference cycles/leaking memory.
+
+ * API/JSAPIWrapperObject.cpp: Added.
+ (JSC):
+ (JSC::::createStructure):
+ (JSC::JSAPIWrapperObject::JSAPIWrapperObject): This is a special JSObject for the Objective-C API that knows
+ for the purposes of garbage collection/marking that it wraps an opaque Objective-C object.
+ (JSC::JSAPIWrapperObject::visitChildren): We add the pointer to the wrapped Objective-C object to the set of
+ opaque roots so that the weak handle owner for JSManagedValues can find it later.
+ * API/JSAPIWrapperObject.h: Added.
+ (JSC):
+ (JSAPIWrapperObject):
+ (JSC::JSAPIWrapperObject::wrappedObject):
+ (JSC::JSAPIWrapperObject::setWrappedObject):
+ * API/JSBase.cpp:
+ (JSSynchronousGarbageCollect):
+ * API/JSBasePrivate.h:
+ * API/JSCallbackObject.cpp:
+ (JSC):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::destroy): Moved this to the header so that we don't get link errors with JSAPIWrapperObject.
+ * API/JSContext.mm:
+ (-[JSContext initWithVirtualMachine:]): We weren't adding manually allocated/initialized JSVirtualMachine objects to
+ the global cache of virtual machines. The init methods handle this now rather than contextWithGlobalContextRef, since
+ not everyone is guaranteed to use the latter.
+ (-[JSContext initWithGlobalContextRef:]):
+ (+[JSContext contextWithGlobalContextRef:]):
+ * API/JSManagedValue.h: Added.
+ * API/JSManagedValue.mm: Added.
+ (JSManagedValueHandleOwner):
+ (managedValueHandleOwner):
+ (+[JSManagedValue weakValueWithValue:]):
+ (+[JSManagedValue managedValueWithValue:owner:]):
+ (-[JSManagedValue init]): We explicitly call the ARC entrypoints to initialize/get the weak owner field since we don't
+ use ARC when building our framework.
+ (-[JSManagedValue initWithValue:]):
+ (-[JSManagedValue initWithValue:owner:]):
+ (-[JSManagedValue dealloc]):
+ (-[JSManagedValue value]):
+ (-[JSManagedValue weakOwner]):
+ (JSManagedValueHandleOwner::isReachableFromOpaqueRoots): If the Objective-C owner is still alive (i.e. loading the weak field
+ returns non-nil) and that value was added to the set of opaque roots by the wrapper for that Objective-C owner, then the the
+ JSObject to which the JSManagedObject refers is still alive.
+ * API/JSObjectRef.cpp: We have to add explicit checks for the JSAPIWrapperObject, just like the other types of JSCallbackObjects.
+ (JSObjectGetPrivate):
+ (JSObjectSetPrivate):
+ (JSObjectGetPrivateProperty):
+ (JSObjectSetPrivateProperty):
+ (JSObjectDeletePrivateProperty):
+ * API/JSValue.mm:
+ (objectToValueWithoutCopy):
+ * API/JSValueRef.cpp:
+ (JSValueIsObjectOfClass):
+ * API/JSVirtualMachine.mm:
+ (-[JSVirtualMachine initWithContextGroupRef:]):
+ (+[JSVirtualMachine virtualMachineWithContextGroupRef:]):
+ * API/JSWrapperMap.mm:
+ (wrapperFinalize):
+ (makeWrapper): This is our own internal version of JSObjectMake which creates JSAPIWrapperObjects, the Obj-C API
+ version of JSCallbackObjects.
+ (createObjectWithCustomBrand):
+ (-[JSObjCClassInfo wrapperForObject:]):
+ (tryUnwrapObjcObject):
+ * API/JavaScriptCore.h:
+ * API/tests/testapi.mm: Added new tests for the strong and weak uses of JSManagedValue in the context of an
+ onclick handler for an Objective-C object inserted into a JSContext.
+ (-[TextXYZ setWeakOnclick:]):
+ (-[TextXYZ setOnclick:]):
+ (-[TextXYZ weakOnclick]):
+ (-[TextXYZ onclick]):
+ (-[TextXYZ click]):
+ * CMakeLists.txt: Various build system additions.
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSGlobalObject.cpp: Added the new canonical Structure for the JSAPIWrapperObject class.
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::objcWrapperObjectStructure):
+
+2013-03-06 Filip Pizlo <fpizlo@apple.com>
+
+ ConvertThis should be turned into Identity based on predictions in Fixup, rather than based on proofs in ConstantFolding
+ https://bugs.webkit.org/show_bug.cgi?id=111674
+
+ Reviewed by Oliver Hunt.
+
+ This gets rid of the speculated forms of ConvertThis in the backend, and has Fixup
+ convert them to either Identity(Object:@child) if the child is predicted object, or
+ Phantom(Other:@child) ; WeakJSConstant(global this object) if it's predicted Other.
+
+ The goal of this is to ensure that the optimization fixpoint doesn't create
+ Identity's, since doing so requires a rerun of CSE. So far this isn't a speed-up
+ but I'm hoping this will be a step towards reducing the need to rerun the fixpoint
+ so as to ultimately reduce compile times.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGAssemblyHelpers.h:
+ (AssemblyHelpers):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::observeUseKindOnNode):
+ (JSC::DFG::FixupPhase::setUseKindAndUnboxIfProfitable):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::globalThisObjectFor):
+ (Graph):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::convertToIdentity):
+ (JSC::DFG::Node::convertToWeakConstant):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-03-07 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Children method in LLINT AST Not class should return [@child]
+ https://bugs.webkit.org/show_bug.cgi?id=90740
+
+ Reviewed by Filip Pizlo.
+
+ * offlineasm/ast.rb: Fixed the return value of the children method in the Not AST class.
+
+2013-03-05 Oliver Hunt <oliver@apple.com>
+
+ Bring back eager resolution of function scoped variables
+ https://bugs.webkit.org/show_bug.cgi?id=111497
+
+ Reviewed by Geoffrey Garen.
+
+ This reverts the get/put_scoped_var part of the great non-local
+ variable resolution refactoring. This still leaves all the lazy
+ variable resolution logic as it's necessary for global property
+ resolution, and i don't want to make the patch bigger than it
+ already is.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::generateFunctionCodeBlock):
+ (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC):
+ (UnlinkedFunctionExecutable):
+ (UnlinkedCodeBlock):
+ (JSC::UnlinkedCodeBlock::usesGlobalObject):
+ (JSC::UnlinkedCodeBlock::setGlobalObjectRegister):
+ (JSC::UnlinkedCodeBlock::globalObjectRegister):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::ResolveResult::checkValidity):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitLoadGlobalObject):
+ (JSC):
+ (JSC::BytecodeGenerator::resolve):
+ (JSC::BytecodeGenerator::resolveConstDecl):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithThis):
+ (JSC::BytecodeGenerator::emitGetStaticVar):
+ (JSC::BytecodeGenerator::emitPutStaticVar):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::ResolveResult::lexicalResolve):
+ (JSC::ResolveResult::isStatic):
+ (JSC::ResolveResult::depth):
+ (JSC::ResolveResult::index):
+ (ResolveResult):
+ (JSC::ResolveResult::ResolveResult):
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ResolveNode::isPure):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::PostfixNode::emitResolve):
+ (JSC::TypeOfResolveNode::emitBytecode):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::debugFail):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ (JSC::DFG::canInlineOpcode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC):
+ (JSC::JIT::emit_op_put_scoped_var):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC):
+ (JSC::JIT::emit_op_put_scoped_var):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::getProgramCodeBlock):
+ (JSC::CodeCache::getEvalCodeBlock):
+ * runtime/CodeCache.h:
+ (JSC):
+ (CodeCache):
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::FunctionExecutable::produceCodeBlockFor):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::createEvalCodeBlock):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ * runtime/Options.cpp:
+ (JSC::Options::initialize):
+
+2013-03-06 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, roll out http://trac.webkit.org/changeset/144989
+
+ I think we want the assertion that I removed.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::merge):
+ (JSC::DFG::AbstractState::mergeVariableBetweenBlocks):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+
+2013-03-06 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::AbstractState::merge() is still more complicated than it needs to be
+ https://bugs.webkit.org/show_bug.cgi?id=111619
+
+ Reviewed by Mark Hahnenberg.
+
+ This method is the one place where we still do some minimal amount of liveness pruning, but the style with
+ which it is written is awkward, and it makes an assertion about variablesAtTail that will be invalidated
+ by https://bugs.webkit.org/show_bug.cgi?id=111539.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::merge):
+ (JSC::DFG::AbstractState::mergeVariableBetweenBlocks):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+
+2013-03-06 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not run full CSE after the optimization fixpoint, since it really just wants store elimination
+ https://bugs.webkit.org/show_bug.cgi?id=111536
+
+ Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+ The fixpoint will do aggressive load elimination and pure CSE. There's no need to do it after the fixpoint.
+ On the other hand, the fixpoint does not profit from doing store elimination (except for SetLocal/Flush).
+ Previously we had CSE do both, and had it avoid doing some store elimination during the fixpoint by querying
+ the fixpoint state. This changes CSE to be templated on mode - either NormalCSE or StoreElimination - so
+ that we explicitly put it into one of those modes depending on where we call it from. The goal is to reduce
+ time spent doing load elimination after the fixpoint, since that is just wasted cycles.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::CSEPhase):
+ (JSC::DFG::CSEPhase::run):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+ (JSC::DFG::performCSE):
+ (DFG):
+ (JSC::DFG::performStoreElimination):
+ * dfg/DFGCSEPhase.h:
+ (DFG):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+
+2013-03-06 Andreas Kling <akling@apple.com>
+
+ Pack Structure members better.
+ <http://webkit.org/b/111593>
+ <rdar://problem/13359200>
+
+ Reviewed by Mark Hahnenberg.
+
+ Shrink Structure by 8 bytes (now at 104 bytes) on 64-bit by packing the members better.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ * runtime/Structure.h:
+ (Structure):
+
+2013-03-06 Andreas Kling <akling@apple.com>
+
+ Unreviewed, fix Windows build after r144910.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2013-03-05 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not check if nodes are shouldGenerate prior to DCE
+ https://bugs.webkit.org/show_bug.cgi?id=111520
+
+ Reviewed by Geoffrey Garen.
+
+ All nodes are live before DCE. We don't need to check that they aren't, because they
+ definitely will be.
+
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::int32ToDoubleCSE):
+ (JSC::DFG::CSEPhase::constantCSE):
+ (JSC::DFG::CSEPhase::weakConstantCSE):
+ (JSC::DFG::CSEPhase::getCalleeLoadElimination):
+ (JSC::DFG::CSEPhase::getArrayLengthElimination):
+ (JSC::DFG::CSEPhase::globalVarLoadElimination):
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (JSC::DFG::CSEPhase::globalVarWatchpointElimination):
+ (JSC::DFG::CSEPhase::globalVarStoreElimination):
+ (JSC::DFG::CSEPhase::scopedVarStoreElimination):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkStructureElimination):
+ (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+ (JSC::DFG::CSEPhase::putByOffsetStoreElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::checkArrayElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getMyScopeLoadElimination):
+ (JSC::DFG::CSEPhase::getLocalLoadElimination):
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2013-03-06 Csaba Osztrogonác <ossy@webkit.org>
+
+ Fix unused parameter warnings in ARM assembler
+ https://bugs.webkit.org/show_bug.cgi?id=111433
+
+ Reviewed by Kentaro Hara.
+
+ * assembler/ARMAssembler.h: Remove unreachable revertJump() after r143346.
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::moveIntsToDouble): Remove unused scratch parameter instead of UNUSED_PARAM.
+ (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): Remove unused fpTemp parameter.
+ (JSC::MacroAssemblerARM::revertJumpReplacementToPatchableBranchPtrWithPatch): Remove unused parameters.
+
+2013-03-06 Andreas Kling <akling@apple.com>
+
+ Unused Structure property tables waste 14MB on Membuster.
+ <http://webkit.org/b/110854>
+ <rdar://problem/13292104>
+
+ Reviewed by Geoffrey Garen.
+
+ Turn PropertyTable into a GC object and have Structure drop unpinned tables when marking.
+ 14 MB progression on Membuster3.
+
+ This time it should stick; I've been through all the tests with COLLECT_ON_EVERY_ALLOCATION.
+ The issue with the last version was that Structure::m_offset could be used uninitialized
+ when re-materializing a previously GC'd property table, causing some sanity checks to fail.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+
+ Added PropertyTable.cpp.
+
+ * runtime/PropertyTable.cpp: Added.
+ (JSC::PropertyTable::create):
+ (JSC::PropertyTable::clone):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC::PropertyTable::destroy):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::visitChildren):
+
+ Moved marking of property table values here from Structure::visitChildren().
+
+ * runtime/WriteBarrier.h:
+ (JSC::WriteBarrierBase::get):
+
+ Move m_cell to a local before using it multiple times. This avoids a multiple-access race when
+ Structure::checkOffsetConsistency() is used in assertions on the main thread while a marking thread
+ zaps the property table.
+
+ * runtime/Structure.h:
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::propertyTable):
+
+ Added a getter for the Structure's PropertyTable that ASSERTs GC currently isn't active.
+ Because GC can zap an unpinned property table at any time, it's not entirely safe to access it.
+ Renamed the variable itself to m_propertyTableUnsafe to force call sites into explaining themselves.
+
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::checkOffsetConsistency):
+
+ Moved these out of Structure.h to break header dependency cycle between Structure/PropertyTable.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::visitChildren):
+
+ Null out m_propertyTable if the table is unpinned. This'll cause the table to get GC'd.
+
+ (JSC::Structure::takePropertyTableOrCloneIfPinned):
+
+ Added for setting up the property table in a new transition, this code is now shared between
+ addPropertyTransition() and nonPropertyTransition().
+
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+ Add a global propertyTableStructure.
+
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::createStructure):
+ (JSC::PropertyTable::copy):
+
+ Make PropertyTable a GC object.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::dumpStatistics):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::despecifyDictionaryFunction):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::sealTransition):
+ (JSC::Structure::freezeTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::isSealed):
+ (JSC::Structure::isFrozen):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::pin):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::get):
+ (JSC::Structure::despecifyFunction):
+ (JSC::Structure::despecifyAllFunctions):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::remove):
+ (JSC::Structure::createPropertyMap):
+ (JSC::Structure::getPropertyNamesFromStructure):
+ (JSC::Structure::checkConsistency):
+
+2013-03-05 Filip Pizlo <fpizlo@apple.com>
+
+ Get rid of the invert argument to SpeculativeJIT::jumpSlowForUnwantedArrayMode
+ https://bugs.webkit.org/show_bug.cgi?id=105624
+
+ Reviewed by Oliver Hunt.
+
+ All callers pass invert = false, which is the default value of the argument. So, get
+ rid of the argument and fold away all code that checks it.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2013-03-05 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix an incorrect comment. The comment was a holdover from a work-in-progress version of this code.
+
+ * dfg/DFGDCEPhase.cpp:
+ (JSC::DFG::DCEPhase::run):
+
+2013-03-04 Filip Pizlo <fpizlo@apple.com>
+
+ DFG DCE might eliminate checks unsoundly
+ https://bugs.webkit.org/show_bug.cgi?id=109389
+
+ Reviewed by Oliver Hunt.
+
+ This gets rid of all eager reference counting, and does all dead code elimination
+ in one phase - the DCEPhase. This phase also sets up the node reference counts,
+ which are then used not just for DCE but also register allocation and stack slot
+ allocation.
+
+ Doing this required a number of surgical changes in places that previously relied
+ on always having liveness information. For example, the structure check hoisting
+ phase must now consult whether a VariableAccessData is profitable for unboxing to
+ make sure that it doesn't try to do hoisting on set SetLocals. The arguments
+ simplification phase employs its own light-weight liveness analysis. Both phases
+ previously just used reference counts.
+
+ The largest change is that now, dead nodes get turned into Phantoms. Those
+ Phantoms will retain those child edges that are not proven. This ensures that any
+ type checks performed by a dead node remain even after the node is killed. On the
+ other hand, this Phantom conversion means that we need special handling for
+ SetLocal. I decided to make the four forms of SetLocal explicit:
+
+ MovHint(@a, rK): Just indicates that node @a contains the value that would have
+ now been placed into virtual register rK. Does not actually cause @a to be
+ stored into rK. This would have previously been a dead SetLocal with @a
+ being live. MovHints are always dead.
+
+ ZombieHint(rK): Indicates that at this point, register rK will contain a dead
+ value and OSR should put Undefined into it. This would have previously been
+ a dead SetLocal with @a being dead also. ZombieHints are always dead.
+
+ MovHintAndCheck(@a, rK): Identical to MovHint except @a is also type checked,
+ according to whatever UseKind the edge to @a has. The type check is always a
+ forward exit. MovHintAndChecks are always live, since they are
+ NodeMustGenerate. Previously this would have been a dead SetLocal with a
+ live @a, and the check would have disappeared. This is one of the bugs that
+ this patch solves.
+
+ SetLocal(@a, rK): This still does exactly what it does now, if the SetLocal is
+ live.
+
+ Basically this patch makes it so that dead SetLocals eventually decay to MovHint,
+ ZombieHint, or MovHintAndCheck depending on the situation. If the child @a is
+ also dead, then you get a ZombieHint. If the child @a is live but the SetLocal
+ has a type check and @a's type hasn't been proven to have that type then you get
+ a MovHintAndCheck. Otherwise you get a MovHint.
+
+ This is performance neutral.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ (ArgumentsSimplificationPhase):
+ (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
+ * dfg/DFGBasicBlock.h:
+ (BasicBlock):
+ * dfg/DFGBasicBlockInlines.h:
+ (DFG):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (JSC::DFG::ByteCodeParser::insertPhiNode):
+ (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::run):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ * dfg/DFGCPSRethreadingPhase.cpp:
+ (JSC::DFG::CPSRethreadingPhase::run):
+ (JSC::DFG::CPSRethreadingPhase::addPhiSilently):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCommon.cpp:
+ (WTF::printInternal):
+ (WTF):
+ * dfg/DFGCommon.h:
+ (WTF):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+ (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
+ * dfg/DFGDCEPhase.cpp: Added.
+ (DFG):
+ (DCEPhase):
+ (JSC::DFG::DCEPhase::DCEPhase):
+ (JSC::DFG::DCEPhase::run):
+ (JSC::DFG::DCEPhase::findTypeCheckRoot):
+ (JSC::DFG::DCEPhase::countEdge):
+ (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::performDCE):
+ * dfg/DFGDCEPhase.h: Added.
+ (DFG):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ (JSC::DFG::FixupPhase::fixIntEdge):
+ (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
+ (JSC::DFG::FixupPhase::truncateConstantToInt32):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::Graph):
+ (JSC::DFG::Graph::dump):
+ (DFG):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::changeChild):
+ (JSC::DFG::Graph::changeEdge):
+ (JSC::DFG::Graph::compareAndSwap):
+ (JSC::DFG::Graph::clearAndDerefChild):
+ (JSC::DFG::Graph::performSubstitution):
+ (JSC::DFG::Graph::performSubstitutionForEdge):
+ (Graph):
+ (JSC::DFG::Graph::substitute):
+ * dfg/DFGInsertionSet.h:
+ (InsertionSet):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::Node):
+ (JSC::DFG::Node::convertToConstant):
+ (JSC::DFG::Node::convertToGetLocalUnlinked):
+ (JSC::DFG::Node::containsMovHint):
+ (Node):
+ (JSC::DFG::Node::hasVariableAccessData):
+ (JSC::DFG::Node::willHaveCodeGenOrOSR):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ (JSC::DFG::SpeculativeJIT::compileMovHint):
+ (JSC::DFG::SpeculativeJIT::compileMovHintAndCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileInlineStart):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ (JSC::DFG::StructureCheckHoistingPhase::shouldConsiderForHoisting):
+ (StructureCheckHoistingPhase):
+ * dfg/DFGValidate.cpp:
+ (JSC::DFG::Validate::validate):
+
+2013-03-05 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: JSValue should implement init and return nil in exceptional cases
+ https://bugs.webkit.org/show_bug.cgi?id=111487
+
+ Reviewed by Darin Adler.
+
+ * API/JSValue.mm:
+ (-[JSValue init]): We return nil here because there is no way to get the instance into a coherent state
+ without a JSContext.
+ (-[JSValue initWithValue:inContext:]): Similarly, we should also return nil here if either of the arguments is 0.
+
+2013-03-05 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r144708.
+ http://trac.webkit.org/changeset/144708
+ https://bugs.webkit.org/show_bug.cgi?id=111447
+
+ random assertion crashes in inspector tests on qt+mac bots
+ (Requested by kling on #webkit).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::copy):
+ * runtime/PropertyTable.cpp: Removed.
+ * runtime/Structure.cpp:
+ (JSC::Structure::dumpStatistics):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::despecifyDictionaryFunction):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::sealTransition):
+ (JSC::Structure::freezeTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::isSealed):
+ (JSC::Structure::isFrozen):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::pin):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::get):
+ (JSC::Structure::despecifyFunction):
+ (JSC::Structure::despecifyAllFunctions):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::remove):
+ (JSC::Structure::createPropertyMap):
+ (JSC::Structure::getPropertyNamesFromStructure):
+ (JSC::Structure::visitChildren):
+ (JSC::Structure::checkConsistency):
+ * runtime/Structure.h:
+ (JSC):
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+ (JSC::Structure::checkOffsetConsistency):
+ (Structure):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::get):
+ * runtime/WriteBarrier.h:
+ (JSC::WriteBarrierBase::get):
+
+2013-03-05 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX (r144698): Only enable SPEECH_SYNTHESIS for Mac
+ <http://webkit.org/b/106742>
+
+ Fixes the following build failures:
+
+ Undefined symbols for architecture i386:
+ "__ZTVN7WebCore25PlatformSpeechSynthesizerE", referenced from:
+ __ZN7WebCore25PlatformSpeechSynthesizerC2EPNS_31PlatformSpeechSynthesizerClientE in PlatformSpeechSynthesizer.o
+ NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
+ "__ZN7WebCore25PlatformSpeechSynthesizer19initializeVoiceListEv", referenced from:
+ __ZN7WebCore25PlatformSpeechSynthesizerC2EPNS_31PlatformSpeechSynthesizerClientE in PlatformSpeechSynthesizer.o
+ ld: symbol(s) not found for architecture i386
+
+ * Configurations/FeatureDefines.xcconfig:
+ - Fix definition of ENABLE_ENCRYPTED_MEDIA_V2_macosx to match
+ other FeatureDefines.xcconfig files.
+ - Only set ENABLE_SPEECH_SYNTHESIS for the macosx platform.
+
+2013-03-04 Andreas Kling <akling@apple.com>
+
+ Unused Structure property tables waste 14MB on Membuster.
+ <http://webkit.org/b/110854>
+ <rdar://problem/13292104>
+
+ Reviewed by Geoffrey Garen.
+
+ Turn PropertyTable into a GC object and have Structure drop unpinned tables when marking.
+ 14 MB progression on Membuster3.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+
+ Added PropertyTable.cpp.
+
+ * runtime/PropertyTable.cpp: Added.
+ (JSC::PropertyTable::create):
+ (JSC::PropertyTable::clone):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC::PropertyTable::destroy):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::visitChildren):
+
+ Moved marking of property table values here from Structure::visitChildren().
+
+ * runtime/WriteBarrier.h:
+ (JSC::WriteBarrierBase::get):
+
+ Move m_cell to a local before using it multiple times. This avoids a multiple-access race when
+ Structure::checkOffsetConsistency() is used in assertions on the main thread while a marking thread
+ zaps the property table.
+
+ * runtime/Structure.h:
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+ * runtime/StructureInlines.h:
+ (JSC::Structure::propertyTable):
+
+ Added a getter for the Structure's PropertyTable that ASSERTs GC currently isn't active.
+ Because GC can zap an unpinned property table at any time, it's not entirely safe to access it.
+ Renamed the variable itself to m_propertyTableUnsafe to force call sites into explaining themselves.
+
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::checkOffsetConsistency):
+
+ Moved these out of Structure.h to break header dependency cycle between Structure/PropertyTable.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::visitChildren):
+
+ Null out m_propertyTable if the table is unpinned. This'll cause the table to get GC'd.
+
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+ Add a global propertyTableStructure.
+
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::createStructure):
+ (JSC::PropertyTable::copy):
+
+ Make PropertyTable a GC object.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::dumpStatistics):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::despecifyDictionaryFunction):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::sealTransition):
+ (JSC::Structure::freezeTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::isSealed):
+ (JSC::Structure::isFrozen):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::pin):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::get):
+ (JSC::Structure::despecifyFunction):
+ (JSC::Structure::despecifyAllFunctions):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::remove):
+ (JSC::Structure::createPropertyMap):
+ (JSC::Structure::getPropertyNamesFromStructure):
+ (JSC::Structure::checkConsistency):
+
+2013-03-04 Chris Fleizach <cfleizach@apple.com>
+
+ Support WebSpeech - Speech Synthesis
+ https://bugs.webkit.org/show_bug.cgi?id=106742
+
+ Reviewed by Simon Fraser.
+
+ Enable speech synthesis for the Mac.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-03-04 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Remove contextInternalContext from JSContextInternal.h
+ https://bugs.webkit.org/show_bug.cgi?id=111356
+
+ Reviewed by Geoffrey Garen.
+
+ We don't need it any more since we have globalContextRef in JSContext.
+
+ * API/JSContext.mm:
+ * API/JSContextInternal.h:
+ * API/JSValue.mm:
+ (+[JSValue valueWithBool:inContext:]):
+ (+[JSValue valueWithDouble:inContext:]):
+ (+[JSValue valueWithInt32:inContext:]):
+ (+[JSValue valueWithUInt32:inContext:]):
+ (+[JSValue valueWithNewObjectInContext:]):
+ (+[JSValue valueWithNewArrayInContext:]):
+ (+[JSValue valueWithNewRegularExpressionFromPattern:flags:inContext:]):
+ (+[JSValue valueWithNewErrorFromMessage:inContext:]):
+ (+[JSValue valueWithNullInContext:]):
+ (+[JSValue valueWithUndefinedInContext:]):
+ (-[JSValue toBool]):
+ (-[JSValue toDouble]):
+ (-[JSValue toNumber]):
+ (-[JSValue toString]):
+ (-[JSValue toDate]):
+ (-[JSValue toArray]):
+ (-[JSValue toDictionary]):
+ (-[JSValue valueForProperty:]):
+ (-[JSValue setValue:forProperty:]):
+ (-[JSValue deleteProperty:]):
+ (-[JSValue hasProperty:]):
+ (-[JSValue valueAtIndex:]):
+ (-[JSValue setValue:atIndex:]):
+ (-[JSValue isUndefined]):
+ (-[JSValue isNull]):
+ (-[JSValue isBoolean]):
+ (-[JSValue isNumber]):
+ (-[JSValue isString]):
+ (-[JSValue isObject]):
+ (-[JSValue isEqualToObject:]):
+ (-[JSValue isEqualWithTypeCoercionToObject:]):
+ (-[JSValue isInstanceOf:]):
+ (-[JSValue callWithArguments:]):
+ (-[JSValue constructWithArguments:]):
+ (-[JSValue invokeMethod:withArguments:]):
+ (valueToObject):
+ (objectToValueWithoutCopy):
+ (objectToValue):
+ (-[JSValue initWithValue:inContext:]):
+ (-[JSValue dealloc]):
+ (-[JSValue description]):
+ * API/JSWrapperMap.mm:
+ (createObjectWithCustomBrand):
+ (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]):
+ (-[JSObjCClassInfo wrapperForObject:]):
+ (-[JSWrapperMap jsWrapperForObject:]):
+ * API/ObjCCallbackFunction.mm:
+ (ObjCCallbackFunction::call):
+ (objCCallbackFunctionForInvocation):
+
+2013-03-04 Andreas Kling <akling@apple.com>
+
+ Add simple vector traits for JSC::Identifier.
+ <http://webkit.org/b/111323>
+
+ Reviewed by Geoffrey Garen.
+
+ Identifiers are really just Strings, giving them simple vector traits makes
+ Vector move them with memcpy() instead of churning the refcounts.
+
+ * runtime/Identifier.h:
+ (WTF):
+
+2013-03-04 Kunihiko Sakamoto <ksakamoto@chromium.org>
+
+ Add build flag for FontLoader
+ https://bugs.webkit.org/show_bug.cgi?id=111289
+
+ Reviewed by Benjamin Poulain.
+
+ Add ENABLE_FONT_LOAD_EVENTS build flag (disabled by default).
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-03-03 Andreas Kling <akling@apple.com>
+
+ Shrink JSC::HashTable entries.
+ <http://webkit.org/b/111275>
+ <rdar://problem/13333511>
+
+ Reviewed by Anders Carlsson.
+
+ Move the Intrinsic value out of the function-specific part of the union,
+ and store it next to m_attributes. Reduces the size of HashEntry by 8 bytes.
+
+ 990 kB progression on Membuster3. (PTUS: 797 kB)
+
+ * runtime/Lookup.h:
+ (JSC::HashEntry::initialize):
+ (JSC::HashEntry::intrinsic):
+ (HashEntry):
+
+2013-03-01 David Kilzer <ddkilzer@apple.com>
+
+ BUILD FIX: testapi should link to Foundation, not CoreFoundation
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Change testapi to
+ link to Foundation.framework instead of CoreFoundation.framework
+ since it uses NS types.
+
+2013-03-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Passing JS functions to Objective-C callbacks causes JSValue to leak
+ https://bugs.webkit.org/show_bug.cgi?id=107836
+
+ Reviewed by Oliver Hunt.
+
+ We've decided to remove support for this feature from the API because there's no way to automatically manage
+ the memory for clients in a satisfactory manner. Clients can still pass JS functions to Objective-C methods,
+ but the methods must accept plain JSValues instead of Objective-C blocks.
+
+ We now ignore functions that are part of a protocol that inherits from JSExport that accept blocks as arguments.
+
+ * API/JSBlockAdaptor.h: Removed.
+ * API/JSBlockAdaptor.mm: Removed.
+ * API/ObjCCallbackFunction.mm:
+ (ArgumentTypeDelegate::typeBlock): Return nil to signal that we want to ignore this function when copying it
+ to the object from the protocol.
+ * API/tests/testapi.mm: Added a test to make sure that we ignore methods declared as part of a JSExport-ed protocol
+ that have block arguments.
+ (-[TestObject bogusCallback:]):
+ * JavaScriptCore.gypi: Updated build files.
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-03-01 Filip Pizlo <fpizlo@apple.com>
+
+ DFG Branch(LogicalNot) peephole should not try to optimize and work-around the case where LogicalNot may be otherwise live
+ https://bugs.webkit.org/show_bug.cgi?id=111209
+
+ Reviewed by Oliver Hunt.
+
+ Even if it is then everything will work just fine. It's not necessary to check the ref count here.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+
+2013-03-01 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CSE phase shouldn't rely on ref count of nodes, since it doesn't have to
+ https://bugs.webkit.org/show_bug.cgi?id=111205
+
+ Reviewed by Oliver Hunt.
+
+ I don't understand the intuition behind setLocalStoreElimination() validating that the SetLocal's ref count
+ is 1. I believe this is a hold-over from when setLocalStoreElimination() would match one SetLocal to another,
+ and then try to eliminate the first SetLocal. But that's not how it works now. Now, setLocalStoreElimination()
+ is actually Flush elimination: it eliminates any Flush that anchors a SetLocal if it proves that every path
+ from the SetLocal to the Flush is devoid of operations that may observe the local. It doesn't actually kill
+ the SetLocal itself: if the SetLocal is live because of other things (other Flushes or GetLocals in other
+ basic blocks), then the SetLocal will naturally still be alive because th Flush was only keeping the SetLocal
+ alive by one count rather than being solely responsible for its liveness.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ (JSC::DFG::CSEPhase::eliminate):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+
+2013-03-01 Filip Pizlo <fpizlo@apple.com>
+
+ Rename MovHint to MovHintEvent so I can create a NodeType called MovHint
+
+ Rubber stamped by Mark Hahnenberg.
+
+ This is similar to the SetLocal/SetLocalEvent naming scheme, where SetLocal is the
+ NodeType and SetLocalEvent is the VariableEventKind.
+
+ * dfg/DFGVariableEvent.cpp:
+ (JSC::DFG::VariableEvent::dump):
+ * dfg/DFGVariableEvent.h:
+ (JSC::DFG::VariableEvent::movHint):
+ (JSC::DFG::VariableEvent::id):
+ (JSC::DFG::VariableEvent::operand):
+ (VariableEvent):
+ * dfg/DFGVariableEventStream.cpp:
+ (JSC::DFG::VariableEventStream::reconstruct):
+
+2013-03-01 Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+
+ [JSC] Fix sign comparison warning/error after r144340.
+ https://bugs.webkit.org/show_bug.cgi?id=111164
+
+ Reviewed by Mark Hahnenberg.
+
+ gcc (both 4.2.1 and 4.7.2) complain about comparing signed and
+ unsigned terms (clang accepts it just fine).
+
+ Work around that by casting the 1 to an uintptr_t as well.
+
+ * dfg/DFGEdge.h:
+ (JSC::DFG::Edge::makeWord):
+
+2013-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CFA should not do liveness pruning
+ https://bugs.webkit.org/show_bug.cgi?id=111119
+
+ Reviewed by Mark Hahnenberg.
+
+ It adds complexity and probably buys nothing. Moreover, I'm transitioning to having
+ liveness only available at the bitter end of compilation, so this will stop working
+ after https://bugs.webkit.org/show_bug.cgi?id=109389 anyway.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+
+2013-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ Don't try to emit profiling if you don't have the DFG JIT.
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * jit/JIT.h:
+ (JSC::JIT::shouldEmitProfiling):
+
+2013-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ DFG Phantom node should be honest about the fact that it can exit
+ https://bugs.webkit.org/show_bug.cgi?id=111115
+
+ Reviewed by Mark Hahnenberg.
+
+ The chances of this having cause serious issues are low, since most clients of the
+ NodeDoesNotExit flag run after CFA and CFA updates this properly. But one possible
+ case of badness is if the ByteCodeParser inserted a Phantom with a type check in
+ between a LogicalNot and a Branch; then that peephole optimization in Fixup might
+ go slightly wrong.
+
+ * dfg/DFGNodeType.h:
+ (DFG):
+
+2013-02-28 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Add casts in DFGGPRInfo.h to suppress warnings
+ https://bugs.webkit.org/show_bug.cgi?id=111104
+
+ Reviewed by Filip Pizlo.
+
+ With certain flags on, we get compiler warnings on ARM. We should do the proper casts to make these warnings go away.
+
+ * dfg/DFGGPRInfo.h:
+ (JSC::DFG::GPRInfo::toIndex):
+ (JSC::DFG::GPRInfo::debugName):
+
+2013-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ It should be easy to determine if a DFG node exits forward or backward when doing type checks
+ https://bugs.webkit.org/show_bug.cgi?id=111102
+
+ Reviewed by Mark Hahnenberg.
+
+ This adds a NodeExitsForward flag, which tells you the exit directionality of
+ type checks performed by the node. Even if you convert the node to a Phantom
+ and use the Edge UseKind for type checks, you'll still get the same exit
+ directionality that the original node would have wanted.
+
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGArrayifySlowPathGenerator.h:
+ (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+ * dfg/DFGCPSRethreadingPhase.cpp:
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::eliminate):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::checkArray):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::setOpAndDefaultNonExitFlags):
+ (JSC::DFG::Node::convertToPhantom):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::nodeFlagsAsString):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::backwardSpeculationCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ (JSC::DFG::SpeculativeJIT::backwardTypeCheck):
+ (JSC::DFG::SpeculativeJIT::typeCheck):
+ (JSC::DFG::SpeculativeJIT::forwardTypeCheck):
+ (JSC::DFG::SpeculativeJIT::fillStorage):
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateIntegerOperand::gpr):
+ (SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateDoubleOperand::fpr):
+ (SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::gpr):
+ (SpeculateCellOperand):
+ (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
+ (JSC::DFG::SpeculateBooleanOperand::gpr):
+ (SpeculateBooleanOperand):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-28 Filip Pizlo <fpizlo@apple.com>
+
+ CodeBlock::valueProfile() has a bogus assertion
+ https://bugs.webkit.org/show_bug.cgi?id=111106
+ <rdar://problem/13131427>
+
+ Reviewed by Mark Hahnenberg.
+
+ This was just a bad assertion: m_bytecodeOffset == -1 means that the value profile is constructed but not initialized.
+ ValueProfile constructs itself in a safe way; you can call any method you want on a constructed but not initialized
+ ValueProfile. CodeBlock first constructs all ValueProfiles (by growing the ValueProfile vector) and then initializes
+ their m_bytecodeOffset later. This is necessary because the initialization is linking bytecode instructions to their
+ ValueProfiles, so at that point we don't want the ValueProfile vector to resize, which implies that we want all of
+ them to already be constructed. A GC can happen during this phase, and the GC may want to walk all ValueProfiles.
+ This is safe, but one of the ValueProfile getters (CodeBlock::valueProfile()) was asserting that any value profile
+ you get has had its m_bytecodeOffset initialized. This need not be the case and nothing will go wrong if it isn't.
+
+ The solution is to remove the assertion, which I believe was put there to ensure that my m_valueProfiles refactoring
+ a long time ago was sound: it used to be that a ValueProfile with m_bytecodeOffset == -1 was an argument profile; now
+ all argument profiles are in m_argumentValueProfiles instead. I think it's safe to say that this refactoring was done
+ soundly since it was a long time ago. So we should kill the assertion - I don't see an easy way to make the assertion
+ sound with respect to the GC-during-CodeBlock-construction issue, and I don't believe that the assertion is buying us
+ anything at this point.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::valueProfile):
+
+2013-02-27 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CFA should leave behind information in Edge that says if the Edge's type check is proven to succeed
+ https://bugs.webkit.org/show_bug.cgi?id=110840
+
+ Reviewed by Mark Hahnenberg.
+
+ This doesn't add any observable functionality to the compiler, yet. But it does give
+ every phase that runs after CFA the ability to know, in O(1) time, whether an edge
+ will need to execute a type check.
+
+ * dfg/DFGAbstractState.h:
+ (JSC::DFG::AbstractState::filterEdgeByUse):
+ (JSC::DFG::AbstractState::filterByType):
+ * dfg/DFGCommon.cpp:
+ (WTF):
+ (WTF::printInternal):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::isProved):
+ (DFG):
+ (JSC::DFG::proofStatusForIsProved):
+ (WTF):
+ * dfg/DFGEdge.cpp:
+ (JSC::DFG::Edge::dump):
+ * dfg/DFGEdge.h:
+ (JSC::DFG::Edge::Edge):
+ (JSC::DFG::Edge::setNode):
+ (JSC::DFG::Edge::useKindUnchecked):
+ (JSC::DFG::Edge::setUseKind):
+ (Edge):
+ (JSC::DFG::Edge::proofStatusUnchecked):
+ (JSC::DFG::Edge::proofStatus):
+ (JSC::DFG::Edge::setProofStatus):
+ (JSC::DFG::Edge::isProved):
+ (JSC::DFG::Edge::needsCheck):
+ (JSC::DFG::Edge::shift):
+ (JSC::DFG::Edge::makeWord):
+
+2013-02-28 Simon Hausmann <simon.hausmann@digia.com>
+
+ [Qt][Mac] Fix massive parallel builds
+
+ Reviewed by Tor Arne Vestbø.
+
+ There exists a race condition that LLIntDesiredOffsets.h is written to
+ by two parllel instances of the ruby script. This patch ensures that similar to the output file,
+ the generated file is also prefixed according to the build configuration.
+
+ * LLIntOffsetsExtractor.pro:
+
+2013-02-27 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r144168.
+ http://trac.webkit.org/changeset/144168
+ https://bugs.webkit.org/show_bug.cgi?id=111019
+
+ It broke the build and tronical is unavailable (Requested by
+ Ossy_night on #webkit).
+
+ * LLIntOffsetsExtractor.pro:
+
+2013-02-26 Filip Pizlo <fpizlo@apple.com>
+
+ Disable some unsound DFG DCE
+ https://bugs.webkit.org/show_bug.cgi?id=110948
+
+ Reviewed by Michael Saboff.
+
+ DCE of bitops is not sound since the bitops might call some variant of valueOf.
+
+ This used to work right because ValueToInt32 was MustGenerate. From the DFG IR
+ standpoint it feels weird to make ValueToInt32 be MustGenerate since that node is
+ implemented entirely as a pure conversion. If we ever gave the DFG the ability to
+ do effectful bitops, we would most likely implement them as special nodes not
+ related to the ValueToInt32 and bitop nodes we have now.
+
+ This change is performance neutral.
+
+ * dfg/DFGNodeType.h:
+ (DFG):
+
+2013-02-27 Glenn Adams <glenn@skynav.com>
+
+ Add ENABLE_CSS3_TEXT_LINE_BREAK flag.
+ https://bugs.webkit.org/show_bug.cgi?id=110944
+
+ Reviewed by Dean Jackson.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-27 Julien Brianceau <jbrianceau@nds.com>
+
+ Fix build when DFG_JIT is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=110991
+
+ Reviewed by Csaba Osztrogonác.
+
+ * jit/JIT.h:
+ (JSC::JIT::canBeOptimizedOrInlined):
+
+2013-02-27 Simon Hausmann <simon.hausmann@digia.com>
+
+ [Qt][Mac] Fix massive parallel builds
+
+ Reviewed by Tor Arne Vestbø.
+
+ There exists a race condition that LLIntDesiredOffsets.h is written to
+ by two parllel instances of the ruby script. This patch ensures that similar to the output file,
+ the generated file is also prefixed according to the build configuration.
+
+ * LLIntOffsetsExtractor.pro:
+
+2013-02-26 Filip Pizlo <fpizlo@apple.com>
+
+ DFG OSR exit doesn't know which virtual register to use for the last result register for post_inc and post_dec
+ https://bugs.webkit.org/show_bug.cgi?id=109036
+ <rdar://problem/13292139>
+
+ Reviewed by Gavin Barraclough.
+
+ This was a two-fold problem:
+
+ 1) post_inc/dec has two results - the new value of the variable, and the old value of the variable. DFG OSR exit
+ assumed that the "last result" used for the Baseline JIT's register allocation would be the new value. It was
+ wrong in this assumption.
+
+ 2) The Baseline JIT knew to disable its last result optimization in cases where it might confuse the DFG. But it
+ was doing this only for code blocks that could be totally optimized, but not code blocks that could only be
+ optimized when inlined.
+
+ This patch introduces a more rigorous notion of when the Baseline JIT emits profiling, when it does extra work
+ to account for the possibility of OSR exit, and when it does extra work to account for the possibility of OSR
+ entry. These notions are called shouldEmitProfiling(), canBeOptimizedOrInlined(), and canBeOptimized(),
+ respectively.
+
+ This is performance-neutral and fixes the reported bug. It probably fixes other bugs as well, since previously
+ we for example weren't doing the more conservative implementation of op_mov in the Baseline JIT for code blocks
+ that could be inlined but not optimized. So, if such a code block OSR exited at just the right point, you'd get
+ symptoms similar to this bug.
+
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * dfg/DFGCommon.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::JIT::compilePatchGetArrayLength):
+ (JSC::JIT::canBeOptimizedOrInlined):
+ (JIT):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_post_inc):
+ (JSC::JIT::emit_op_post_dec):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emit_op_post_inc):
+ (JSC::JIT::emit_op_post_dec):
+ * jit/JITCall.cpp:
+ (JSC::JIT::emit_op_call_put_result):
+ (JSC::JIT::compileOpCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileOpCall):
+ * jit/JITInlines.h:
+ (JSC::JIT::emitArrayProfilingSite):
+ (JSC::JIT::map):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_mov):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::privateCompilePutByIdTransition):
+
+2013-02-26 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. AppleWin VS2010 build fix.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-02-25 Filip Pizlo <fpizlo@apple.com>
+
+ The DFG backend's and OSR's decision to unbox a variable should be based on whether it's used in a typed context
+ https://bugs.webkit.org/show_bug.cgi?id=110433
+
+ Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+ This introduces the equivalent of a liveness analysis, except for type checking.
+ A variable is said to be "profitable for unboxing" (i.e. live at a type check)
+ if there exists a type check on a GetLocal of that variable, and the type check
+ is consistent with the variable's prediction. Variables that are not profitable
+ for unboxing aren't unboxed. Previously they would have been.
+
+ This is a slight speed-up on some things but mostly neutral.
+
+ * dfg/DFGArgumentPosition.h:
+ (JSC::DFG::ArgumentPosition::ArgumentPosition):
+ (JSC::DFG::ArgumentPosition::mergeShouldNeverUnbox):
+ (JSC::DFG::ArgumentPosition::mergeArgumentPredictionAwareness):
+ (JSC::DFG::ArgumentPosition::mergeArgumentUnboxingAwareness):
+ (ArgumentPosition):
+ (JSC::DFG::ArgumentPosition::isProfitableToUnbox):
+ (JSC::DFG::ArgumentPosition::shouldUseDoubleFormat):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::checkAndSet):
+ (DFG):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::run):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::alwaysUnboxSimplePrimitives):
+ (JSC::DFG::FixupPhase::setUseKindAndUnboxIfProfitable):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+ * dfg/DFGVariableAccessData.h:
+ (JSC::DFG::VariableAccessData::VariableAccessData):
+ (JSC::DFG::VariableAccessData::mergeIsCaptured):
+ (JSC::DFG::VariableAccessData::mergeIsProfitableToUnbox):
+ (VariableAccessData):
+ (JSC::DFG::VariableAccessData::isProfitableToUnbox):
+ (JSC::DFG::VariableAccessData::shouldUnboxIfPossible):
+ (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed):
+ (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias):
+ (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
+ (JSC::DFG::VariableAccessData::mergeFlags):
+
+2013-02-26 Oliver Hunt <oliver@apple.com>
+
+ Fix windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-02-26 Oliver Hunt <oliver@apple.com>
+
+ Web Inspector: REGRESSION: [JSC] SourceProvider reuses IDs
+ https://bugs.webkit.org/show_bug.cgi?id=99674
+
+ Reviewed by Gavin Barraclough.
+
+ Simple incrementing counter for SourceProvider IDs. Uses a
+ lock to incrementing the counter so we don't increment reuse
+ counter values or reassign the ID for a given SourceProvider.
+
+ * parser/SourceProvider.cpp:
+ (JSC::SourceProvider::SourceProvider):
+ (JSC):
+ (JSC::SourceProvider::getID):
+ * parser/SourceProvider.h:
+ (JSC::SourceProvider::asID):
+ (SourceProvider):
+
+2013-02-26 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r144074.
+ http://trac.webkit.org/changeset/144074
+ https://bugs.webkit.org/show_bug.cgi?id=110897
+
+ Causing 20+ crashes on Mac (Requested by bradee-oh on
+ #webkit).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::copy):
+ * runtime/PropertyTable.cpp: Removed.
+ * runtime/Structure.cpp:
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::createPropertyMap):
+ (JSC::Structure::visitChildren):
+ * runtime/Structure.h:
+ (JSC):
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::checkOffsetConsistency):
+ (Structure):
+ * runtime/StructureInlines.h:
+
+2013-02-26 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. AppleWin VS2010 build fix.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorCommon.props:
+
+2013-02-26 Jer Noble <jer.noble@apple.com>
+
+ Unreviewed build fix; use correct macro for platform name in FeatureDefines.xcconfig.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-26 Michael Saboff <msaboff@apple.com>
+
+ Potential crash in YARR JIT generated code when building 64 bit
+ https://bugs.webkit.org/show_bug.cgi?id=110893
+
+ Reviewed by Gavin Barraclough.
+
+ The ABI doesn't define the behavior for the upper bits of a value that takes less than 64 bits.
+ Therefore, we zero extend both the count and length registers to assure that these unsigned values
+ don't have garbage upper bits.
+
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::generateEnter):
+
+2013-02-26 Andreas Kling <akling@apple.com>
+
+ Unused Structure property tables waste 14MB on Membuster.
+ <http://webkit.org/b/110854>
+ <rdar://problem/13292104>
+
+ Reviewed by Filip Pizlo.
+
+ Turn PropertyTable into a GC object and have Structure drop unpinned tables when marking.
+ 14 MB progression on Membuster3.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+
+ Added PropertyTable.cpp.
+
+ * runtime/PropertyTable.cpp: Added.
+ (JSC::PropertyTable::create):
+ (JSC::PropertyTable::clone):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC::PropertyTable::destroy):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::visitChildren):
+
+ Moved marking of property table values here from Structure::visitChildren().
+
+ * runtime/StructureInlines.h:
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::checkOffsetConsistency):
+
+ Moved these to StructureInlines.h to break header dependency cycle between Structure/PropertyTable.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::visitChildren):
+
+ Null out m_propertyTable if the table is unpinned. This'll cause the table to get GC'd.
+
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::createPropertyMap):
+ * runtime/Structure.h:
+ (Structure):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::createStructure):
+ (JSC::PropertyTable::copy):
+
+2013-02-26 Andreas Kling <akling@apple.com>
+
+ Unreviewed, rolling out r144054.
+ http://trac.webkit.org/changeset/144054
+ https://bugs.webkit.org/show_bug.cgi?id=110854
+
+ broke builds
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::copy):
+ * runtime/PropertyTable.cpp: Removed.
+ * runtime/Structure.cpp:
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::createPropertyMap):
+ (JSC::Structure::visitChildren):
+ * runtime/Structure.h:
+ (JSC):
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::checkOffsetConsistency):
+ (Structure):
+ * runtime/StructureInlines.h:
+
+2013-02-26 Andreas Kling <akling@apple.com>
+
+ Unused Structure property tables waste 14MB on Membuster.
+ <http://webkit.org/b/110854>
+ <rdar://problem/13292104>
+
+ Reviewed by Filip Pizlo.
+
+ Turn PropertyTable into a GC object and have Structure drop unpinned tables when marking.
+ 14 MB progression on Membuster3.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+
+ Added PropertyTable.cpp.
+
+ * runtime/PropertyTable.cpp: Added.
+ (JSC::PropertyTable::create):
+ (JSC::PropertyTable::clone):
+ (JSC::PropertyTable::PropertyTable):
+ (JSC::PropertyTable::destroy):
+ (JSC::PropertyTable::~PropertyTable):
+ (JSC::PropertyTable::visitChildren):
+
+ Moved marking of property table values here from Structure::visitChildren().
+
+ * runtime/StructureInlines.h:
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::checkOffsetConsistency):
+
+ Moved these to StructureInlines.h to break header dependency cycle between Structure/PropertyTable.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::visitChildren):
+
+ Null out m_propertyTable if the table is unpinned. This'll cause the table to get GC'd.
+
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::copyPropertyTableForPinning):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::createPropertyMap):
+ * runtime/Structure.h:
+ (Structure):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::createStructure):
+ (JSC::PropertyTable::copy):
+
+2013-02-26 Jocelyn Turcotte <jocelyn.turcotte@digia.com>
+
+ Implement JIT on Windows 64 bits
+ https://bugs.webkit.org/show_bug.cgi?id=107965
+
+ Reviewed by Simon Hausmann.
+
+ 1. MSVC doesn't support inline assembly for 64 bits, implements the trampoline in a separate ASM file.
+
+ 2. Windows 64 bits has a different calling convention than other OSes following the AMD64 ABI.
+ Differences that we have to handle here:
+ - Registers passed parameters are RCX, RDX, R8 and R9 instead of RDI, RSI, RDX, RCX, R8 and R9
+ - RDI and RSI must be preserved by callee
+ - Only return values <= 8 bytes can be returned by register (RDX can't be used to return a second word)
+ - There is no red-zone after RIP on the stack, but instead 4 reserved words before it
+
+ * Target.pri:
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+ (JSC):
+ (JITStackFrame):
+ (JSC::JITStackFrame::returnAddressSlot):
+ * jit/JITStubsMSVC64.asm: Added.
+ * jit/JSInterfaceJIT.h:
+ (JSInterfaceJIT):
+ * jit/ThunkGenerators.cpp:
+ (JSC::nativeForGenerator):
+ * yarr/YarrJIT.cpp:
+ (YarrGenerator):
+ (JSC::Yarr::YarrGenerator::generateEnter):
+ (JSC::Yarr::YarrGenerator::generateReturn):
+
+2013-02-26 Oliver Hunt <oliver@apple.com>
+
+ Kill another analyzer warning in javascriptcore
+ https://bugs.webkit.org/show_bug.cgi?id=110802
+
+ Reviewed by Benjamin Poulain.
+
+ Add null checks.
+
+ * profiler/LegacyProfiler.cpp:
+ (JSC::LegacyProfiler::startProfiling):
+ (JSC::LegacyProfiler::stopProfiling):
+
+2013-02-26 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r144004.
+ http://trac.webkit.org/changeset/144004
+ https://bugs.webkit.org/show_bug.cgi?id=110858
+
+ This iOS change is outdated (Requested by notbenjamin on
+ #webkit).
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitNode):
+ (JSC::BytecodeGenerator::emitNodeInConditionContext):
+ (BytecodeGenerator):
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ * parser/Parser.h:
+ (JSC::Parser::canRecurse):
+ (Parser):
+
+2013-02-25 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION(r143654): some jquery test asserts on 32 bit debug build
+ https://bugs.webkit.org/show_bug.cgi?id=110756
+
+ Reviewed by Geoffrey Garen.
+
+ TypeOf does speculations manually, so it should mark its JSValueOperand as doing ManualOperandSpeculation.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-25 Benjamin Poulain <bpoulain@apple.com>
+
+ [JSC] Upstream iOS Stack bound checking
+ https://bugs.webkit.org/show_bug.cgi?id=110813
+
+ Reviewed by Filip Pizlo.
+
+ On iOS, the StackBounds cannot be cached because the stack
+ can be in one of two threads (the web thread or the UI thread).
+
+ We simply always consider the current stack bound when testing
+ stack boundaries.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitNode):
+ (JSC::BytecodeGenerator::emitNodeInConditionContext):
+ (BytecodeGenerator):
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ * parser/Parser.h:
+ (JSC::Parser::canRecurse):
+ (Parser):
+
+2013-02-25 Michael Saboff <msaboff@apple.com>
+
+ For JSVALUE32_64, maxOffsetRelativeToPatchedStorage() doesn't compute the maximum negative offset
+ https://bugs.webkit.org/show_bug.cgi?id=110828
+
+ Reviewed by Oliver Hunt.
+
+ * runtime/JSObject.h:
+ (JSC::maxOffsetRelativeToPatchedStorage): Only add the OBJECT_OFFSETOF(tag) for positive offsets.
+ That way this function will return the offset farthest from 0 needed to access either the payload
+ or tag.
+
+2013-02-25 Jeffrey Pfau <jpfau@apple.com>
+
+ Optionally partition cache to prevent using cache for tracking
+ https://bugs.webkit.org/show_bug.cgi?id=110269
+
+ Reviewed by Maciej Stachowiak.
+
+ * Configurations/FeatureDefines.xcconfig: Add defines for cache partitioning and public suffix list usage
+
+2013-02-25 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. VS2010 solution build fix.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorCommon.props:
+
+2013-02-24 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::Edge should have more bits for UseKind, and DFG::Allocator should be simpler
+ https://bugs.webkit.org/show_bug.cgi?id=110722
+
+ Reviewed by Oliver Hunt.
+
+ This rolls out the DFG::Allocator part of http://trac.webkit.org/changeset/143654,
+ and changes Edge to have more room for UseKinds and possibly other things.
+
+ This is performance-neutral on both 32-bit and 64-bit. It reduces the size of
+ DFG::Node on 64-bit (by virtue of getting rid of the 16-byte alignment of Node)
+ and increases it slightly on 32-bit (by 4 bytes total - 16-byte alignment led to
+ 80 bytes, but the base size of Node plus the 12 bytes of new m_encodedWords in
+ Edge gets 84 bytes). But, it will mean that we don't have to increase Node by
+ another 16 bytes if we ever want to add more UseKinds or other things to Edge.
+
+ * dfg/DFGAllocator.h:
+ (DFG):
+ (Allocator):
+ (JSC::DFG::Allocator::Region::headerSize):
+ (JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
+ (JSC::DFG::Allocator::Region::data):
+ (JSC::DFG::Allocator::Region::isInThisRegion):
+ (JSC::DFG::::Allocator):
+ (JSC::DFG::::~Allocator):
+ (JSC::DFG::::allocate):
+ (JSC::DFG::::free):
+ (JSC::DFG::::freeAll):
+ (JSC::DFG::::reset):
+ (JSC::DFG::::indexOf):
+ (JSC::DFG::::allocatorOf):
+ (JSC::DFG::::bumpAllocate):
+ (JSC::DFG::::freeListAllocate):
+ (JSC::DFG::::allocateSlow):
+ (JSC::DFG::::freeRegionsStartingAt):
+ (JSC::DFG::::startBumpingIn):
+ * dfg/DFGEdge.h:
+ (JSC::DFG::Edge::Edge):
+ (Edge):
+ (JSC::DFG::Edge::node):
+ (JSC::DFG::Edge::setNode):
+ (JSC::DFG::Edge::useKindUnchecked):
+ (JSC::DFG::Edge::setUseKind):
+ (JSC::DFG::Edge::operator==):
+ (JSC::DFG::Edge::operator!=):
+ (JSC::DFG::Edge::makeWord):
+ * dfg/DFGNodeAllocator.h:
+ (DFG):
+
+2013-02-22 Filip Pizlo <fpizlo@apple.com>
+
+ The DFG special case checks for isCreatedThisArgument are fragile
+ https://bugs.webkit.org/show_bug.cgi?id=110535
+
+ Reviewed by Oliver Hunt.
+
+ There may be many situations in which we want to force a variable to never be
+ unboxed. Capturing is one such case, and the created this argument is another.
+ Previously all code that dealt with this issue had to query both scenarios.
+
+ Now DFG::VariableAccessData knows these things. You just have to ask
+ VariableAccessData for whether a variable should be unboxed. Anyone wishing to
+ force a variable to never be unboxed just tells VariableAccessData.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (DFG):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (CFGSimplificationPhase):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGUnificationPhase.cpp:
+ (JSC::DFG::UnificationPhase::run):
+ * dfg/DFGVariableAccessData.h:
+ (JSC::DFG::VariableAccessData::VariableAccessData):
+ (JSC::DFG::VariableAccessData::mergeIsCaptured):
+ (JSC::DFG::VariableAccessData::mergeShouldNeverUnbox):
+ (VariableAccessData):
+ (JSC::DFG::VariableAccessData::shouldNeverUnbox):
+ (JSC::DFG::VariableAccessData::shouldUnboxIfPossible):
+ (JSC::DFG::VariableAccessData::shouldUseDoubleFormat):
+ (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat):
+
+2013-02-25 Geoffrey Garen <ggaren@apple.com>
+
+ Do one lookup per code cache insertion instead of two
+ https://bugs.webkit.org/show_bug.cgi?id=110674
+
+ Reviewed by Sam Weinig.
+
+ Deployed the idiomatic "add null value" trick to avoid a second hash
+ lookup when inserting an item.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCacheMap::pruneSlowCase): Factored this into a helper function
+ to improve clarity and get some code off the hot path.
+
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode): Use the add() API
+ to avoid two hash lookups. Be sure to remove items if parsing fails,
+ otherwise we'll leave nulls in the table. (I'm guessing that caching parse
+ errors is not a win.)
+
+ * runtime/CodeCache.h:
+ (JSC::SourceCodeValue::SourceCodeValue):
+ (CodeCacheMap):
+ (JSC::CodeCacheMap::add): Combined find() and set() into add().
+
+ (JSC::CodeCacheMap::remove):
+ (JSC::CodeCacheMap::age):
+ (JSC::CodeCacheMap::prune): Refactored to support above changes.
+
+2013-02-25 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ [BlackBerry][ARM] Fix cast-align warnings in JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=110738
+
+ Reviewed by Rob Buis.
+
+ Use reinterpret_cast_ptr instead of reinterpret_cast for
+ pointers.
+
+ * dfg/DFGOperations.cpp:
+ * heap/CopiedBlock.h:
+ (JSC::CopiedBlock::zeroFillWilderness):
+ * heap/WeakBlock.h:
+ (JSC::WeakBlock::asWeakImpl):
+ (JSC::WeakBlock::asFreeCell):
+ (JSC::WeakBlock::weakImpls):
+ * heap/WeakImpl.h:
+ (JSC::WeakImpl::asWeakImpl):
+ * interpreter/JSStack.cpp:
+ (JSC::JSStack::disableErrorStackReserve):
+ * interpreter/JSStack.h:
+ (JSC::JSStack::reservationEnd):
+ * runtime/ArrayStorage.h:
+ (JSC::ArrayStorage::from):
+ * runtime/Butterfly.h:
+ (JSC::Butterfly::indexingPayload):
+ * runtime/IndexingHeader.h:
+ (JSC::IndexingHeader::propertyStorage):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::tearOff):
+ (JSC::JSActivation::isTornOff):
+ (JSC::JSActivation::storage):
+
+2013-02-22 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::SpeculativeJIT::speculateNumber() should just use SpeculateDoubleOperand instead of doing its own thing
+ https://bugs.webkit.org/show_bug.cgi?id=110659
+
+ Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+ This simplifies the code, and also has the effect that if speculateNumber() is called
+ prior to someone actually using the number in a double context, then the number will
+ already be up-converted to double and ready to go.
+
+ Previously if this ever came up, the subsequent use would have to again branch to see
+ if the value is tagged as int or tagged as double.
+
+ On the other hand, if you ever did speculateNumber() and then used the value as a
+ JSValue, this will be a slow down now.
+
+ I suspect that the former (speculateNumber() and then use as number) is more likely
+ than the latter (speculateNumber() and then use as JSValue).
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculateNumber):
+
+2013-02-22 Filip Pizlo <fpizlo@apple.com>
+
+ DFG FixupPhase should have one common hook for knowing if a node is ever being speculated a certain way
+ https://bugs.webkit.org/show_bug.cgi?id=110650
+
+ Reviewed by Mark Hahnenberg.
+
+ Changes almost all calls to edge.setUseKind(kind) to be
+ setUseKindAndUnboxIfProfitable<kind>(edge). This will allow us to use the latter
+ as a hook for deciding which locals to unbox (webkit.org/b/110433).
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::setUseKindAndUnboxIfProfitable):
+ (JSC::DFG::FixupPhase::fixIntEdge):
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+ (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
+
+2013-02-22 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION(r143654): some fast/js test crashes on 32 bit build
+ https://bugs.webkit.org/show_bug.cgi?id=110590
+
+ Reviewed by Mark Hahnenberg.
+
+ In compileValueToInt32, the refactoring in r143654 undid one of the fixes from
+ r143314 due to a merge goof.
+
+ In speculateNumber, we were simply forgetting to indicate that we need a
+ ManualOperandSpeculation on a JSValueOperand. ManualOperandSpeculation should
+ be passed whenever you will be performing the type checks yourself rather than
+ using the operand class to do it for you.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ (JSC::DFG::SpeculativeJIT::speculateNumber):
+
+2013-02-22 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Fix the 32-bit build by using the right data type in more places.
+
+ * runtime/CodeCache.h:
+ (CodeCacheMap):
+
+2013-02-22 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Fix the 32-bit build by using the right data type.
+
+ * runtime/CodeCache.h:
+ (JSC::CodeCacheMap::find):
+
+2013-02-21 Geoffrey Garen <ggaren@apple.com>
+
+ Code cache size should adapt to workload
+ https://bugs.webkit.org/show_bug.cgi?id=110560
+
+ Reviewed by Antti Koivisto.
+
+ (*) 5% PLT arithmetic mean speedup
+ (*) 10% PLT geometric mean speedup
+ (*) 3.4X microbenchmark speedup
+ (*) Reduces initial cache capacity by 16X
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::CodeCache): Updated for interface change.
+
+ * runtime/CodeCache.h:
+ (JSC::SourceCodeValue::SourceCodeValue):
+ (SourceCodeValue): Turned the cache value into a struct so it can track its age.
+
+ (CodeCacheMap):
+ (JSC::CodeCacheMap::CodeCacheMap):
+ (JSC::CodeCacheMap::find):
+ (JSC::CodeCacheMap::set):
+ (JSC::CodeCacheMap::clear):
+ (JSC::CodeCacheMap::pruneIfNeeded):
+ (CodeCache): Grow and shrink in response to usage.
+
+2013-02-21 Jessie Berlin <jberlin@apple.com>
+
+ Fix a typo that broke the 32 bit build.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-21 Michael Saboff <msaboff@apple.com>
+
+ 25-30% regression in V8 RayTrace test in 32 bit builds with JIT disabled
+ https://bugs.webkit.org/show_bug.cgi?id=110539
+
+ Reviewed by Filip Pizlo.
+
+ Change the scale used to lookup pointers in JSGlobalObject::m_specialPointers to be 4 bytes for
+ the 32 bit version of the interpreter.
+
+ * llint/LowLevelInterpreter32_64.asm:
+
+2013-02-21 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Add executable property to cmd file.
+ Required for executable files to maintain their executable permissions over svn.
+
+ * JavaScriptCore.vcxproj/copy-files.cmd: Added property svn:executable.
+
+2013-02-21 Filip Pizlo <fpizlo@apple.com>
+
+ Object allocation profiling will refuse to create objects with more than JSFinalObject::maxInlineCapacity() inline slots, but JSFunction::allocationProfile() asserts that the number of inline slots is always what it asked for
+ https://bugs.webkit.org/show_bug.cgi?id=110519
+ <rdar://problem/13218566>
+
+ Reviewed by Geoffrey Garen.
+
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::allocationProfile):
+
+2013-02-21 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Build fix for VS2010 WebKit solution.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-02-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not change its mind about what type speculations a node does, by encoding the checks in the NodeType, UseKind, and ArrayMode
+ https://bugs.webkit.org/show_bug.cgi?id=109371
+
+ Reviewed by Oliver Hunt.
+
+ FixupPhase now locks in the speculations that each node will do. The DFG then
+ remembers those speculations, and doesn't change its mind about them even if the
+ graph is transformed - for example if a node's child is repointed to a different
+ node as part of CSE, CFG simplification, or folding. Each node ensures that it
+ executes the speculations promised by its edges. This is true even for Phantom
+ nodes.
+
+ This still leaves some craziness on the table for future work, like the
+ elimination of speculating SetLocal's due to CFG simplification
+ (webkit.org/b/109388) and elimination of nodes via DCE (webkit.org/b/109389).
+
+ In all, this allows for a huge simplification of the DFG. Instead of having to
+ execute the right speculation heuristic each time you want to decide what a node
+ does (for example Node::shouldSpeculateInteger(child1, child2) &&
+ node->canSpeculateInteger()), you just ask for the use kinds of its children
+ (typically node->binaryUseKind() == Int32Use). Because the use kinds are
+ discrete, you can often just switch over them. This makes many parts of the code
+ more clear than they were before.
+
+ Having UseKinds describe the speculations being performed also makes it far
+ easier to perform analyses that need to know what speculations are done. This is
+ so far only used to simplify large parts of the CFA.
+
+ To have a larger vocabulary of UseKinds, this also changes the node allocator to
+ be able to round up Node sizes to the nearest multiple of 16.
+
+ This appears to be neutral on benchmarks, except for some goofy speed-ups, like
+ 8% on Octane/box2d.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::startExecuting):
+ (DFG):
+ (JSC::DFG::AbstractState::executeEdges):
+ (JSC::DFG::AbstractState::verifyEdge):
+ (JSC::DFG::AbstractState::verifyEdges):
+ (JSC::DFG::AbstractState::executeEffects):
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ (JSC::DFG::AbstractState::filterEdgeByUse):
+ (JSC::DFG::AbstractState::filterByType):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::filter):
+ * dfg/DFGAdjacencyList.h:
+ (JSC::DFG::AdjacencyList::AdjacencyList):
+ (JSC::DFG::AdjacencyList::child):
+ (JSC::DFG::AdjacencyList::setChild):
+ (JSC::DFG::AdjacencyList::reset):
+ (JSC::DFG::AdjacencyList::firstChild):
+ (JSC::DFG::AdjacencyList::setFirstChild):
+ (JSC::DFG::AdjacencyList::numChildren):
+ (JSC::DFG::AdjacencyList::setNumChildren):
+ (AdjacencyList):
+ * dfg/DFGAllocator.h:
+ (DFG):
+ (Allocator):
+ (JSC::DFG::Allocator::cellSize):
+ (JSC::DFG::Allocator::Region::headerSize):
+ (JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
+ (JSC::DFG::Allocator::Region::payloadSize):
+ (JSC::DFG::Allocator::Region::payloadBegin):
+ (JSC::DFG::Allocator::Region::payloadEnd):
+ (JSC::DFG::Allocator::Region::isInThisRegion):
+ (JSC::DFG::::Allocator):
+ (JSC::DFG::::~Allocator):
+ (JSC::DFG::::allocate):
+ (JSC::DFG::::free):
+ (JSC::DFG::::freeAll):
+ (JSC::DFG::::reset):
+ (JSC::DFG::::indexOf):
+ (JSC::DFG::::allocatorOf):
+ (JSC::DFG::::bumpAllocate):
+ (JSC::DFG::::freeListAllocate):
+ (JSC::DFG::::allocateSlow):
+ (JSC::DFG::::freeRegionsStartingAt):
+ (JSC::DFG::::startBumpingIn):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (JSC::DFG::ByteCodeParser::handleMinMax):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCommon.h:
+ (DFG):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGEdge.cpp:
+ (JSC::DFG::Edge::dump):
+ * dfg/DFGEdge.h:
+ (JSC::DFG::Edge::useKindUnchecked):
+ (JSC::DFG::Edge::useKind):
+ (JSC::DFG::Edge::shift):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::run):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ (JSC::DFG::FixupPhase::fixIntEdge):
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+ (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::truncateConstantToInt32):
+ (JSC::DFG::FixupPhase::truncateConstantsIfNecessary):
+ (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
+ * dfg/DFGGraph.cpp:
+ (DFG):
+ (JSC::DFG::Graph::refChildren):
+ (JSC::DFG::Graph::derefChildren):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::ref):
+ (JSC::DFG::Graph::deref):
+ (JSC::DFG::Graph::performSubstitution):
+ (JSC::DFG::Graph::isPredictedNumerical):
+ (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
+ (DFG):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::Node):
+ (JSC::DFG::Node::convertToGetByOffset):
+ (JSC::DFG::Node::convertToPutByOffset):
+ (JSC::DFG::Node::willHaveCodeGenOrOSR):
+ (JSC::DFG::Node::child1):
+ (JSC::DFG::Node::child2):
+ (JSC::DFG::Node::child3):
+ (JSC::DFG::Node::binaryUseKind):
+ (Node):
+ (JSC::DFG::Node::isBinaryUseKind):
+ * dfg/DFGNodeAllocator.h:
+ (DFG):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::nodeFlagsAsString):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+ (JSC::DFG::SpeculativeJIT::typeCheck):
+ (JSC::DFG::SpeculativeJIT::forwardTypeCheck):
+ (JSC::DFG::SpeculativeJIT::fillStorage):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+ (JSC::DFG::SpeculativeJIT::compileAdd):
+ (JSC::DFG::SpeculativeJIT::compileArithSub):
+ (JSC::DFG::SpeculativeJIT::compileArithNegate):
+ (JSC::DFG::SpeculativeJIT::compileArithMul):
+ (JSC::DFG::SpeculativeJIT::compileArithMod):
+ (JSC::DFG::SpeculativeJIT::compare):
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ (JSC::DFG::SpeculativeJIT::speculateInt32):
+ (JSC::DFG::SpeculativeJIT::speculateNumber):
+ (JSC::DFG::SpeculativeJIT::speculateRealNumber):
+ (JSC::DFG::SpeculativeJIT::speculateBoolean):
+ (JSC::DFG::SpeculativeJIT::speculateCell):
+ (JSC::DFG::SpeculativeJIT::speculateObject):
+ (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
+ (JSC::DFG::SpeculativeJIT::speculateString):
+ (JSC::DFG::SpeculativeJIT::speculateNotCell):
+ (JSC::DFG::SpeculativeJIT::speculateOther):
+ (JSC::DFG::SpeculativeJIT::speculate):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::valueOfNumberConstant):
+ (JSC::DFG::SpeculativeJIT::needsTypeCheck):
+ (JSC::DFG::IntegerOperand::IntegerOperand):
+ (JSC::DFG::IntegerOperand::edge):
+ (IntegerOperand):
+ (JSC::DFG::IntegerOperand::node):
+ (JSC::DFG::IntegerOperand::gpr):
+ (JSC::DFG::IntegerOperand::use):
+ (JSC::DFG::JSValueOperand::JSValueOperand):
+ (JSValueOperand):
+ (JSC::DFG::JSValueOperand::edge):
+ (JSC::DFG::JSValueOperand::node):
+ (JSC::DFG::JSValueOperand::gpr):
+ (JSC::DFG::JSValueOperand::fill):
+ (JSC::DFG::JSValueOperand::use):
+ (JSC::DFG::StorageOperand::StorageOperand):
+ (JSC::DFG::StorageOperand::edge):
+ (StorageOperand):
+ (JSC::DFG::StorageOperand::node):
+ (JSC::DFG::StorageOperand::gpr):
+ (JSC::DFG::StorageOperand::use):
+ (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
+ (SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateIntegerOperand::edge):
+ (JSC::DFG::SpeculateIntegerOperand::node):
+ (JSC::DFG::SpeculateIntegerOperand::gpr):
+ (JSC::DFG::SpeculateIntegerOperand::use):
+ (JSC::DFG::SpeculateStrictInt32Operand::SpeculateStrictInt32Operand):
+ (SpeculateStrictInt32Operand):
+ (JSC::DFG::SpeculateStrictInt32Operand::edge):
+ (JSC::DFG::SpeculateStrictInt32Operand::node):
+ (JSC::DFG::SpeculateStrictInt32Operand::gpr):
+ (JSC::DFG::SpeculateStrictInt32Operand::use):
+ (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
+ (SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateDoubleOperand::edge):
+ (JSC::DFG::SpeculateDoubleOperand::node):
+ (JSC::DFG::SpeculateDoubleOperand::fpr):
+ (JSC::DFG::SpeculateDoubleOperand::use):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::edge):
+ (JSC::DFG::SpeculateCellOperand::node):
+ (JSC::DFG::SpeculateCellOperand::gpr):
+ (JSC::DFG::SpeculateCellOperand::use):
+ (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
+ (JSC::DFG::SpeculateBooleanOperand::edge):
+ (SpeculateBooleanOperand):
+ (JSC::DFG::SpeculateBooleanOperand::node):
+ (JSC::DFG::SpeculateBooleanOperand::gpr):
+ (JSC::DFG::SpeculateBooleanOperand::use):
+ (DFG):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * dfg/DFGUseKind.cpp: Added.
+ (WTF):
+ (WTF::printInternal):
+ * dfg/DFGUseKind.h: Added.
+ (DFG):
+ (JSC::DFG::typeFilterFor):
+ (JSC::DFG::isNumerical):
+ (WTF):
+ * dfg/DFGValidate.cpp:
+ (JSC::DFG::Validate::reportValidationContext):
+
+2013-02-20 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Need a way to use the Objective-C JavaScript API with WebKit
+ https://bugs.webkit.org/show_bug.cgi?id=106059
+
+ Reviewed by Geoffrey Garen.
+
+ * API/JSBase.h: Renamed enable flag for API.
+ * API/JSBlockAdaptor.h: Using new flag.
+ * API/JSBlockAdaptor.mm: Ditto.
+ * API/JSContext.h: Add convenience C API conversion function for JSGlobalContextRef.
+ * API/JSContext.mm:
+ (-[JSContext JSGlobalContextRef]): Implementation of C API convenience function.
+ (-[JSContext initWithVirtualMachine:]): We don't use the m_apiData field any more.
+ (-[JSContext initWithGlobalContextRef:]): init method for allocating new JSContexts given a JSGlobalContextRef.
+ (-[JSContext dealloc]): No more m_apiData.
+ (-[JSContext wrapperForObjCObject:]): Renamed wrapperForObject.
+ (-[JSContext wrapperForJSObject:]): Fetches or allocates the JSValue for the specified JSValueRef in this JSContext.
+ (+[JSContext contextWithGlobalContextRef:]): Helper function to grab the lightweight JSContext wrapper for a given
+ JSGlobalContextRef from the global wrapper cache or allocate a new one if there isn't already one.
+ * API/JSContextInternal.h: New flag, new method declaration for initWithGlobalContextRef.
+ * API/JSExport.h: New flag.
+ * API/JSValue.h: New flag and new C API convenience method.
+ * API/JSValue.mm:
+ (-[JSValue JSValueRef]): Implementation of the C API convenience method.
+ (objectToValueWithoutCopy):
+ (+[JSValue valueWithValue:inContext:]): We now ask the JSContext for an Objective-C JSValue wrapper, which it can cache
+ in its internal JSWrapperMap.
+ * API/JSValueInternal.h:
+ * API/JSVirtualMachine.h:
+ * API/JSVirtualMachine.mm: Added global cache that maps JSContextGroupRef -> JSVirtualMachine lightweight wrappers.
+ (wrapperCacheLock):
+ (initWrapperCache):
+ (+[JSVMWrapperCache addWrapper:forJSContextGroupRef:]):
+ (+[JSVMWrapperCache wrapperForJSContextGroupRef:]):
+ (-[JSVirtualMachine init]):
+ (-[JSVirtualMachine initWithContextGroupRef:]):
+ (-[JSVirtualMachine dealloc]):
+ (+[JSVirtualMachine virtualMachineWithContextGroupRef:]):
+ (-[JSVirtualMachine contextForGlobalContextRef:]):
+ (-[JSVirtualMachine addContext:forGlobalContextRef:]):
+ * API/JSVirtualMachineInternal.h:
+ * API/JSWrapperMap.h:
+ * API/JSWrapperMap.mm:
+ (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]): We use the JSObjectSetPrototype C API call because
+ setting the __proto__ property causes all sorts of bad things to happen behind the scenes, which can cause crashes based on
+ when it gets called.
+ (-[JSWrapperMap initWithContext:]):
+ (-[JSWrapperMap jsWrapperForObject:]):
+ (-[JSWrapperMap objcWrapperForJSValueRef:]):
+ * API/JavaScriptCore.h:
+ * API/ObjCCallbackFunction.h:
+ * API/ObjCCallbackFunction.mm:
+ (ObjCCallbackFunction::ObjCCallbackFunction): We never actually should have retained the target in the case that we had a
+ block as a callback. Blocks are initially allocated on the stack and are only moved to the heap if we call their copy method.
+ Retaining the block on the stack was a bad idea because if that stack frame ever went away and we called the block later,
+ we'd crash and burn.
+ (ObjCCallbackFunction::setContext): We need a new setter for when the weak reference to a JSContext inside an ObjCCallbackFunction
+ disappears, we can allocate a new one in its place.
+ (ObjCCallbackFunction):
+ (objCCallbackFunctionCallAsFunction): Reset the callback's context if it's ever destroyed.
+ (objCCallbackFunctionForInvocation): Again, don't set the __proto__ property because it uses black magic that can cause us to crash
+ depending on when this is called.
+ (objCCallbackFunctionForBlock): Here is where we copy the block to the heap when we're first creating the callback object for it.
+ * API/tests/testapi.c:
+ (main):
+ * API/tests/testapi.mm: We're going to get rid of the automatic block conversion, since that is causing leaks. I changed it
+ here in this test just so that it wouldn't mask any other potential leaks. Also modified some of the tests since JSContexts are
+ just lightweight wrappers now, we're not guaranteed to get the same pointer back from the call to [JSValue context] as the one
+ that the value was created in.
+ (-[TestObject callback:]):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData): No more m_apiData.
+ * runtime/JSGlobalData.h: Ditto.
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject): Ditto.
+ * runtime/JSGlobalObject.h:
+
+2013-02-19 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::SpeculativeJIT::compileInt32ToDouble() has an unnecessary case for constant operands
+ https://bugs.webkit.org/show_bug.cgi?id=110309
+
+ Reviewed by Sam Weinig.
+
+ It used to be necessary, back when we didn't have constant folding. Now we have
+ constant folding. So we don't need it.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+
+2013-02-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG inlines Resolves that it doesn't know how to handle correctly
+ https://bugs.webkit.org/show_bug.cgi?id=110405
+
+ Reviewed by Geoffrey Garen.
+
+ Don't try to be clever: if there's a failing resolve, we can't inline it, period.
+
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineResolveOperations):
+ (JSC::DFG::canInlineOpcode):
+
+2013-02-20 Roger Fong <roger_fong@apple.com>
+
+ Get VS2010 Solution B&I ready.
+ <rdar://problem/1322988>
+
+ Rubberstamped by Timothy Horton.
+
+ Add Production configuration.
+ Add a JavaScriptCore submit solution with a DebugSuffix configuration.
+ Modify JavaScriptCore.make as necessary.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.make: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCore.sln: Removed.
+ * JavaScriptCore.vcxproj/JavaScriptCore.submit.sln: Copied from Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.sln.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorCommon.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorPostBuild.cmd:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorPreBuild.cmd:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorProduction.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorRelease.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreGeneratedProduction.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGeneratedRelease.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreProduction.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreRelease.props:
+ * JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj:
+ * JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj:
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj:
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props:
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props:
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.props: Added.
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props:
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj:
+ * JavaScriptCore.vcxproj/jsc/jscCommon.props:
+ * JavaScriptCore.vcxproj/jsc/jscProduction.props: Added.
+ * JavaScriptCore.vcxproj/jsc/jscRelease.props:
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj:
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props:
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpProduction.props: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpRelease.props:
+ * JavaScriptCore.vcxproj/testapi/testapi.vcxproj:
+ * JavaScriptCore.vcxproj/testapi/testapiCommon.props:
+ * JavaScriptCore.vcxproj/testapi/testapiProduction.props: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiRelease.props:
+
+2013-02-19 Jer Noble <jer.noble@apple.com>
+
+ EME: Enable both ENCRYPTED_MEDIA and ENCRYPTED_MEDIA_V2 until clients transition to the new API.
+ https://bugs.webkit.org/show_bug.cgi?id=110284
+
+ Reviewed by Eric Carlson.
+
+ Re-enable the ENCRYPTED_MEDIA flag.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-20 Dirk Schulze <krit@webkit.org>
+
+ Enable CANVAS_PATH flag
+ https://bugs.webkit.org/show_bug.cgi?id=108508
+
+ Reviewed by Simon Fraser.
+
+ Enable CANVAS_PATH flag on trunk.
+
+ Existing tests cover the feature.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-19 Mark Rowe <mrowe@apple.com>
+
+ Unreviewed, uninteresting change to test a theory about bad dependency handling.
+
+ * API/JSStringRefCF.cpp:
+ (JSStringCreateWithCFString): Remove an unnecessary else clause.
+
+2013-02-19 Oliver Hunt <oliver@apple.com>
+
+ Silence some analyzer warnings
+ https://bugs.webkit.org/show_bug.cgi?id=110281
+
+ Reviewed by Mark Hahnenberg.
+
+ The static analyzer believes that callerCodeBlock can be null,
+ based on other code performing null tests. This should not
+ ever be the case, but we'll add RELEASE_ASSERTs to make it
+ obvious if we're ever wrong.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::getCallerInfo):
+
+2013-02-19 Oliver Hunt <oliver@apple.com>
+
+ Don't force everything to be blinded in debug builds
+ https://bugs.webkit.org/show_bug.cgi?id=110279
+
+ Reviewed by Mark Hahnenberg.
+
+ Switch to an explicit flag for indicating that we want
+ every constant to be blinded.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::shouldBlind):
+
+2013-02-19 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of Opcode.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * bytecode/Opcode.h:
+
+2013-02-19 Filip Pizlo <fpizlo@apple.com>
+
+ Moved PolymorphicAccessStructureList into its own file.
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/Instruction.h:
+ (JSC):
+ * bytecode/PolymorphicAccessStructureList.h: Added.
+ (JSC):
+ (PolymorphicAccessStructureList):
+ (PolymorphicStubInfo):
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::PolymorphicStubInfo):
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+ (JSC::PolymorphicAccessStructureList::visitWeak):
+ * bytecode/StructureStubInfo.h:
+
+2013-02-19 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of Instruction.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * bytecode/Instruction.h:
+
+2013-02-18 Geoffrey Garen <ggaren@apple.com>
+
+ Unreviewed, rolling in r143348.
+ http://trac.webkit.org/changeset/143348
+ https://bugs.webkit.org/show_bug.cgi?id=110242
+
+ The bug was that isEmptyValue() was returning true for the deleted value.
+ Fixed this and simplified things further by delegating to m_sourceCode
+ for both isNull() and isHashTableDeletedValue(), so they can't be out of
+ sync.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/CodeCache.h:
+ (JSC::SourceCodeKey::SourceCodeKey):
+ (JSC::SourceCodeKey::isHashTableDeletedValue):
+ (JSC::SourceCodeKey::hash):
+ (JSC::SourceCodeKey::length):
+ (JSC::SourceCodeKey::isNull):
+ (JSC::SourceCodeKey::operator==):
+ (SourceCodeKey):
+
+2013-02-15 Martin Robinson <mrobinson@igalia.com>
+
+ [GTK] Improve gyp build JavaScriptCore code generation
+ https://bugs.webkit.org/show_bug.cgi?id=109969
+
+ Reviewed by Dirk Pranke.
+
+ Switch away from using DerivedSources.make when building JavaScriptCore generated
+ sources. This bring a couple advantages, such as building the sources in parallel,
+ but requires us to list the generated sources more than once.
+
+ * JavaScriptCore.gyp/JavaScriptCoreGTK.gyp: Add rules for generating JavaScriptCore sources.
+ * JavaScriptCore.gyp/generate-derived-sources.sh: Added.
+ * JavaScriptCore.gyp/redirect-stdout.sh: Added.
+
+2013-02-19 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r143348.
+ http://trac.webkit.org/changeset/143348
+ https://bugs.webkit.org/show_bug.cgi?id=110242
+
+ "Caused a deleted value sentinel crash on the layout tests"
+ (Requested by ggaren on #webkit).
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/CodeCache.h:
+ (JSC::SourceCodeKey::SourceCodeKey):
+ (JSC::SourceCodeKey::isHashTableDeletedValue):
+ (JSC::SourceCodeKey::hash):
+ (JSC::SourceCodeKey::length):
+ (JSC::SourceCodeKey::isNull):
+ (JSC::SourceCodeKey::operator==):
+ (SourceCodeKey):
+
+2013-02-19 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ HeapBlock::destroy should issue warning if result is unused
+ https://bugs.webkit.org/show_bug.cgi?id=110233
+
+ Reviewed by Oliver Hunt.
+
+ To enforce the fact that we need to return blocks to the BlockAllocator after calling destroy,
+ we should add WARN_UNUSED_RETURN to HeapBlock::destroy and any other destroy functions in its subclasses.
+
+ * heap/HeapBlock.h:
+
+2013-02-19 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ WeakSet::removeAllocator leaks WeakBlocks
+ https://bugs.webkit.org/show_bug.cgi?id=110228
+
+ Reviewed by Geoffrey Garen.
+
+ We need to return the WeakBlock to the BlockAllocator after the call to WeakBlock::destroy.
+
+ * heap/WeakSet.cpp:
+ (JSC::WeakSet::removeAllocator):
+
+2013-02-18 Geoffrey Garen <ggaren@apple.com>
+
+ Save space on keys in the CodeCache
+ https://bugs.webkit.org/show_bug.cgi?id=110179
+
+ Reviewed by Oliver Hunt.
+
+ Share the SourceProvider's string instead of making our own copy. This
+ chops off 16MB - 32MB from the CodeCache's memory footprint when full.
+ (It's 16MB when the strings are LChar, and 32MB when they're UChar.)
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/CodeCache.h: Removed a defunct enum value.
+
+ (JSC::SourceCodeKey::SourceCodeKey):
+ (JSC::SourceCodeKey::isHashTableDeletedValue):
+ (SourceCodeKey):
+ (JSC::SourceCodeKey::hash):
+ (JSC::SourceCodeKey::length):
+ (JSC::SourceCodeKey::isNull):
+ (JSC::SourceCodeKey::string):
+ (JSC::SourceCodeKey::operator==): Store a SourceCode instead of a String
+ so we can share our string with our SourceProvider. Cache our hash so
+ we don't have to re-decode our string just to re-hash the table.
+
+2013-02-19 Zoltan Herczeg <zherczeg@webkit.org>
+
+ revertBranchPtrWithPatch is incorrect on ARM traditional
+ https://bugs.webkit.org/show_bug.cgi?id=110201
+
+ Reviewed by Oliver Hunt.
+
+ Revert two instructions back to their original value.
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::revertBranchPtrWithPatch):
+ (ARMAssembler):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::branchPtrWithPatch):
+ (JSC::MacroAssemblerARM::revertJumpReplacementToBranchPtrWithPatch):
+
+2013-02-19 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION(r143241): It made 27 layout tests crash on 32 bit platforms
+ https://bugs.webkit.org/show_bug.cgi?id=110184
+
+ Reviewed by Zoltan Herczeg.
+
+ 32-bit backend was making all sorts of crazy assumptions, which happened to mostly
+ not break things prior to http://trac.webkit.org/changeset/143241. This brings the
+ 32-bit backend's type speculation fully into compliance with what the 64-bit
+ backend does.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+
+2013-02-18 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Unreviewed build fix for Apple Windows. Second stage.
+ Add missed export statement.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-02-18 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-02-18 Darin Adler <darin@apple.com>
+
+ Remove unneeded explicit function template arguments.
+ https://bugs.webkit.org/show_bug.cgi?id=110043
+
+ Reviewed by Ryosuke Niwa.
+
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierASCIIStringTranslator::hash): Let the compiler deduce the type
+ when calling computeHashAndMaskTop8Bits.
+ (JSC::IdentifierLCharFromUCharTranslator::hash): Ditto.
+ * runtime/Identifier.h:
+ (JSC::IdentifierCharBufferTranslator::hash): Ditto.
+2013-02-18 Geoffrey Garen <ggaren@apple.com>
+
+ Shrank the SourceProvider cache
+ https://bugs.webkit.org/show_bug.cgi?id=110158
+
+ Reviewed by Oliver Hunt.
+
+ CodeCache is now our primary source cache, so a long-lived SourceProvider
+ cache is a waste. I measured this as a 10MB Membuster win; with more
+ precise instrumentation, Andreas estimated it as up to 30MB.
+
+ I didn't eliminate the SourceProvider cache because it's still useful
+ in speeding up uncached parsing of scripts with large nested functions
+ (i.e., all scripts).
+
+ * heap/Heap.cpp:
+ (JSC::Heap::collect): Discard all source provider caches after GC. This
+ is a convenient place to do so because it's reasonably soon after initial
+ parsing without being immediate.
+
+ * parser/Parser.cpp:
+ (JSC::::Parser): Updated for interface change: The heap now owns the
+ source provider cache, since most SourceProviders are not expected to
+ have one by default, and the heap is responsible for throwing them away.
+
+ (JSC::::parseInner): No need to update statistics on cache size, since
+ we're going to throw it away no matter what.
+
+ (JSC::::parseFunctionInfo): Reduced the minimum function size to 16. This
+ is a 27% win on a new parsing micro-benchmark I've added. Now that the
+ cache is temporary, we don't have to worry so much about its memory
+ footprint.
+
+ * parser/Parser.h:
+ (Parser): Updated for interface changes.
+
+ * parser/SourceProvider.cpp:
+ (JSC::SourceProvider::SourceProvider):
+ (JSC::SourceProvider::~SourceProvider):
+ * parser/SourceProvider.h:
+ (JSC):
+ (SourceProvider): SourceProvider doesn't own its cache anymore because
+ the cache is temporary.
+
+ * parser/SourceProviderCache.cpp:
+ (JSC::SourceProviderCache::clear):
+ (JSC::SourceProviderCache::add):
+ * parser/SourceProviderCache.h:
+ (JSC::SourceProviderCache::SourceProviderCache):
+ (SourceProviderCache):
+ * parser/SourceProviderCacheItem.h:
+ (SourceProviderCacheItem): No need to update statistics on cache size,
+ since we're going to throw it away no matter what.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::addSourceProviderCache):
+ (JSC):
+ (JSC::JSGlobalData::clearSourceProviderCaches):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSGlobalData): Moved the cache here so it's easier to throw away.
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG backend Branch handling has duplicate code and dead code
+ https://bugs.webkit.org/show_bug.cgi?id=110162
+
+ Reviewed by Mark Hahnenberg.
+
+ Streamline the code, and make the 64 backend's optimizations make more sense
+ (i.e. not be dead code).
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-18 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows] Unreviewed VS2010 build correction after r143273.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Add missing source
+ file SourceProvider.cpp.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in: Add missing exports.
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Structure::flattenDictionaryStructure should compute max offset in a manner that soundly handles the case where the property list becomes empty
+ https://bugs.webkit.org/show_bug.cgi?id=110155
+ <rdar://problem/13233773>
+
+ Reviewed by Mark Rowe.
+
+ This was a rookie mistake. It was doing:
+
+ for (blah) {
+ m_offset = foo // foo's monotonically increase in the loop
+ }
+
+ as a way of computing max offset for all of the properties. Except what if the loop doesn't
+ execute because there are no properties? Well, then, you're going to have a bogus m_offset.
+
+ The solution is to initialize m_offset at the top of the loop.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::flattenDictionaryStructure):
+
+2013-02-18 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ MIPS DFG implementation.
+ https://bugs.webkit.org/show_bug.cgi?id=101328
+
+ Reviewed by Oliver Hunt.
+
+ DFG implementation for MIPS.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::MIPSAssembler):
+ (JSC::MIPSAssembler::sllv):
+ (JSC::MIPSAssembler::movd):
+ (MIPSAssembler):
+ (JSC::MIPSAssembler::negd):
+ (JSC::MIPSAssembler::labelForWatchpoint):
+ (JSC::MIPSAssembler::label):
+ (JSC::MIPSAssembler::vmov):
+ (JSC::MIPSAssembler::linkDirectJump):
+ (JSC::MIPSAssembler::maxJumpReplacementSize):
+ (JSC::MIPSAssembler::revertJumpToMove):
+ (JSC::MIPSAssembler::replaceWithJump):
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::poke):
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::add32):
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::and32):
+ (JSC::MacroAssemblerMIPS::lshift32):
+ (JSC::MacroAssemblerMIPS::mul32):
+ (JSC::MacroAssemblerMIPS::or32):
+ (JSC::MacroAssemblerMIPS::rshift32):
+ (JSC::MacroAssemblerMIPS::urshift32):
+ (JSC::MacroAssemblerMIPS::sub32):
+ (JSC::MacroAssemblerMIPS::xor32):
+ (JSC::MacroAssemblerMIPS::store32):
+ (JSC::MacroAssemblerMIPS::jump):
+ (JSC::MacroAssemblerMIPS::branchAdd32):
+ (JSC::MacroAssemblerMIPS::branchMul32):
+ (JSC::MacroAssemblerMIPS::branchSub32):
+ (JSC::MacroAssemblerMIPS::branchNeg32):
+ (JSC::MacroAssemblerMIPS::call):
+ (JSC::MacroAssemblerMIPS::loadDouble):
+ (JSC::MacroAssemblerMIPS::moveDouble):
+ (JSC::MacroAssemblerMIPS::swapDouble):
+ (JSC::MacroAssemblerMIPS::subDouble):
+ (JSC::MacroAssemblerMIPS::mulDouble):
+ (JSC::MacroAssemblerMIPS::divDouble):
+ (JSC::MacroAssemblerMIPS::negateDouble):
+ (JSC::MacroAssemblerMIPS::branchEqual):
+ (JSC::MacroAssemblerMIPS::branchNotEqual):
+ (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
+ (JSC::MacroAssemblerMIPS::branchTruncateDoubleToUint32):
+ (JSC::MacroAssemblerMIPS::truncateDoubleToInt32):
+ (JSC::MacroAssemblerMIPS::truncateDoubleToUint32):
+ (JSC::MacroAssemblerMIPS::branchDoubleNonZero):
+ (JSC::MacroAssemblerMIPS::branchDoubleZeroOrNaN):
+ (JSC::MacroAssemblerMIPS::invert):
+ (JSC::MacroAssemblerMIPS::replaceWithJump):
+ (JSC::MacroAssemblerMIPS::maxJumpReplacementSize):
+ * dfg/DFGAssemblyHelpers.h:
+ (AssemblyHelpers):
+ (JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
+ (JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
+ (JSC::DFG::AssemblyHelpers::debugCall):
+ * dfg/DFGCCallHelpers.h:
+ (CCallHelpers):
+ (JSC::DFG::CCallHelpers::setupArguments):
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+ * dfg/DFGFPRInfo.h:
+ (DFG):
+ (FPRInfo):
+ (JSC::DFG::FPRInfo::toRegister):
+ (JSC::DFG::FPRInfo::toIndex):
+ (JSC::DFG::FPRInfo::debugName):
+ * dfg/DFGGPRInfo.h:
+ (DFG):
+ (GPRInfo):
+ (JSC::DFG::GPRInfo::toRegister):
+ (JSC::DFG::GPRInfo::toIndex):
+ (JSC::DFG::GPRInfo::debugName):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * jit/JSInterfaceJIT.h:
+ (JSInterfaceJIT):
+ * runtime/JSGlobalData.h:
+ (JSC::ScratchBuffer::allocationSize):
+ (ScratchBuffer):
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::SpeculativeJIT::isKnownXYZ methods should use CFA rather than other things
+ https://bugs.webkit.org/show_bug.cgi?id=110092
+
+ Reviewed by Geoffrey Garen.
+
+ These methods were previously using GenerationInfo and other things to try to
+ gain information that the CFA could give away for free, if you asked kindly
+ enough.
+
+ Also fixed CallLinkStatus's dump() method since it was making an invalid
+ assertion: we most certainly can have a status where the structure is non-null
+ and the executable is null, like if we're dealing with an InternalFunction.
+
+ Also removed calls to isKnownNotXYZ from fillSpeculateABC methods in 32_64. I
+ don't know why that was there. But it was causing asserts if the value was
+ empty - i.e. we had already exited unconditionally but we didn't know it. I
+ could have fixed this by introducing another form of isKnownNotXYZ which was
+ tolerant of empty values, but I didn't feel like fixing code that I knew to be
+ unnecessary. (More deeply, isKnownNotCell, for example, really asks: "do you
+ know that this value can never be a cell?" while some of the previous uses
+ wanted to ask: "do you know that this is a value that is not a cell?". The
+ former is "true" if the value is a contradiction [i.e. BOTTOM], while the
+ latter is "false" for contradictions, since contradictions are not values.)
+
+ * bytecode/CallLinkStatus.cpp:
+ (JSC::CallLinkStatus::dump):
+ * bytecode/CallLinkStatus.h:
+ (JSC::CallLinkStatus::CallLinkStatus):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::isKnownInteger):
+ (JSC::DFG::SpeculativeJIT::isKnownCell):
+ (JSC::DFG::SpeculativeJIT::isKnownNotInteger):
+ (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
+ (JSC::DFG::SpeculativeJIT::isKnownNotCell):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ * dfg/DFGStructureAbstractValue.h:
+ (JSC::DFG::StructureAbstractValue::dump):
+
+2013-02-17 Filip Pizlo <fpizlo@apple.com>
+
+ Get rid of DFG::DoubleOperand and simplify ValueToInt32
+ https://bugs.webkit.org/show_bug.cgi?id=110072
+
+ Reviewed by Geoffrey Garen.
+
+ ValueToInt32 had a side-effecting path, which was not OSR-friendly: an OSR after
+ the side-effect would lead to the side-effect re-executing. I got rid of that path
+ and replaced it with an optimization for the case where the input is speculated
+ number-or-other. This makes idioms like null|0 and true|0 work as expected, and
+ get optimized appropriately.
+
+ Also got rid of DoubleOperand. Replaced all remaining uses of it with
+ SpeculateDoubleOperand. Because the latter asserts that the Edge is a DoubleUse
+ edge and the remaining uses of DoubleOperand are all for untyped uses, I worked
+ around the assertion by setting the UseKind to DoubleUse by force. This is sound,
+ since all existing assertions for DoubleUse are actually asserting that we're not
+ converting a value to double unexpectedly. But all of these calls to
+ SpeculateDoubleOperand are when the operand is already known to be represented as
+ double, so there is no conversion.
+
+ This is neutral on benchmarks, except stanford-crypto-ccm, which speeds up a
+ little. Mostly, this is intended to delete a bunch of code. DoubleOperand was
+ equivalent to the replace-edge-with-DoubleUse trick that I'm using now, except it
+ involved a _lot_ more code.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (DFG):
+ (FPRTemporary):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (DFG):
+
+2013-02-18 Ádám Kallai <kadam@inf.u-szeged.hu>
+
+ [Qt] Mountain Lion buildfix after r143147.
+
+ Reviewed by Csaba Osztrogonác.
+
+ * runtime/DateConstructor.cpp:
+
+2013-02-18 Zan Dobersek <zdobersek@igalia.com>
+
+ Stop placing std::isfinite and std::signbit inside the global scope
+ https://bugs.webkit.org/show_bug.cgi?id=109817
+
+ Reviewed by Darin Adler.
+
+ Prefix calls to the isfinite and signbit methods with std:: as the two
+ methods are no longer being imported into the global scope.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::shouldBlindDouble):
+ * offlineasm/cloop.rb:
+ * runtime/BigInteger.h:
+ (JSC::BigInteger::BigInteger):
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ * runtime/DatePrototype.cpp:
+ (JSC::fillStructuresUsingTimeArgs):
+ (JSC::fillStructuresUsingDateArgs):
+ (JSC::dateProtoFuncToISOString):
+ (JSC::dateProtoFuncSetYear):
+ * runtime/JSCJSValueInlines.h:
+ (JSC::JSValue::JSValue):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncIsFinite):
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::appendStringifiedValue):
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncMax): Also include an opportunistic style fix.
+ (JSC::mathProtoFuncMin): Ditto.
+ * runtime/NumberPrototype.cpp:
+ (JSC::toStringWithRadix):
+ (JSC::numberProtoFuncToExponential):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToPrecision):
+ (JSC::numberProtoFuncToString):
+ * runtime/Uint16WithFraction.h:
+ (JSC::Uint16WithFraction::Uint16WithFraction):
+
+2013-02-18 Ádám Kallai <kadam@inf.u-szeged.hu>
+
+ [Qt] Mountain Lion buildfix after r143147.
+
+ Reviewed by Csaba Osztrogonác.
+
+ * runtime/DateInstance.cpp:
+
+2013-02-18 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Unreviewed speculative build fix for Apple Win bots.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of StructureStubInfo.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * bytecode/StructureStubInfo.h:
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of JSGlobalObject.h and JSGlobalObjectFunctions.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/JSGlobalObject.h:
+ * runtime/JSGlobalObjectFunctions.h:
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indention of Operations.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/Operations.h:
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Remove DFG::SpeculativeJIT::isKnownNumeric(), since it's not called from anywhere.
+
+ Rubber stamped by Andy Estes.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Remove DFG::SpeculativeJIT::isStrictInt32(), since it's not called from anywhere.
+
+ Rubber stampted by Andy Estes.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2013-02-18 Filip Pizlo <fpizlo@apple.com>
+
+ Remove dead code for ValueToNumber from the DFG.
+
+ Rubber stamped by Andy Estes.
+
+ We killed ValueToNumber at some point, but forgot to kill all of the backend support
+ for it.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleMinMax):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ * dfg/DFGSpeculativeJIT64.cpp:
+
+2013-02-17 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed buildfix for JSVALUE32_64 builds after r143147.
+
+ * jit/JIT.h:
+
+2013-02-17 Filip Pizlo <fpizlo@apple.com>
+
+ Move all Structure out-of-line inline methods to StructureInlines.h
+ https://bugs.webkit.org/show_bug.cgi?id=110024
+
+ Rubber stamped by Mark Hahnenberg and Sam Weinig.
+
+ This was supposed to be easy.
+
+ But, initially, there was a Structure inline method in CodeBlock.h, and moving that
+ into StructureInlines.h meant that Operations.h included CodeBlock.h. This would
+ cause WebCore build failures, because CodeBlock.h transitively included the JSC
+ parser (via many, many paths), and the JSC parser defines tokens using enumeration
+ elements that CSSGrammar.cpp (generated by bison) would #define. For example,
+ bison would give CSSGrammar.cpp a #define FUNCTION 123, and would do so before
+ including anything interesting. The JSC parser would have an enum that included
+ FUNCTION as an element. Hence the JSC parser included into CSSGrammar.cpp would have
+ a token element called FUNCTION declared in an enumeration, but FUNCTION was
+ #define'd to 123, leading to a parser error.
+
+ Wow.
+
+ So I removed all transitive include paths from CodeBlock.h to the JSC Parser. I
+ believe I was able to do so without out-of-lining anything interesting or performance
+ critical. This is probably a purely good thing to have done: it will be nice to be
+ able to make changes to the parser without having to compile the universe.
+
+ Of course, doing this caused a bunch of other things to not compile, since a bunch of
+ headers relied on things being implicitly included for them when they transitively
+ included the parser. I fixed a lot of that.
+
+ Finally, I ended up removing the method that depended on CodeBlock.h from
+ StructureInlines.h, and putting it in Structure.cpp. That might seem like all of this
+ was a waste of time, except that I suspect it was a worthwhile forcing function for
+ cleaning up a bunch of cruft.
+
+ * API/JSCallbackFunction.cpp:
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.h:
+ (JSC):
+ * bytecode/EvalCodeCache.h:
+ * bytecode/SamplingTool.h:
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedFunctionExecutable::parameterCount):
+ (JSC):
+ * bytecode/UnlinkedCodeBlock.h:
+ (UnlinkedFunctionExecutable):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/Label.h:
+ (JSC):
+ * dfg/DFGByteCodeParser.cpp:
+ * dfg/DFGByteCodeParser.h:
+ * dfg/DFGFPRInfo.h:
+ * dfg/DFGRegisterBank.h:
+ * heap/HandleStack.cpp:
+ * jit/JITWriteBarrier.h:
+ * parser/Nodes.h:
+ (JSC):
+ * parser/Parser.h:
+ * parser/ParserError.h: Added.
+ (JSC):
+ (JSC::ParserError::ParserError):
+ (ParserError):
+ (JSC::ParserError::toErrorObject):
+ * parser/ParserModes.h:
+ * parser/SourceProvider.cpp: Added.
+ (JSC):
+ (JSC::SourceProvider::SourceProvider):
+ (JSC::SourceProvider::~SourceProvider):
+ * parser/SourceProvider.h:
+ (JSC):
+ (SourceProvider):
+ * runtime/ArrayPrototype.cpp:
+ * runtime/DatePrototype.cpp:
+ * runtime/Executable.h:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObject.h:
+ (JSC):
+ * runtime/Operations.h:
+ * runtime/Structure.cpp:
+ (JSC::Structure::prototypeForLookup):
+ (JSC):
+ * runtime/Structure.h:
+ (JSC):
+ * runtime/StructureInlines.h: Added.
+ (JSC):
+ (JSC::Structure::create):
+ (JSC::Structure::createStructure):
+ (JSC::Structure::get):
+ (JSC::Structure::masqueradesAsUndefined):
+ (JSC::SlotVisitor::internalAppend):
+ (JSC::Structure::transitivelyTransitionedFrom):
+ (JSC::Structure::setEnumerationCache):
+ (JSC::Structure::enumerationCache):
+ (JSC::Structure::prototypeForLookup):
+ (JSC::Structure::prototypeChain):
+ (JSC::Structure::isValid):
+ * runtime/StructureRareData.cpp:
+
+2013-02-17 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Windows build fix.
+
+ * runtime/CodeCache.h:
+ (CodeCacheMap):
+
+2013-02-16 Geoffrey Garen <ggaren@apple.com>
+
+ Code cache should be explicit about what it caches
+ https://bugs.webkit.org/show_bug.cgi?id=110039
+
+ Reviewed by Oliver Hunt.
+
+ This patch makes the code cache more explicit in two ways:
+
+ (1) The cache caches top-level scripts. Any sub-functions executed as a
+ part of a script are cached with it and evicted with it.
+
+ This simplifies things by eliminating out-of-band sub-function tracking,
+ and fixes pathological cases where functions for live scripts would be
+ evicted in favor of functions for dead scripts, and/or high probability
+ functions executed early in script lifetime would be evicted in favor of
+ low probability functions executed late in script lifetime, due to LRU.
+
+ Statistical data from general browsing and PLT confirms that caching
+ functions independently of scripts is not profitable.
+
+ (2) The cache tracks script size, not script count.
+
+ This reduces the worst-case cache size by a factor of infinity.
+
+ Script size is a reasonable first-order estimate of in-memory footprint
+ for a cached script because there are no syntactic constructs that have
+ super-linear memory footprint.
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::generateFunctionCodeBlock): Moved this function out of the cache
+ because it does not consult the cache, and is not managed by it.
+
+ (JSC::UnlinkedFunctionExecutable::visitChildren): Visit our code blocks
+ because they are strong references now, rather than weak, a la (1).
+
+ (JSC::UnlinkedFunctionExecutable::codeBlockFor): Updated for interface changes.
+
+ * bytecode/UnlinkedCodeBlock.h:
+ (UnlinkedFunctionExecutable):
+ (UnlinkedFunctionCodeBlock): Strong now, not weak, a la (1).
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::CodeCache):
+ * runtime/CodeCache.h:
+ (JSC::SourceCodeKey::length):
+ (SourceCodeKey):
+ (CodeCacheMap):
+ (JSC::CodeCacheMap::CodeCacheMap):
+ (JSC::CodeCacheMap::find):
+ (JSC::CodeCacheMap::set):
+ (JSC::CodeCacheMap::clear):
+ (CodeCache):
+ (JSC::CodeCache::clear): Removed individual function tracking, due to (1).
+ Added explicit character counting, for (2).
+
+ You might think 16000000 characters is a lot. It is. But this patch
+ didn't establish that limit -- it just took the existing limit and
+ made it more visible. I intend to reduce the size of the cache in a
+ future patch.
+
+2013-02-16 Filip Pizlo <fpizlo@apple.com>
+
+ Remove support for bytecode comments, since it doesn't build, and hasn't been used in a while.
+ https://bugs.webkit.org/show_bug.cgi?id=110035
+
+ Rubber stamped by Andreas Kling.
+
+ There are other ways of achieving the same effect, like adding print statements to the bytecode generator.
+ The fact that this feature doesn't build and nobody noticed implies that it's probably not a popular
+ feature. As well, the amount of wiring that was required for it was quite big considering its relatively
+ modest utility.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC):
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecode/Comment.h: Removed.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitOpcode):
+ (JSC):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::symbolTable):
+
+2013-02-16 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows] Unreviewed Visual Studio 2010 build fix after r143117
+
+ * JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props: Reference new path to property sheets.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+ Build correction after new operator == added.
+
+2013-02-16 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of Structure.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/Structure.h:
+
+2013-02-16 Christophe Dumez <ch.dumez@sisa.samsung.com>
+
+ Unreviewed build fix.
+
+ Export symbol for new CString operator== operator to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-02-15 Filip Pizlo <fpizlo@apple.com>
+
+ Structure should be more methodical about the relationship between m_offset and m_propertyTable
+ https://bugs.webkit.org/show_bug.cgi?id=109978
+
+ Reviewed by Mark Hahnenberg.
+
+ Allegedly, the previous relationship was that either m_propertyTable or m_offset
+ would be set, and if m_propertyTable was not set you could rebuild it. In reality,
+ we would sometimes "reset" both: some transitions wouldn't set m_offset, and other
+ transitions would clear the previous structure's m_propertyTable. So, in a
+ structure transition chain of A->B->C you could have:
+
+ A transitions to B: B doesn't copy m_offset but does copy m_propertyTable, because
+ that seemed like a good idea at the time (this was a common idiom in the code).
+ B transitions to C: C steals B's m_propertyTable, leaving B with neither a
+ m_propertyTable nor a m_offset.
+
+ Then we would ask for the size of the property storage of B and get the answer
+ "none". That's not good.
+
+ Now, there is a new relationship, which, hopefully, should fix things: m_offset is
+ always set and always refers to the maximum offset ever used by the property table.
+ From this, you can infer both the inline and out-of-line property size, and
+ capacity. This is accomplished by having PropertyTable::add() take a
+ PropertyOffset reference, which must be Structure::m_offset. It will update this
+ offset. As well, all transitions now copy m_offset. And we frequently assert
+ (using RELEASE_ASSERT) that the m_offset matches what m_propertyTable would tell
+ you. Hence if you ever modify the m_propertyTable, you'll also update the offset.
+ If you ever copy the property table, you'll also copy the offset. Life should be
+ good, I think.
+
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyTable::add):
+ * runtime/Structure.cpp:
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::removePropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::attributeChangeTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::sealTransition):
+ (JSC::Structure::freezeTransition):
+ (JSC::Structure::preventExtensionsTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::checkConsistency):
+ (JSC::Structure::putSpecificValue):
+ (JSC::Structure::createPropertyMap):
+ (JSC::PropertyTable::checkConsistency):
+ * runtime/Structure.h:
+ (JSC):
+ (JSC::Structure::putWillGrowOutOfLineStorage):
+ (JSC::Structure::outOfLineCapacity):
+ (JSC::Structure::outOfLineSize):
+ (JSC::Structure::isEmpty):
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+ (Structure):
+ (JSC::Structure::checkOffsetConsistency):
+
+2013-02-15 Martin Robinson <mrobinson@igalia.com>
+
+ [GTK] Spread the gyp build files throughout the tree
+ https://bugs.webkit.org/show_bug.cgi?id=109960
+
+ Reviewed by Dirk Pranke.
+
+ * JavaScriptCore.gyp/JavaScriptCoreGTK.gyp: Renamed from Source/WebKit/gtk/gyp/JavaScriptCore.gyp.
+ * JavaScriptCore.gyp/generate-derived-sources.sh: Renamed from Source/WebKit/gtk/gyp/generate-derived-sources.sh.
+
+2013-02-15 Filip Pizlo <fpizlo@apple.com>
+
+ DFG SpeculativeJIT64 should be more precise about when it's dealing with a cell (even though it probably doesn't matter)
+ https://bugs.webkit.org/show_bug.cgi?id=109625
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-15 Geoffrey Garen <ggaren@apple.com>
+
+ Merged the global function cache into the source code cache
+ https://bugs.webkit.org/show_bug.cgi?id=108660
+
+ Reviewed by Sam Weinig.
+
+ Responding to review comments by Darin Adler.
+
+ * runtime/CodeCache.h:
+ (JSC::SourceCodeKey::SourceCodeKey): Don't initialize m_name and m_flags
+ in the hash table deleted value because they're meaningless.
+
+2013-02-14 Filip Pizlo <fpizlo@apple.com>
+
+ DFG AbstractState should filter operands to NewArray more precisely
+ https://bugs.webkit.org/show_bug.cgi?id=109900
+
+ Reviewed by Mark Hahnenberg.
+
+ NewArray for primitive indexing types speculates that the inputs are the appropriate
+ primitives. Now, the CFA filters the abstract state accordingly, as well.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+
+2013-02-15 Andreas Kling <akling@apple.com>
+
+ Yarr: Use OwnPtr to make pattern/disjunction/character-class ownership clearer.
+ <http://webkit.org/b/109218>
+
+ Reviewed by Benjamin Poulain.
+
+ - Let classes that manage lifetime of other objects hold on to them with OwnPtr instead of raw pointers.
+ - Placed some strategic Vector::shrinkToFit(), ::reserveInitialCapacity() and ::swap().
+
+ 668 kB progression on Membuster3.
+
+ * yarr/YarrInterpreter.cpp:
+ (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternEnd):
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+ (ByteCompiler):
+ * yarr/YarrInterpreter.h:
+ (JSC::Yarr::BytecodePattern::BytecodePattern):
+ (BytecodePattern):
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::opCompileParenthesesSubpattern):
+ (JSC::Yarr::YarrGenerator::opCompileParentheticalAssertion):
+ (JSC::Yarr::YarrGenerator::opCompileBody):
+ * yarr/YarrPattern.cpp:
+ (JSC::Yarr::CharacterClassConstructor::charClass):
+ (JSC::Yarr::YarrPatternConstructor::YarrPatternConstructor):
+ (JSC::Yarr::YarrPatternConstructor::reset):
+ (JSC::Yarr::YarrPatternConstructor::atomPatternCharacter):
+ (JSC::Yarr::YarrPatternConstructor::atomCharacterClassEnd):
+ (JSC::Yarr::YarrPatternConstructor::copyDisjunction):
+ (JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
+ (JSC::Yarr::YarrPatternConstructor::checkForTerminalParentheses):
+ (JSC::Yarr::YarrPatternConstructor::optimizeBOL):
+ (JSC::Yarr::YarrPatternConstructor::containsCapturingTerms):
+ (JSC::Yarr::YarrPatternConstructor::optimizeDotStarWrappedExpressions):
+ * yarr/YarrPattern.h:
+ (JSC::Yarr::PatternDisjunction::addNewAlternative):
+ (PatternDisjunction):
+ (YarrPattern):
+ (JSC::Yarr::YarrPattern::reset):
+ (JSC::Yarr::YarrPattern::newlineCharacterClass):
+ (JSC::Yarr::YarrPattern::digitsCharacterClass):
+ (JSC::Yarr::YarrPattern::spacesCharacterClass):
+ (JSC::Yarr::YarrPattern::wordcharCharacterClass):
+ (JSC::Yarr::YarrPattern::nondigitsCharacterClass):
+ (JSC::Yarr::YarrPattern::nonspacesCharacterClass):
+ (JSC::Yarr::YarrPattern::nonwordcharCharacterClass):
+
+2013-02-14 Geoffrey Garen <ggaren@apple.com>
+
+ Merged the global function cache into the source code cache
+ https://bugs.webkit.org/show_bug.cgi?id=108660
+
+ Reviewed by Sam Weinig.
+
+ This has a few benefits:
+
+ (*) Saves a few kB by removing a second cache data structure.
+
+ (*) Reduces the worst case memory usage of the cache by 1.75X. (Heavy
+ use of 'new Function' and other techniques could cause us to fill
+ both root caches, and they didn't trade off against each other.)
+
+ (*) Paves the way for future improvements based on a non-trivial
+ cache key (for example, shrinkable pointer to the key string, and
+ more precise cache size accounting).
+
+ Also cleaned up the cache implementation and simplified it a bit.
+
+ * heap/Handle.h:
+ (HandleBase):
+ * heap/Strong.h:
+ (Strong): Build!
+
+ * runtime/CodeCache.cpp:
+ (JSC):
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::generateFunctionCodeBlock):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ (JSC::CodeCache::usedFunctionCode): Updated for three interface changes:
+
+ (*) SourceCodeKey is a class, not a pair.
+
+ (*) Table values are abstract pointers, since they can be executables
+ or code blocks. (In a future patch, I'd like to change this so we
+ always store only code blocks. But that's too much for one patch.)
+
+ (*) The cache function is named "set" because it always overwrites
+ unconditionally.
+
+ * runtime/CodeCache.h:
+ (CacheMap):
+ (JSC::CacheMap::find):
+ (JSC::CacheMap::set):
+ (JSC::CacheMap::clear): Added support for specifying hash traits, so we
+ can use a SourceCodeKey.
+
+ Removed side table and random number generator to save space and reduce
+ complexity. Hash tables are already random, so we don't need another source
+ of randomness.
+
+ (SourceCodeKey):
+ (JSC::SourceCodeKey::SourceCodeKey):
+ (JSC::SourceCodeKey::isHashTableDeletedValue):
+ (JSC::SourceCodeKey::hash):
+ (JSC::SourceCodeKey::isNull):
+ (JSC::SourceCodeKey::operator==):
+ (JSC::SourceCodeKeyHash::hash):
+ (JSC::SourceCodeKeyHash::equal):
+ (SourceCodeKeyHash):
+ (SourceCodeKeyHashTraits):
+ (JSC::SourceCodeKeyHashTraits::isEmptyValue): A SourceCodeKey is just a
+ fancy triplet: source code string; function name (or null, for non-functions);
+ and flags. Flags and function name distinguish between functions and programs
+ with identical code, so they can live in the same cache.
+
+ I chose to use the source code string as the primary hashing reference
+ because it's likely to be unique. We can use profiling to choose another
+ technique in future, if collisions between functions and programs prove
+ to be hot. I suspect they won't.
+
+ (JSC::CodeCache::clear):
+ (CodeCache): Removed the second cache.
+
+ * heap/Handle.h:
+ (HandleBase):
+ * heap/Strong.h:
+ (Strong):
+ * runtime/CodeCache.cpp:
+ (JSC):
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::generateFunctionCodeBlock):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ (JSC::CodeCache::usedFunctionCode):
+ * runtime/CodeCache.h:
+ (JSC):
+ (CacheMap):
+ (JSC::CacheMap::find):
+ (JSC::CacheMap::set):
+ (JSC::CacheMap::clear):
+ (SourceCodeKey):
+ (JSC::SourceCodeKey::SourceCodeKey):
+ (JSC::SourceCodeKey::isHashTableDeletedValue):
+ (JSC::SourceCodeKey::hash):
+ (JSC::SourceCodeKey::isNull):
+ (JSC::SourceCodeKey::operator==):
+ (JSC::SourceCodeKeyHash::hash):
+ (JSC::SourceCodeKeyHash::equal):
+ (SourceCodeKeyHash):
+ (SourceCodeKeyHashTraits):
+ (JSC::SourceCodeKeyHashTraits::isEmptyValue):
+ (JSC::CodeCache::clear):
+ (CodeCache):
+
+2013-02-14 Tony Chang <tony@chromium.org>
+
+ Unreviewed, set svn:eol-style native for .sln, .vcproj, and .vsprops files.
+ https://bugs.webkit.org/show_bug.cgi?id=96934
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln: Modified property svn:eol-style.
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Modified property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpCommon.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpDebug.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpDebugAll.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpDebugCairoCFLite.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpProduction.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpRelease.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpReleaseCairoCFLite.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/testRegExp/testRegExpReleasePGO.vsprops: Added property svn:eol-style.
+
+2013-02-14 Tony Chang <tony@chromium.org>
+
+ Unreviewed, set svn:eol-style CRLF for .sln files.
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln: Modified property svn:eol-style.
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Modified property svn:eol-style.
+
+2013-02-14 David Kilzer <ddkilzer@apple.com>
+
+ [Mac] Clean up WARNING_CFLAGS
+ <http://webkit.org/b/109747>
+ <rdar://problem/13208373>
+
+ Reviewed by Mark Rowe.
+
+ * Configurations/Base.xcconfig: Use
+ GCC_WARN_64_TO_32_BIT_CONVERSION to enable and disable
+ -Wshorten-64-to-32 rather than WARNING_CFLAGS.
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln: Modified property svn:eol-style.
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Modified property svn:eol-style.
+
+2013-02-13 Anders Carlsson <andersca@apple.com>
+
+ Better build fix.
+
+ * API/tests/testapi.c:
+ (assertEqualsAsNumber):
+ (main):
+
+2013-02-13 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Build fix.
+
+ * API/tests/testapi.c:
+ (assertEqualsAsNumber):
+ (main):
+
+2013-02-13 Oliver Hunt <oliver@apple.com>
+
+ Yet another build fix
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2013-02-13 Zan Dobersek <zdobersek@igalia.com>
+
+ The 'global isinf/isnan' compiler quirk required when using clang with libstdc++
+ https://bugs.webkit.org/show_bug.cgi?id=109325
+
+ Reviewed by Anders Carlsson.
+
+ Prefix calls to the isinf and isnan methods with std::, declaring we want to use the
+ two methods as they're provided by the C++ standard library being used.
+
+ * API/JSValueRef.cpp:
+ (JSValueMakeNumber):
+ * JSCTypedArrayStubs.h:
+ (JSC):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitLoad):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::constantNaN):
+ * offlineasm/cloop.rb:
+ * runtime/DateConstructor.cpp:
+ (JSC::dateUTC): Also include an opportunistic style fix.
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::calculateGregorianDateTime):
+ (JSC::DateInstance::calculateGregorianDateTimeUTC):
+ * runtime/DatePrototype.cpp:
+ (JSC::dateProtoFuncGetMilliSeconds):
+ (JSC::dateProtoFuncGetUTCMilliseconds):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ * runtime/JSCJSValue.cpp:
+ (JSC::JSValue::toInteger):
+ * runtime/JSDateMath.cpp:
+ (JSC::getUTCOffset):
+ (JSC::parseDateFromNullTerminatedCharacters):
+ (JSC::parseDate):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncIsNaN):
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncMax):
+ (JSC::mathProtoFuncMin):
+ (JSC::mathProtoFuncPow):
+ * runtime/PropertyDescriptor.cpp:
+ (JSC::sameValue):
+
+2013-02-13 Filip Pizlo <fpizlo@apple.com>
+
+ Change another use of (SpecCell & ~SpecString) to SpecObject.
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+
+2013-02-13 Filip Pizlo <fpizlo@apple.com>
+
+ ForwardInt32ToDouble is not in DFG::MinifiedNode's list of relevant node types
+ https://bugs.webkit.org/show_bug.cgi?id=109726
+
+ Reviewed by Mark Hahnenberg.
+
+ If you add it to the list of relevant node types, you also need to make sure
+ it's listed as either hasChild or one of the other kinds. Otherwise you get
+ an assertion. This is causing test failures in run-javascriptcore-tests.
+
+ * dfg/DFGMinifiedNode.h:
+ (JSC::DFG::MinifiedNode::hasChild):
+
+2013-02-13 Oliver Hunt <oliver@apple.com>
+
+ Build fix.
+
+ Rearranged the code somewhat to reduce the number of
+ DFG related ifdefs.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2013-02-13 Filip Pizlo <fpizlo@apple.com>
+
+ ForwardInt32ToDouble is not in DFG::MinifiedNode's list of relevant node types
+ https://bugs.webkit.org/show_bug.cgi?id=109726
+
+ Reviewed by Gavin Barraclough.
+
+ This is asymptomatic because ForwardInt32ToDouble is only used in SetLocals, in
+ which case the value is already stored to the stack. Still, we should fix this.
+
+ * dfg/DFGMinifiedNode.h:
+ (JSC::DFG::belongsInMinifiedGraph):
+
+2013-02-12 Filip Pizlo <fpizlo@apple.com>
+
+ DFG LogicalNot/Branch peephole removal and inversion ignores the possibility of things exiting
+ https://bugs.webkit.org/show_bug.cgi?id=109489
+
+ Reviewed by Mark Hahnenberg.
+
+ If things can exit between the LogicalNot and the Branch then don't peephole.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+
+2013-02-13 Oliver Hunt <oliver@apple.com>
+
+ Remove unnecessary indirection to non-local variable access operations
+ https://bugs.webkit.org/show_bug.cgi?id=109724
+
+ Reviewed by Filip Pizlo.
+
+ Linked bytecode now stores a direct pointer to the resolve operation
+ vectors, so the interpreter no longer needs a bunch of indirection to
+ to perform non-local lookup.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecode/Instruction.h:
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGGraph.h:
+ (ResolveGlobalData):
+ (ResolveOperationData):
+ (PutToBaseOperationData):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC::JIT::emit_op_resolve):
+ (JSC::JIT::emitSlow_op_resolve):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emitSlow_op_resolve_base):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emitSlow_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_put_to_base):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter.asm:
+
+2013-02-13 Zoltan Herczeg <zherczeg@webkit.org>
+
+ replaceWithJump should not decrease the offset by 1 on ARM traditional.
+ https://bugs.webkit.org/show_bug.cgi?id=109689
+
+ Reviewed by Oliver Hunt.
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::replaceWithJump):
+
+2013-02-12 Joseph Pecoraro <pecoraro@apple.com>
+
+ [iOS] Enable PAGE_VISIBILITY_API
+ https://bugs.webkit.org/show_bug.cgi?id=109399
+
+ Reviewed by David Kilzer.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-12 Filip Pizlo <fpizlo@apple.com>
+
+ Renamed SpecObjectMask to SpecObject.
+
+ Rubber stamped by Mark Hahnenberg.
+
+ "SpecObjectMask" is a weird name considering that a bunch of the other speculated
+ types are also masks, but don't have "Mask" in the name.
+
+ * bytecode/SpeculatedType.h:
+ (JSC):
+ (JSC::isObjectSpeculation):
+ (JSC::isObjectOrOtherSpeculation):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+
+2013-02-12 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CFA doesn't filter precisely enough for CompareStrictEq
+ https://bugs.webkit.org/show_bug.cgi?id=109618
+
+ Reviewed by Mark Hahnenberg.
+
+ The backend speculates object for this case, but the CFA was filtering on
+ (SpecCell & ~SpecString) | SpecOther.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+
+2013-02-12 Martin Robinson <mrobinson@igalia.com>
+
+ Fix the gyp build of JavaScriptCore.
+
+ * JavaScriptCore.gypi: Added some missing DFG files to the source list.
+
+2013-02-12 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r142387.
+ http://trac.webkit.org/changeset/142387
+ https://bugs.webkit.org/show_bug.cgi?id=109601
+
+ caused all layout and jscore tests on windows to fail
+ (Requested by kling on #webkit).
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (UnlinkedCodeBlock):
+
+2013-02-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CompareEq optimization should be retuned
+ https://bugs.webkit.org/show_bug.cgi?id=109545
+
+ Reviewed by Mark Hahnenberg.
+
+ - Made the object-to-object equality case work again by hoisting the if statement
+ for it. Previously, object-to-object equality would be compiled as
+ object-to-object-or-other.
+
+ - Added AbstractState guards for most of the type checks that the object equality
+ code uses.
+
+ Looks like a hint of a speed-up on all of the things.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::compare):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+
+2013-02-12 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ JSC asserting with long parameter list functions in debug mode on ARM traditional
+ https://bugs.webkit.org/show_bug.cgi?id=109565
+
+ Reviewed by Zoltan Herczeg.
+
+ Increase the value of sequenceGetByIdSlowCaseInstructionSpace to 80.
+
+ * jit/JIT.h:
+
+2013-02-11 Oliver Hunt <oliver@apple.com>
+
+ Make JSC API more NULL tolerant
+ https://bugs.webkit.org/show_bug.cgi?id=109515
+
+ Reviewed by Mark Hahnenberg.
+
+ We do so much marshalling for the C API these days anyway that a single null
+ check isn't a performance issue. Yet the existing "null is unsafe" behaviour
+ leads to crashes in embedding applications whenever there's an untested code
+ path, so it seems having defined behaviour is superior.
+
+ * API/APICast.h:
+ (toJS):
+ (toJSForGC):
+ * API/JSObjectRef.cpp:
+ (JSObjectIsFunction):
+ (JSObjectCallAsFunction):
+ (JSObjectIsConstructor):
+ (JSObjectCallAsConstructor):
+ * API/tests/testapi.c:
+ (main):
+
+2013-02-11 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, adding a FIXME to remind ourselves of a bug.
+ https://bugs.webkit.org/show_bug.cgi?id=109487
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+
+2013-02-11 Filip Pizlo <fpizlo@apple.com>
+
+ Strange bug in DFG OSR in JSC
+ https://bugs.webkit.org/show_bug.cgi?id=109491
+
+ Reviewed by Mark Hahnenberg.
+
+ Int32ToDouble was being injected after a side-effecting operation and before a SetLocal. Anytime we
+ inject something just before a SetLocal we should be aware that the previous operation may have been
+ a side-effect associated with the current code origin. Hence, we should use a forward exit.
+ Int32ToDouble does not do forward exits by default.
+
+ This patch adds a forward-exiting form of Int32ToDouble, for use in SetLocal Int32ToDouble injections.
+ Changed the CSE and other things to treat these nodes identically, but for the exit strategy to be
+ distinct (Int32ToDouble -> backward, ForwardInt32ToDouble -> forward). The use of the NodeType for
+ signaling exit direction is not "great" but it's what we use in other places already (like
+ ForwardCheckStructure).
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::int32ToDoubleCSE):
+ (CSEPhase):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCommon.h:
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+ (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::willHaveCodeGenOrOSR):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGVariableEventStream.cpp:
+ (JSC::DFG::VariableEventStream::reconstruct):
+
+2013-02-11 Filip Pizlo <fpizlo@apple.com>
+
+ NonStringCell and Object are practically the same thing for the purpose of speculation
+ https://bugs.webkit.org/show_bug.cgi?id=109492
+
+ Reviewed by Mark Hahnenberg.
+
+ Removed isNonStringCellSpeculation, and made all callers use isObjectSpeculation.
+
+ Changed isNonStringCellOrOtherSpeculation to be isObjectOrOtherSpeculation.
+
+ I believe this is correct because even weird object types like JSNotAnObject end up
+ being "objects" from the standpoint of our typesystem. Anyway, the assumption that
+ "is cell but not a string" equates to "object" is an assumption that is already made
+ in other places in the system so there's little value in being paranoid about it.
+
+ * bytecode/SpeculatedType.h:
+ (JSC::isObjectSpeculation):
+ (JSC::isObjectOrOtherSpeculation):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::shouldSpeculateObjectOrOther):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::compare):
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-10 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CompareEq(a, null) and CompareStrictEq(a, const) are unsound with respect to constant folding
+ https://bugs.webkit.org/show_bug.cgi?id=109387
+
+ Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+ Lock in the decision to use a non-speculative constant comparison as early as possible
+ and don't let the CFA change it by folding constants. This might be a performance
+ penalty on some really weird code (FWIW, I haven't seen this on benchmarks), but on
+ the other hand it completely side-steps the unsoundness that the bug speaks of.
+
+ Rolling back in after adding 32-bit path.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::isConstantForCompareStrictEq):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-10 Filip Pizlo <fpizlo@apple.com>
+
+ DFG TypeOf implementation should have its backend code aligned to what the CFA does
+ https://bugs.webkit.org/show_bug.cgi?id=109385
+
+ Reviewed by Sam Weinig.
+
+ The problem was that if we ended up trying to constant fold, but didn't succeed
+ because of prediction mismatches, then we would also fail to do filtration.
+
+ Rearranged the control flow in the CFA to fix that.
+
+ As far as I know, this is asymptomatic - it's sort of OK for the CFA to prove less
+ things, which is what the bug was.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+
+2013-02-11 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r142491.
+ http://trac.webkit.org/changeset/142491
+ https://bugs.webkit.org/show_bug.cgi?id=109470
+
+ broke the 32 bit build (Requested by jessieberlin on #webkit).
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-10 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CompareEq(a, null) and CompareStrictEq(a, const) are unsound with respect to constant folding
+ https://bugs.webkit.org/show_bug.cgi?id=109387
+
+ Reviewed by Oliver Hunt.
+
+ Lock in the decision to use a non-speculative constant comparison as early as possible
+ and don't let the CFA change it by folding constants. This might be a performance
+ penalty on some really weird code (FWIW, I haven't seen this on benchmarks), but on
+ the other hand it completely side-steps the unsoundness that the bug speaks of.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::isConstantForCompareStrictEq):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-11 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed fix after r13954 for !ENABLE(JIT) builds.
+
+ * llint/LowLevelInterpreter.cpp:
+
+2013-02-11 Gabor Rapcsanyi <rgabor@webkit.org>
+
+ JSC build failing with verbose debug mode
+ https://bugs.webkit.org/show_bug.cgi?id=109441
+
+ Reviewed by Darin Adler.
+
+ Fixing some verbose messages which caused build errors.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::eliminate):
+ * dfg/DFGPredictionInjectionPhase.cpp:
+ (JSC::DFG::PredictionInjectionPhase::run):
+
+2013-02-10 Martin Robinson <mrobinson@igalia.com>
+
+ Fix the GTK+ gyp build
+
+ * JavaScriptCore.gypi: Update the source list to accurately
+ reflect what's in the repository and remove the offsets extractor
+ from the list of JavaScriptCore files. It's only used to build
+ the extractor binary.
+
+2013-02-09 Andreas Kling <akling@apple.com>
+
+ Shrink-wrap UnlinkedCodeBlock members.
+ <http://webkit.org/b/109368>
+
+ Reviewed by Oliver Hunt.
+
+ Rearrange the members of UnlinkedCodeBlock to avoid unnecessary padding on 64-bit.
+ Knocks ~600 KB off of the Membuster3 peak.
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (UnlinkedCodeBlock):
+
+2013-02-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should allow phases to break Phi's and then have one phase to rebuild them
+ https://bugs.webkit.org/show_bug.cgi?id=108414
+
+ Reviewed by Mark Hahnenberg.
+
+ Introduces two new DFG forms: LoadStore and ThreadedCPS. These are described in
+ detail in DFGCommon.h.
+
+ Consequently, DFG phases no longer have to worry about preserving data flow
+ links between basic blocks. It is generally always safe to request that the
+ graph be dethreaded (Graph::dethread), which brings it into LoadStore form, where
+ the data flow is implicit. In this form, only liveness-at-head needs to be
+ preserved.
+
+ All of the machinery for "threading" the graph to introduce data flow between
+ blocks is now moved out of the bytecode parser and into the CPSRethreadingPhase.
+ All phases that previously did this maintenance themselves now just rely on
+ being able to dethread the graph. The one exception is the structure check
+ hoising phase, which operates over a threaded graph and preserves it, for the
+ sake of performance.
+
+ Also moved two other things into their own phases: unification (previously found
+ in the parser) and prediction injection (previously found in various places).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/Operands.h:
+ (Operands):
+ (JSC::Operands::sizeFor):
+ (JSC::Operands::atFor):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+ * dfg/DFGAllocator.h:
+ (JSC::DFG::::allocateSlow):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGBasicBlockInlines.h:
+ (DFG):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getLocal):
+ (JSC::DFG::ByteCodeParser::getArgument):
+ (JSC::DFG::ByteCodeParser::flushDirect):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::parse):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::killUnreachable):
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ (CFGSimplificationPhase):
+ (JSC::DFG::CFGSimplificationPhase::fixJettisonedPredecessors):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+ * dfg/DFGCPSRethreadingPhase.cpp: Added.
+ (DFG):
+ (CPSRethreadingPhase):
+ (JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
+ (JSC::DFG::CPSRethreadingPhase::run):
+ (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
+ (JSC::DFG::CPSRethreadingPhase::clearVariablesAtHeadAndTail):
+ (JSC::DFG::CPSRethreadingPhase::addPhiSilently):
+ (JSC::DFG::CPSRethreadingPhase::addPhi):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocal):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeSetLocal):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocal):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeSetArgument):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
+ (JSC::DFG::CPSRethreadingPhase::propagatePhis):
+ (JSC::DFG::CPSRethreadingPhase::PhiStackEntry::PhiStackEntry):
+ (PhiStackEntry):
+ (JSC::DFG::CPSRethreadingPhase::phiStackFor):
+ (JSC::DFG::performCPSRethreading):
+ * dfg/DFGCPSRethreadingPhase.h: Added.
+ (DFG):
+ * dfg/DFGCSEPhase.cpp:
+ (CSEPhase):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCommon.cpp:
+ (WTF):
+ (WTF::printInternal):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::logCompilationChanges):
+ (DFG):
+ (WTF):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::Graph):
+ (JSC::DFG::Graph::dump):
+ (JSC::DFG::Graph::dethread):
+ (JSC::DFG::Graph::collectGarbage):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::performSubstitution):
+ (Graph):
+ (JSC::DFG::Graph::performSubstitutionForEdge):
+ (JSC::DFG::Graph::convertToConstant):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::convertToPhantomLocal):
+ (Node):
+ (JSC::DFG::Node::convertToGetLocal):
+ (JSC::DFG::Node::hasVariableAccessData):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPhase.cpp:
+ (JSC::DFG::Phase::beginPhase):
+ * dfg/DFGPhase.h:
+ (JSC::DFG::runAndLog):
+ * dfg/DFGPredictionInjectionPhase.cpp: Added.
+ (DFG):
+ (PredictionInjectionPhase):
+ (JSC::DFG::PredictionInjectionPhase::PredictionInjectionPhase):
+ (JSC::DFG::PredictionInjectionPhase::run):
+ (JSC::DFG::performPredictionInjection):
+ * dfg/DFGPredictionInjectionPhase.h: Added.
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::run):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * dfg/DFGUnificationPhase.cpp: Added.
+ (DFG):
+ (UnificationPhase):
+ (JSC::DFG::UnificationPhase::UnificationPhase):
+ (JSC::DFG::UnificationPhase::run):
+ (JSC::DFG::performUnification):
+ * dfg/DFGUnificationPhase.h: Added.
+ (DFG):
+ * dfg/DFGValidate.cpp:
+ (JSC::DFG::Validate::validate):
+ (JSC::DFG::Validate::dumpGraphIfAppropriate):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ (JSC::DFG::VirtualRegisterAllocationPhase::run):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::setUpCall):
+ * runtime/JSCJSValue.cpp:
+ (JSC::JSValue::dump):
+ * runtime/JSString.h:
+ (JSString):
+ * runtime/Options.h:
+ (JSC):
+
+2013-02-08 Jer Noble <jer.noble@apple.com>
+
+ Bring WebKit up to speed with latest Encrypted Media spec.
+ https://bugs.webkit.org/show_bug.cgi?id=97037
+
+ Reviewed by Eric Carlson.
+
+ Define the ENABLE_ENCRYPTED_MEDIA_V2 setting.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Objective-C API for JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=105889
+
+ Reviewed by Joseph Pecoraro
+
+ Following up on review comments, mostly typos.
+
+ * API/JSBlockAdaptor.h:
+ * API/JSBlockAdaptor.mm:
+ (-[JSBlockAdaptor blockFromValue:inContext:withException:]):
+ * API/JSContext.h:
+ * API/JSExport.h:
+ * API/JSValue.h:
+ * API/JSValue.mm:
+ * API/JSWrapperMap.mm:
+ (selectorToPropertyName):
+ (-[JSWrapperMap classInfoForClass:]):
+ (-[JSWrapperMap wrapperForObject:]):
+
+2013-02-08 Martin Robinson <mrobinson@igalia.com>
+
+ [GTK] Add an experimental gyp build
+ https://bugs.webkit.org/show_bug.cgi?id=109003
+
+ Reviewed by Gustavo Noronha Silva.
+
+ * JavaScriptCore.gypi: Update the list of source files to include those
+ necessary for the GTK+ build.
+
+2013-02-08 Andreas Kling <akling@apple.com>
+
+ JSC: Lower minimum PropertyTable size.
+ <http://webkit.org/b/109247>
+
+ Reviewed by Darin Adler.
+
+ Lower the minimum table size for PropertyTable from 16 to 8.
+ 3.32 MB progression on Membuster3 (a ~13% reduction in memory used by PropertyTables.)
+
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable):
+ (JSC::PropertyTable::sizeForCapacity):
+
+2013-02-07 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. More VS2010 WebKit solution touchups.
+ Make JavaScriptCoreExports.def.in be treated as a custom build file so that changes to it cause the exports to be rebuilt.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
+
+2013-02-07 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: testapi.mm should use ARC
+ https://bugs.webkit.org/show_bug.cgi?id=107838
+
+ Reviewed by Mark Rowe.
+
+ Removing the changes to the Xcode project file and moving the equivalent flags into
+ the ToolExecutable xcconfig file.
+
+ * Configurations/ToolExecutable.xcconfig:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-02-07 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows] Unreviewed Visual Studio 2010 build fixes after r142179.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in: Correct changed symbols
+ * JavaScriptCore.vcxproj/JavaScriptCoreExports.def: Removed autogenerated file.
+
+2013-02-05 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::ByteCodeParser should do surgical constant folding to reduce load on the optimization fixpoint
+ https://bugs.webkit.org/show_bug.cgi?id=109000
+
+ Reviewed by Oliver Hunt.
+
+ Previously our source parser's ASTBuilder did some surgical constant folding, but it
+ didn't cover some cases. It was particularly incapable of doing constant folding for
+ cases where we do some minimal loop peeling in the bytecode generator - since it
+ didn't "see" those constants prior to the peeling. Example:
+
+ for (var i = 0; i < 4; ++i)
+ things;
+
+ This will get peeled just a bit by the bytecode generator, so that the "i < 4" is
+ duplicated both at the top of the loop and the bottom. This means that we have a
+ constant comparison: "0 < 4", which the bytecode generator emits without any further
+ thought.
+
+ The DFG optimization fixpoint of course folds this and simplifies the CFG
+ accordingly, but this incurs a compile-time cost. The purpose of this change is to
+ do some surgical constant folding in the DFG's bytecode parser, so that such
+ constructs reduce load on the CFG simplifier and the optimization fixpoint. The goal
+ is not to cover all cases, since the DFG CFA and CFG simplifier have a powerful
+ sparse conditional constant propagation that we can always fall back on. Instead the
+ goal is to cover enough cases that for common small functions we don't have to
+ perform such transformations, thereby reducing compile times.
+
+ This also refactors m_inlineStackEntry->m_inlineCallFrame to be a handy method call
+ and also adds the notion of a TriState-based JSValue::pureToBoolean(). Both of these
+ things are used by the folder.
+
+ As well, care has been taken to make sure that the bytecode parser only does folding
+ that is statically provable, and that doesn't arise out of speculation. This means
+ we cannot fold on data flow that crosses inlining boundaries. On the other hand, the
+ folding that the bytecode parser uses doesn't require phantoming anything. Such is
+ the trade-off: for anything that we do need phantoming, we defer it to the
+ optimization fixpoint.
+
+ Slight SunSpider speed-up.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::get):
+ (JSC::DFG::ByteCodeParser::getLocal):
+ (JSC::DFG::ByteCodeParser::setLocal):
+ (JSC::DFG::ByteCodeParser::flushDirect):
+ (JSC::DFG::ByteCodeParser::flushArgumentsAndCapturedVariables):
+ (JSC::DFG::ByteCodeParser::toInt32):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::inlineCallFrame):
+ (JSC::DFG::ByteCodeParser::currentCodeOrigin):
+ (JSC::DFG::ByteCodeParser::canFold):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::getScope):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::isStronglyProvedConstantIn):
+ (Node):
+ * runtime/JSCJSValue.h:
+ * runtime/JSCJSValueInlines.h:
+ (JSC::JSValue::pureToBoolean):
+ (JSC):
+
+2013-02-07 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Invalid code is generated for storing constants with baseindex addressing modes on ARM traditional.
+ https://bugs.webkit.org/show_bug.cgi?id=109050
+
+ Reviewed by Oliver Hunt.
+
+ The S! scratch register is reused, but it should contain the constant value.
+
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::baseIndexTransfer32):
+ (JSC::ARMAssembler::baseIndexTransfer16):
+
+2013-02-07 Andras Becsi <andras.becsi@digia.com>
+
+ [Qt] Use GNU ar's thin archive format for intermediate static libs
+ https://bugs.webkit.org/show_bug.cgi?id=109052
+
+ Reviewed by Jocelyn Turcotte.
+
+ Adjust project files that used activeBuildConfig()
+ to use targetSubDir().
+
+ * JavaScriptCore.pri:
+ * LLIntOffsetsExtractor.pro:
+ * Target.pri:
+
+2013-02-06 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Touchups to VS2010 WebKit solution.
+ Fix an export generator script, modify some property sheets, add resouce file.
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorDebug.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorPostBuild.cmd:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorRelease.props:
+ * JavaScriptCore.vcxproj/resource.h: Added.
+
+2013-02-06 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Web Inspector: Native Memory Instrumentation: assign class name to the heap graph node automatically
+ https://bugs.webkit.org/show_bug.cgi?id=107262
+
+ Reviewed by Yury Semikhatsky.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-02-06 Mike West <mkwst@chromium.org>
+
+ Add an ENABLE_NOSNIFF feature flag.
+ https://bugs.webkit.org/show_bug.cgi?id=109029
+
+ Reviewed by Jochen Eisinger.
+
+ This new flag will control the behavior of 'X-Content-Type-Options: nosniff'
+ when processing script and other resource types.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-02-05 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ put_to_base should emit a Phantom for "value" across the ForceOSRExit
+ https://bugs.webkit.org/show_bug.cgi?id=108998
+
+ Reviewed by Oliver Hunt.
+
+ Otherwise, the OSR exit compiler could clobber it, which would lead to badness.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::tallyFrequentExitSites): Build fixes for when DFG debug logging is enabled.
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock): Added extra Phantoms for the "value" field where needed.
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Ditto.
+
+2013-02-05 Michael Saboff <msaboff@apple.com>
+
+ Crash at JSC::call when loading www.gap.com with JSVALUE32_64 Enabled
+ https://bugs.webkit.org/show_bug.cgi?id=108991
+
+ Reviewed by Oliver Hunt.
+
+ Changed the restoration from calleeGPR to nonArgGPR0 because the restoration of the return location
+ may step on calleeGPR is it happen to be nonArgGPR2.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::dfgLinkClosureCall):
+
+2013-02-05 Roger Fong <roger_fong@apple.com>
+
+ Add a JavaScriptCore Export Generator project.
+ https://bugs.webkit.org/show_bug.cgi?id=108971.
+
+ Reviewed by Brent Fulgham.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.sln:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj.filters: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGenerator.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorBuildCmd.cmd: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorCommon.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorDebug.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorPostBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorPreBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExportGeneratorRelease.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in: Added.
+
+2013-02-04 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should have a precise view of jump targets
+ https://bugs.webkit.org/show_bug.cgi?id=108868
+
+ Reviewed by Oliver Hunt.
+
+ Previously, the DFG relied entirely on the CodeBlock's jump targets list for
+ determining when to break basic blocks. This worked great, except sometimes it
+ would be too conservative since the CodeBlock just says where the bytecode
+ generator inserted labels.
+
+ This change keeps the old jump target list in CodeBlock since it is still
+ valuable to the baseline JIT, but switches the DFG to use its own jump target
+ calculator. This ought to reduce pressure on the DFG simplifier, which would
+ previously do a lot of work to try to merge redundantly created basic blocks.
+ It appears to be a 1% progression on SunSpider.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/PreciseJumpTargets.cpp: Added.
+ (JSC):
+ (JSC::addSimpleSwitchTargets):
+ (JSC::computePreciseJumpTargets):
+ * bytecode/PreciseJumpTargets.h: Added.
+ (JSC):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+
+2013-02-01 Roger Fong <roger_fong@apple.com>
+
+ Make ConfigurationBuildDir include directories precede WebKitLibraries in JSC.
+ https://bugs.webkit.org/show_bug.cgi?id=108693.
+
+ Rubberstamped by Timothy Horton.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+
+2013-02-04 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Structure::m_outOfLineCapacity is unnecessary
+ https://bugs.webkit.org/show_bug.cgi?id=108206
+
+ Reviewed by Darin Adler.
+
+ Simplifying the utility functions that we use since we don't need a
+ bunch of fancy templates for this one specific call site.
+
+ * runtime/Structure.h:
+ (JSC::Structure::outOfLineCapacity):
+
+2013-02-05 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: testapi.mm should use ARC
+ https://bugs.webkit.org/show_bug.cgi?id=107838
+
+ Reviewed by Oliver Hunt.
+
+ In ToT testapi.mm uses the Obj-C garbage collector, which hides a lot of our object lifetime bugs.
+ We should enable ARC, since that is what most of our clients will be using. We use Xcode project
+ settings to make sure we don't try to compile ARC on 32-bit.
+
+ * API/tests/testapi.mm:
+ (+[TestObject testObject]):
+ (testObjectiveCAPI):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-02-05 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows] Unreviewed VS2010 Build Correction after r141651
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Add missing
+ StructureRareData.h and StructureRareData.cpp files.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Ditto.
+
+2013-02-05 Michael Saboff <msaboff@apple.com>
+
+ r141788 won't build due to not having all changes needed by Node* change
+ https://bugs.webkit.org/show_bug.cgi?id=108944
+
+ Reviewed by David Kilzer.
+
+ Fixed three instances of integerResult(..., m_compileIndex) to be integerResult(..., node).
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileSoftModulo):
+ (JSC::DFG::SpeculativeJIT::compileIntegerArithDivForARMv7s):
+
+2013-02-04 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r141809.
+ http://trac.webkit.org/changeset/141809
+ https://bugs.webkit.org/show_bug.cgi?id=108860
+
+ ARC isn't supported on 32-bit. (Requested by mhahnenberg on
+ #webkit).
+
+ * API/tests/testapi.mm:
+ (+[TestObject testObject]):
+ (testObjectiveCAPI):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-02-04 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: testapi.mm should use ARC
+ https://bugs.webkit.org/show_bug.cgi?id=107838
+
+ Reviewed by Oliver Hunt.
+
+ In ToT testapi.mm uses the Obj-C garbage collector, which hides a lot of our object lifetime bugs.
+ We should enable ARC, since that is what most of our clients will be using.
+
+ * API/tests/testapi.mm:
+ (-[TestObject init]):
+ (-[TestObject dealloc]):
+ (+[TestObject testObject]):
+ (testObjectiveCAPI):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-02-04 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: ObjCCallbackFunction should retain the target of its NSInvocation
+ https://bugs.webkit.org/show_bug.cgi?id=108843
+
+ Reviewed by Darin Adler.
+
+ Currently, ObjCCallbackFunction doesn't retain the target of its NSInvocation. It needs to do
+ this to prevent crashes when trying to invoke a callback later on.
+
+ * API/ObjCCallbackFunction.mm:
+ (ObjCCallbackFunction::ObjCCallbackFunction):
+ (ObjCCallbackFunction::~ObjCCallbackFunction):
+
+2013-02-04 Martin Robinson <mrobinson@igalia.com>
+
+ Fix GTK+ 'make dist' in preparation for the 1.11.5 release.
+
+ * GNUmakefile.list.am: Update the source lists.
+
+2013-02-04 Michael Saboff <msaboff@apple.com>
+
+ For ARMv7s use integer divide instruction for divide and modulo when possible
+ https://bugs.webkit.org/show_bug.cgi?id=108840
+
+ Reviewed in person by Filip Pizlo.
+
+ Added ARMv7s integer divide path for ArithDiv and ArithMod where operands and results are integer.
+ This is patterned after the similar code for X86. Also added modulo power of 2 optimization
+ that uses logical and. Added sdiv and udiv to the ARMv7 disassembler. Put all the changes
+ behind #if CPU(APPLE_ARMV7S).
+
+ * assembler/ARMv7Assembler.h:
+ (ARMv7Assembler):
+ (JSC::ARMv7Assembler::sdiv):
+ (JSC::ARMv7Assembler::udiv):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::isARMv7s):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileSoftModulo):
+ (JSC::DFG::SpeculativeJIT::compileIntegerArithDivForARMv7s):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-02-04 David Kilzer <ddkilzer@apple.com>
+
+ Check PrivateHeaders/JSBasePrivate.h for inappropriate macros
+ <http://webkit.org/b/108749>
+
+ Reviewed by Joseph Pecoraro.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Add
+ PrivateHeaders/JSBasePrivate.h to list of headers to check in
+ "Check for Inappropriate Macros in External Headers" build phase
+ script.
+
+2013-02-04 David Kilzer <ddkilzer@apple.com>
+
+ Remove duplicate entries from JavaScriptCore Xcode project
+
+ $ uniq Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj | diff -u - Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj | patch -p0 -R
+ patching file Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Remove duplicates.
+
+2013-02-04 David Kilzer <ddkilzer@apple.com>
+
+ Sort JavaScriptCore Xcode project file
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-02-03 David Kilzer <ddkilzer@apple.com>
+
+ Upstream ENABLE_PDFKIT_PLUGIN settting
+ <http://webkit.org/b/108792>
+
+ Reviewed by Tim Horton.
+
+ * Configurations/FeatureDefines.xcconfig: Disable PDFKIT_PLUGIN
+ on iOS since PDFKit is a Mac-only framework.
+
+2013-02-02 Andreas Kling <akling@apple.com>
+
+ Vector should consult allocator about ideal size when choosing capacity.
+ <http://webkit.org/b/108410>
+ <rdar://problem/13124002>
+
+ Reviewed by Benjamin Poulain.
+
+ Remove assertion about Vector capacity that won't hold anymore since capacity()
+ may not be what you passed to reserveCapacity().
+ Also export WTF::fastMallocGoodSize() for Windows builds.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2013-02-02 Patrick Gansterer <paroga@webkit.org>
+
+ [CMake] Adopt the WinCE port to new CMake
+ https://bugs.webkit.org/show_bug.cgi?id=108754
+
+ Reviewed by Laszlo Gombos.
+
+ * os-win32/WinMain.cpp: Removed.
+ * shell/PlatformWinCE.cmake: Removed.
+
+2013-02-02 Mark Rowe <mrowe@apple.com>
+
+ <http://webkit.org/b/108745> WTF shouldn't use a script build phase to detect the presence of headers when the compiler can do it for us
+
+ Reviewed by Sam Weinig.
+
+ * DerivedSources.make: Remove an obsolete Makefile rule. This should have been removed when the use
+ of the generated file moved to WTF.
+
+2013-02-02 David Kilzer <ddkilzer@apple.com>
+
+ Upstream iOS FeatureDefines
+ <http://webkit.org/b/108753>
+
+ Reviewed by Anders Carlsson.
+
+ * Configurations/FeatureDefines.xcconfig:
+ - ENABLE_DEVICE_ORIENTATION: Add iOS configurations.
+ - ENABLE_PLUGIN_PROXY_FOR_VIDEO: Ditto.
+ - FEATURE_DEFINES: Add ENABLE_PLUGIN_PROXY_FOR_VIDEO. Add
+ PLATFORM_NAME variant to reduce future merge conflicts.
+
+2013-02-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Structure::m_enumerationCache should be moved to StructureRareData
+ https://bugs.webkit.org/show_bug.cgi?id=108723
+
+ Reviewed by Oliver Hunt.
+
+ m_enumerationCache is only used by objects whose properties are iterated over, so not every Structure needs this
+ field and it can therefore be moved safely to StructureRareData to help with memory savings.
+
+ * runtime/JSPropertyNameIterator.h:
+ (JSPropertyNameIterator):
+ (JSC::Register::propertyNameIterator):
+ (JSC::StructureRareData::enumerationCache): Add to JSPropertyNameIterator.h so that it can see the correct type.
+ (JSC::StructureRareData::setEnumerationCache): Ditto.
+ * runtime/Structure.cpp:
+ (JSC::Structure::addPropertyWithoutTransition): Use the enumerationCache() getter rather than accessing the field.
+ (JSC::Structure::removePropertyWithoutTransition): Ditto.
+ (JSC::Structure::visitChildren): We no longer have to worry about marking the m_enumerationCache field.
+ * runtime/Structure.h:
+ (JSC::Structure::setEnumerationCache): Move the old accessors back since we don't have to have any knowledge of
+ the JSPropertyNameIterator type.
+ (JSC::Structure::enumerationCache): Ditto.
+ * runtime/StructureRareData.cpp:
+ (JSC::StructureRareData::visitChildren): Mark the new m_enumerationCache field.
+ * runtime/StructureRareData.h: Add new functions/fields.
+ (StructureRareData):
+
+2013-02-01 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. JavaScriptCore VS2010 project cleanup.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj:
+
+2013-02-01 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r141662.
+ http://trac.webkit.org/changeset/141662
+ https://bugs.webkit.org/show_bug.cgi?id=108738
+
+ it's an incorrect change since processPhiStack will
+ dereference dangling BasicBlock pointers (Requested by pizlo
+ on #webkit).
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parse):
+
+2013-02-01 Filip Pizlo <fpizlo@apple.com>
+
+ Eliminate dead blocks sooner in the DFG::ByteCodeParser to make clear that you don't need to hold onto them during Phi construction
+ https://bugs.webkit.org/show_bug.cgi?id=108717
+
+ Reviewed by Mark Hahnenberg.
+
+ I think this makes the code clearer. It doesn't change behavior.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parse):
+
+2013-02-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Structure should have a StructureRareData field to save space
+ https://bugs.webkit.org/show_bug.cgi?id=108659
+
+ Reviewed by Oliver Hunt.
+
+ Many of the fields in Structure are used in a subset of all total Structures; however, all Structures must
+ pay the memory cost of those fields, regardless of whether they use them or not. Since we can have potentially
+ many Structures on a single page (e.g. bing.com creates ~1500 Structures), it would be profitable to
+ refactor Structure so that not every Structure has to pay the memory costs for these infrequently used fields.
+
+ To accomplish this, we can create a new StructureRareData class to house these seldom used fields which we
+ can allocate on demand whenever a Structure requires it. This StructureRareData can itself be a JSCell, and
+ can do all the marking of the fields for the Structure. The StructureRareData field will be part of a union
+ with m_previous to minimize overhead. We'll add a new field to JSTypeInfo to indicate that the Structure has
+ a StructureRareData field. During transitions, a Structure will clone its previous Structure's StructureRareData
+ if it has one. There could be some potential for optimizing this process, but the initial implementation will
+ be dumb since we'd be paying these overhead costs for each Structure anyways.
+
+ Initially we'll only put two fields in the StructureRareData to avoid a memory regression. Over time we'll
+ continue to move fields from Structure to StructureRareData. Optimistically, this could potentially reduce our
+ Structure memory footprint by up to around 75%. It could also clear the way for removing destructors from
+ Structures (and into StructureRareData).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGRepatch.cpp: Includes for linking purposes.
+ * jit/JITStubs.cpp:
+ * jsc.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ * runtime/JSCellInlines.h: Added ifdef guards.
+ * runtime/JSGlobalData.cpp: New Structure for StructureRareData class.
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSGlobalObject.h:
+ * runtime/JSTypeInfo.h: New flag to indicate whether or not a Structure has a StructureRareData field.
+ (JSC::TypeInfo::flags):
+ (JSC::TypeInfo::structureHasRareData):
+ * runtime/ObjectPrototype.cpp:
+ * runtime/Structure.cpp: We use a combined WriteBarrier<JSCell> field m_previousOrRareData to avoid compiler issues.
+ (JSC::Structure::dumpStatistics):
+ (JSC::Structure::Structure):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::pin):
+ (JSC::Structure::allocateRareData): Handles allocating a brand new StructureRareData field.
+ (JSC::Structure::cloneRareDataFrom): Handles cloning a StructureRareData field from another. Used during Structure
+ transitions.
+ (JSC::Structure::visitChildren): We no longer have to worry about marking m_objectToStringValue.
+ * runtime/Structure.h:
+ (JSC::Structure::previousID): Checks the structureHasRareData flag to see where it should get the previous Structure.
+ (JSC::Structure::objectToStringValue): Reads the value from the StructureRareData. If it doesn't exist, returns 0.
+ (JSC::Structure::setObjectToStringValue): Ensures that we have a StructureRareData field, then forwards the function
+ call to it.
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::setPreviousID): Checks for StructureRareData and forwards if necessary.
+ (Structure):
+ (JSC::Structure::clearPreviousID): Ditto.
+ (JSC::Structure::create):
+ * runtime/StructureRareData.cpp: Added. All of the basic functionality of a JSCell with the fields that we've moved
+ from Structure and the functions required to access/modify those fields as Structure would have done.
+ (JSC):
+ (JSC::StructureRareData::createStructure):
+ (JSC::StructureRareData::create):
+ (JSC::StructureRareData::clone):
+ (JSC::StructureRareData::StructureRareData):
+ (JSC::StructureRareData::visitChildren):
+ * runtime/StructureRareData.h: Added.
+ (JSC):
+ (StructureRareData):
+ * runtime/StructureRareDataInlines.h: Added.
+ (JSC):
+ (JSC::StructureRareData::previousID):
+ (JSC::StructureRareData::setPreviousID):
+ (JSC::StructureRareData::clearPreviousID):
+ (JSC::Structure::previous): Handles the ugly casting to get the value of the right type of m_previousOrRareData.
+ (JSC::Structure::rareData): Ditto.
+ (JSC::StructureRareData::objectToStringValue):
+ (JSC::StructureRareData::setObjectToStringValue):
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGRepatch.cpp:
+ * jit/JITStubs.cpp:
+ * jsc.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ * runtime/JSCellInlines.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/JSGlobalObject.h:
+ * runtime/JSTypeInfo.h:
+ (JSC):
+ (JSC::TypeInfo::flags):
+ (JSC::TypeInfo::structureHasRareData):
+ * runtime/ObjectPrototype.cpp:
+ * runtime/Structure.cpp:
+ (JSC::Structure::dumpStatistics):
+ (JSC::Structure::Structure):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::pin):
+ (JSC::Structure::allocateRareData):
+ (JSC):
+ (JSC::Structure::cloneRareDataFrom):
+ (JSC::Structure::visitChildren):
+ * runtime/Structure.h:
+ (JSC::Structure::previousID):
+ (JSC::Structure::objectToStringValue):
+ (JSC::Structure::setObjectToStringValue):
+ (JSC::Structure::materializePropertyMapIfNecessary):
+ (JSC::Structure::setPreviousID):
+ (Structure):
+ (JSC::Structure::clearPreviousID):
+ (JSC::Structure::previous):
+ (JSC::Structure::rareData):
+ (JSC::Structure::create):
+ * runtime/StructureRareData.cpp: Added.
+ (JSC):
+ (JSC::StructureRareData::createStructure):
+ (JSC::StructureRareData::create):
+ (JSC::StructureRareData::clone):
+ (JSC::StructureRareData::StructureRareData):
+ (JSC::StructureRareData::visitChildren):
+ * runtime/StructureRareData.h: Added.
+ (JSC):
+ (StructureRareData):
+ * runtime/StructureRareDataInlines.h: Added.
+ (JSC):
+ (JSC::StructureRareData::previousID):
+ (JSC::StructureRareData::setPreviousID):
+ (JSC::StructureRareData::clearPreviousID):
+ (JSC::StructureRareData::objectToStringValue):
+ (JSC::StructureRareData::setObjectToStringValue):
+
+2013-02-01 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ offlineasm BaseIndex handling is broken on ARM due to MIPS changes
+ https://bugs.webkit.org/show_bug.cgi?id=108261
+
+ Reviewed by Filip Pizlo.
+
+ offlineasm BaseIndex handling fix on MIPS.
+
+ * offlineasm/mips.rb:
+ * offlineasm/risc.rb:
+
+2013-02-01 Geoffrey Garen <ggaren@apple.com>
+
+ Removed an unused function: JSGlobalObject::createFunctionExecutableFromGlobalCode
+ https://bugs.webkit.org/show_bug.cgi?id=108657
+
+ Reviewed by Anders Carlsson.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+
+2013-02-01 Geoffrey Garen <ggaren@apple.com>
+
+ Added TriState to WTF and started using it in one place
+ https://bugs.webkit.org/show_bug.cgi?id=108628
+
+ Reviewed by Beth Dakin.
+
+ * runtime/PrototypeMap.h:
+ (JSC::PrototypeMap::isPrototype): Use TriState instead of boolean. In
+ response to review feedback, this is an attempt to clarify that our
+ 'true' condition is actually just a 'maybe'.
+
+ * runtime/PrototypeMap.h:
+ (PrototypeMap):
+ (JSC::PrototypeMap::isPrototype):
+
+2013-02-01 Alexis Menard <alexis@webkit.org>
+
+ Enable unprefixed CSS transitions by default.
+ https://bugs.webkit.org/show_bug.cgi?id=108216
+
+ Reviewed by Dean Jackson.
+
+ Rename the flag CSS_TRANSFORMS_ANIMATIONS_TRANSITIONS_UNPREFIXED
+ to CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED which will be used later to
+ guard the unprefixing work for CSS Transforms and animations.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-31 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::CFGSimplificationPhase::keepOperandAlive() conflates liveness and availability
+ https://bugs.webkit.org/show_bug.cgi?id=108580
+
+ Reviewed by Oliver Hunt.
+
+ This is a harmless bug in that it only results in us keeping a bit too many things
+ for OSR. But it's worth fixing so that the code is consistent.
+
+ keepOperandAlive() is called when block A has a branch to blocks B and C, but the
+ A->B edge is proven to never be taken and we want to optimize the code to have A
+ unconditionally jump to C. In that case, for the purposes of OSR, we need to
+ preserve the knowledge that the state that B expected to be live incoming from A
+ ought still to be live up to the point of where the A->B,C branch used to be. The
+ way we keep things alive is by using the variablesAtTail of A (i.e., we use the
+ knowledge of in what manner A made state available to B and C). The way we choose
+ which state should be kept alive ought to be chosen by the variablesAtHead of B
+ (i.e. the things B says it needs from its predecessors, including A), except that
+ keepOperandAlive() was previously just using variablesAtTail of A for this
+ purpose.
+
+ The fix is to have keepOperandAlive() use both liveness and availability in its
+ logic. It should use liveness (i.e. B->variablesAtHead) to decide what to keep
+ alive, and it should use availability (i.e. A->variablesAtTail) to decide how to
+ keep it alive.
+
+ This might be a microscopic win on some programs, but it's mainly intended to be
+ a code clean-up so that I don't end up scratching my head in confusion the next
+ time I look at this code.
+
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ (JSC::DFG::CFGSimplificationPhase::jettisonBlock):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+
+2013-01-31 Geoffrey Garen <ggaren@apple.com>
+
+ REGRESSION (r141192): Crash beneath cti_op_get_by_id_generic @ discussions.apple.com
+ https://bugs.webkit.org/show_bug.cgi?id=108576
+
+ Reviewed by Filip Pizlo.
+
+ This was a long-standing bug. The DFG would destructively reuse a register
+ in op_convert_this, but:
+
+ * The bug only presented during speculation failure for type Other
+
+ * The bug presented by removing the low bits of a pointer, which
+ used to be harmless, since all objects were so aligned anyway.
+
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Don't reuse our this register as
+ our scratch register. The whole point of our scratch register is to
+ avoid destructively modifying our this register. I'm pretty sure this
+ was a copy-paste error.
+
+2013-01-31 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-01-31 Jessie Berlin <jberlin@apple.com>
+
+ Rolling out r141407 because it is causing crashes under
+ WTF::TCMalloc_Central_FreeList::FetchFromSpans() in Release builds.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2013-01-31 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: JSContext exception property causes reference cycle
+ https://bugs.webkit.org/show_bug.cgi?id=107778
+
+ Reviewed by Darin Adler.
+
+ JSContext has a (retain) JSValue * exception property which, when non-null, creates a
+ reference cycle (since the JSValue * holds a strong reference back to the JSContext *).
+
+ * API/JSContext.mm: Instead of JSValue *, we now use a plain JSValueRef, which eliminates the reference cycle.
+ (-[JSContext initWithVirtualMachine:]):
+ (-[JSContext setException:]):
+ (-[JSContext exception]):
+
+2013-01-31 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed build fix. Win7 port.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-01-31 Joseph Pecoraro <pecoraro@apple.com>
+
+ Disable ENABLE_FULLSCREEN_API on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=108250
+
+ Reviewed by Benjamin Poulain.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-31 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Fix insertion of values greater than the max index allowed by the spec
+ https://bugs.webkit.org/show_bug.cgi?id=108264
+
+ Reviewed by Oliver Hunt.
+
+ Fixed a bug, added a test to the API tests, cleaned up some code.
+
+ * API/JSValue.h: Changed some of the documentation on setValue:atIndex: to indicate that
+ setting values at indices greater than UINT_MAX - 1 wont' affect the length of JS arrays.
+ * API/JSValue.mm:
+ (-[JSValue valueAtIndex:]): We weren't returning when we should have been.
+ (-[JSValue setValue:atIndex:]): Added a comment about why we do the early check for being larger than UINT_MAX.
+ (objectToValueWithoutCopy): Removed two redundant cases that were already checked previously.
+ * API/tests/testapi.mm:
+
+2013-01-30 Andreas Kling <akling@apple.com>
+
+ Vector should consult allocator about ideal size when choosing capacity.
+ <http://webkit.org/b/108410>
+ <rdar://problem/13124002>
+
+ Reviewed by Benjamin Poulain.
+
+ Remove assertion about Vector capacity that won't hold anymore since capacity()
+ may not be what you passed to reserveCapacity().
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2013-01-30 Filip Pizlo <fpizlo@apple.com>
+
+ DFG bytecode parser should have more assertions about the status of local accesses
+ https://bugs.webkit.org/show_bug.cgi?id=108417
+
+ Reviewed by Mark Hahnenberg.
+
+ Assert some things that we already know to be true, just to reassure ourselves that they are true.
+ This is meant as a prerequisite for https://bugs.webkit.org/show_bug.cgi?id=108414, which will
+ make these rules even stricter.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getLocal):
+ (JSC::DFG::ByteCodeParser::getArgument):
+
+2013-01-30 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: JSContext's dealloc causes ASSERT due to ordering of releases
+ https://bugs.webkit.org/show_bug.cgi?id=107978
+
+ Reviewed by Filip Pizlo.
+
+ We need to add the Identifier table save/restore in JSContextGroupRelease so that we
+ have the correct table if we end up destroying the JSGlobalData/Heap.
+
+ * API/JSContextRef.cpp:
+ (JSContextGroupRelease):
+
+2013-01-30 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: exceptionHandler needs to be released in JSContext dealloc
+ https://bugs.webkit.org/show_bug.cgi?id=108378
+
+ Reviewed by Filip Pizlo.
+
+ JSContext has a (copy) exceptionHandler property that it doesn't release in dealloc.
+ That sounds like the potential for a leak. It should be released.
+
+ * API/JSContext.mm:
+ (-[JSContext dealloc]):
+
+2013-01-30 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION(140504): pure CSE no longer matches things, 10% regression on Kraken
+ https://bugs.webkit.org/show_bug.cgi?id=108366
+
+ Reviewed by Geoffrey Garen and Mark Hahnenberg.
+
+ This was a longstanding bug that was revealed by http://trac.webkit.org/changeset/140504.
+ Pure CSE requires that the Node::flags() that may affect the behavior of a node match,
+ when comparing a possibly redundant node to its possible replacement. It was doing this
+ by comparing Node::arithNodeFlags(), which as the name might appear to suggest, returns
+ just those flag bits that correspond to actual node behavior and not auxiliary things.
+ Unfortunately, Node::arithNodeFlags() wasn't actually masking off the irrelevant bits.
+ This worked prior to r140504 because CSE itself didn't mutate the flags, so there was a
+ very high probability that matching nodes would also have completely identical flag bits
+ (even the ones that aren't relevant to arithmetic behavior, like NodeDoesNotExit). But
+ r140504 moved one of CSE's side-tables (m_relevantToOSR) into a flag bit for quicker
+ access. These bits would be mutated as the CSE ran over a basic block, in such a way that
+ there was a very high probability that the possible replacement would already have the
+ bit set, while the redundant node did not have the bit set. Since Node::arithNodeFlags()
+ returned all of the bits, this would cause CSEPhase::pureCSE() to reject the match
+ almost every time.
+
+ The solution is to make Node::arithNodeFlags() do as its name suggests: only return those
+ flags that are relevant to arithmetic behavior. This patch introduces a new mask that
+ represents those bits, and includes NodeBehaviorMask and NodeBackPropMask, which are both
+ used for queries on Node::arithNodeFlags(), and both affect arithmetic code gen. None of
+ the other flags are relevant to Node::arithNodeFlags() since they either correspond to
+ information already conveyed by the opcode (like NodeResultMask, NodeMustGenerate,
+ NodeHasVarArgs, NodeClobbersWorld, NodeMightClobber) or information that doesn't affect
+ the result that the node will produce or any of the queries performed on the result of
+ Node::arithNodeFlags (NodeDoesNotExit and of course NodeRelevantToOSR).
+
+ This is a 10% speed-up on Kraken, undoing the regression from r140504.
+
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::arithNodeFlags):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+
+2013-01-29 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Structure::m_outOfLineCapacity is unnecessary
+ https://bugs.webkit.org/show_bug.cgi?id=108206
+
+ Reviewed by Geoffrey Garen.
+
+ We can calculate our out of line capacity by using the outOfLineSize and our knowledge about our resize policy.
+ According to GDB, this knocks Structures down from 136 bytes to 128 bytes (I'm guessing the extra bytes are from
+ better alignment of object fields), which puts Structures in a smaller size class. Woohoo! Looks neutral on our
+ benchmarks.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC):
+ (JSC::Structure::suggestedNewOutOfLineStorageCapacity):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::addPropertyWithoutTransition):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::outOfLineCapacity):
+ (JSC::Structure::totalStorageCapacity):
+
+2013-01-29 Geoffrey Garen <ggaren@apple.com>
+
+ Be a little more conservative about emitting table-based switches
+ https://bugs.webkit.org/show_bug.cgi?id=108292
+
+ Reviewed by Filip Pizlo.
+
+ Profiling shows we're using op_switch in cases where it's a regression.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC):
+ (JSC::length):
+ (JSC::CaseBlockNode::tryTableSwitch):
+ (JSC::CaseBlockNode::emitBytecodeForBlock):
+ * parser/Nodes.h:
+ (CaseBlockNode):
+
+2013-01-29 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r140983.
+ http://trac.webkit.org/changeset/140983
+ https://bugs.webkit.org/show_bug.cgi?id=108277
+
+ Unfortunately, this API has one last client (Requested by
+ abarth on #webkit).
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-29 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: JSObjCClassInfo creates reference cycle with JSContext
+ https://bugs.webkit.org/show_bug.cgi?id=107839
+
+ Reviewed by Geoffrey Garen.
+
+ Fixing several ASSERTs that were incorrect along with some of the reallocation of m_prototype and
+ m_constructor that they were based on.
+
+ * API/JSWrapperMap.mm:
+ (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]): We now only allocate those
+ fields that are null (i.e. have been collected or have never been allocated to begin with).
+ (-[JSObjCClassInfo reallocateConstructorAndOrPrototype]): Renamed to better indicate that we're
+ reallocating one or both of the prototype/constructor combo.
+ (-[JSObjCClassInfo wrapperForObject:]): Call new reallocate function.
+ (-[JSObjCClassInfo constructor]): Ditto.
+
+2013-01-29 Geoffrey Garen <ggaren@apple.com>
+
+ Make precise size classes more precise
+ https://bugs.webkit.org/show_bug.cgi?id=108270
+
+ Reviewed by Mark Hahnenberg.
+
+ Size inference makes this profitable.
+
+ I chose 8 byte increments because JSString is 24 bytes. Otherwise, 16
+ byte increments might be better.
+
+ * heap/Heap.h:
+ (Heap): Removed firstAllocatorWithoutDestructors because it's unused now.
+
+ * heap/MarkedBlock.h:
+ (MarkedBlock): Updated constants.
+
+ * heap/MarkedSpace.h:
+ (MarkedSpace):
+ (JSC): Also reduced the maximum precise size class because my testing
+ has shown that the smaller size classes are much more common. This
+ offsets some of the size class explosion caused by reducing the precise
+ increment.
+
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions): No need for this ASSERT anymore
+ because we don't rely on firstAllocatorWithoutDestructors anymore, since
+ we pick size classes dynamically now.
+
+2013-01-29 Oliver Hunt <oliver@apple.com>
+
+ Add some hardening to methodTable()
+ https://bugs.webkit.org/show_bug.cgi?id=108253
+
+ Reviewed by Mark Hahnenberg.
+
+ When accessing methodTable() we now always make sure that our
+ structure _could_ be valid. Added a separate method to get a
+ classes methodTable during destruction as it's not possible to
+ validate the structure at that point. This separation might
+ also make it possible to improve the performance of methodTable
+ access more generally in future.
+
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::callDestructor):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSCellInlines.h:
+ (JSC::JSCell::methodTableForDestruction):
+ (JSC):
+ (JSC::JSCell::methodTable):
+
+2013-01-29 Filip Pizlo <fpizlo@apple.com>
+
+ offlineasm BaseIndex handling is broken on ARM due to MIPS changes
+ https://bugs.webkit.org/show_bug.cgi?id=108261
+
+ Reviewed by Oliver Hunt.
+
+ Backends shouldn't override each other's methods. That's not cool.
+
+ * offlineasm/mips.rb:
+
+2013-01-29 Filip Pizlo <fpizlo@apple.com>
+
+ cloop.rb shouldn't use a method called 'dump' for code generation
+ https://bugs.webkit.org/show_bug.cgi?id=108251
+
+ Reviewed by Mark Hahnenberg.
+
+ Revert http://trac.webkit.org/changeset/141178 and rename 'dump' to 'clDump'.
+
+ Also made trivial build fixes for !ENABLE(JIT).
+
+ * offlineasm/cloop.rb:
+ * runtime/Executable.h:
+ (ExecutableBase):
+ (JSC::ExecutableBase::intrinsicFor):
+ * runtime/JSGlobalData.h:
+
+2013-01-29 Geoffrey Garen <ggaren@apple.com>
+
+ Removed GGC because it has been disabled for a long time
+ https://bugs.webkit.org/show_bug.cgi?id=108245
+
+ Reviewed by Filip Pizlo.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::emitPutReplaceStub):
+ (JSC::DFG::emitPutTransitionStub):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::writeBarrier):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * heap/CardSet.h: Removed.
+ * heap/Heap.cpp:
+ (JSC::Heap::markRoots):
+ (JSC::Heap::collect):
+ * heap/Heap.h:
+ (Heap):
+ (JSC::Heap::shouldCollect):
+ (JSC::Heap::isWriteBarrierEnabled):
+ (JSC):
+ (JSC::Heap::writeBarrier):
+ * heap/MarkedBlock.h:
+ (MarkedBlock):
+ (JSC):
+ * heap/MarkedSpace.cpp:
+ (JSC):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitWriteBarrier):
+
+2013-01-29 Filip Pizlo <fpizlo@apple.com>
+
+ Remove redundant AST dump method from cloop.rb, since they are already defined in ast.rb
+ https://bugs.webkit.org/show_bug.cgi?id=108247
+
+ Reviewed by Oliver Hunt.
+
+ Makes offlineasm dumping easier to read and less likely to cause assertion failures.
+ Also fixes the strange situation where cloop.rb and ast.rb both defined dump methods,
+ but cloop.rb was winning.
+
+ * offlineasm/cloop.rb:
+
+2013-01-29 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: JSObjCClassInfo creates reference cycle with JSContext
+ https://bugs.webkit.org/show_bug.cgi?id=107839
+
+ Reviewed by Oliver Hunt.
+
+ JSContext has a JSWrapperMap, which has an NSMutableDictionary m_classMap, which has values that
+ are JSObjCClassInfo objects, which have strong references to two JSValue *'s, m_prototype and
+ m_constructor, which in turn have strong references to the JSContext, creating a reference cycle.
+ We should make m_prototype and m_constructor Weak<JSObject>. This gets rid of the strong reference
+ to the JSContext and also prevents clients from accidentally creating reference cycles by assigning
+ to the prototype of the constructor. If Weak<JSObject> fields are ever garbage collected, we will
+ reallocate them.
+
+ * API/JSContext.mm:
+ (-[JSContext wrapperMap]):
+ * API/JSContextInternal.h:
+ * API/JSWrapperMap.mm:
+ (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]):
+ (-[JSObjCClassInfo dealloc]):
+ (-[JSObjCClassInfo allocateConstructorAndPrototypeWithSuperClassInfo:]):
+ (-[JSObjCClassInfo allocateConstructorAndPrototype]):
+ (-[JSObjCClassInfo wrapperForObject:]):
+ (-[JSObjCClassInfo constructor]):
+
+2013-01-29 Oliver Hunt <oliver@apple.com>
+
+ REGRESSION (r140594): RELEASE_ASSERT_NOT_REACHED in JSC::Interpreter::execute
+ https://bugs.webkit.org/show_bug.cgi?id=108097
+
+ Reviewed by Geoffrey Garen.
+
+ LiteralParser was accepting a bogus 'var a.b = c' statement
+
+ * runtime/LiteralParser.cpp:
+ (JSC::::tryJSONPParse):
+
+2013-01-29 Oliver Hunt <oliver@apple.com>
+
+ Force debug builds to do bounds checks on contiguous property storage
+ https://bugs.webkit.org/show_bug.cgi?id=108212
+
+ Reviewed by Mark Hahnenberg.
+
+ Add a ContiguousData type that we use to represent contiguous property
+ storage. In release builds it is simply a pointer to the correct type,
+ but in debug builds it also carries the data length and performs bounds
+ checks. This means we don't have to add as many manual bounds assertions
+ when performing operations over contiguous data.
+
+ * dfg/DFGOperations.cpp:
+ * runtime/ArrayStorage.h:
+ (ArrayStorage):
+ (JSC::ArrayStorage::vector):
+ * runtime/Butterfly.h:
+ (JSC::ContiguousData::ContiguousData):
+ (ContiguousData):
+ (JSC::ContiguousData::operator[]):
+ (JSC::ContiguousData::data):
+ (JSC::ContiguousData::length):
+ (JSC):
+ (JSC::Butterfly::contiguousInt32):
+ (Butterfly):
+ (JSC::Butterfly::contiguousDouble):
+ (JSC::Butterfly::contiguous):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::sortNumericVector):
+ (ContiguousTypeAccessor):
+ (JSC::ContiguousTypeAccessor::getAsValue):
+ (JSC::ContiguousTypeAccessor::setWithValue):
+ (JSC::ContiguousTypeAccessor::replaceDataReference):
+ (JSC):
+ (JSC::JSArray::sortCompactedVector):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::fillArgList):
+ (JSC::JSArray::copyToArguments):
+ * runtime/JSArray.h:
+ (JSArray):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly):
+ (JSC::JSObject::visitButterfly):
+ (JSC::JSObject::createInitialInt32):
+ (JSC::JSObject::createInitialDouble):
+ (JSC::JSObject::createInitialContiguous):
+ (JSC::JSObject::convertUndecidedToInt32):
+ (JSC::JSObject::convertUndecidedToDouble):
+ (JSC::JSObject::convertUndecidedToContiguous):
+ (JSC::JSObject::convertInt32ToDouble):
+ (JSC::JSObject::convertInt32ToContiguous):
+ (JSC::JSObject::genericConvertDoubleToContiguous):
+ (JSC::JSObject::convertDoubleToContiguous):
+ (JSC::JSObject::rageConvertDoubleToContiguous):
+ (JSC::JSObject::ensureInt32Slow):
+ (JSC::JSObject::ensureDoubleSlow):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::rageEnsureContiguousSlow):
+ (JSC::JSObject::ensureLengthSlow):
+ * runtime/JSObject.h:
+ (JSC::JSObject::ensureInt32):
+ (JSC::JSObject::ensureDouble):
+ (JSC::JSObject::ensureContiguous):
+ (JSC::JSObject::rageEnsureContiguous):
+ (JSObject):
+ (JSC::JSObject::indexingData):
+ (JSC::JSObject::currentIndexingData):
+
+2013-01-29 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows, WinCairo] Unreviewed build fix after r141050
+
+ * JavaScriptCore.vcxproj/JavaScriptCoreExports.def: Update symbols
+ to match JavaScriptCore.vcproj version.
+
+2013-01-29 Allan Sandfeld Jensen <allan.jensen@digia.com>
+
+ [Qt] Implement GCActivityCallback
+ https://bugs.webkit.org/show_bug.cgi?id=103998
+
+ Reviewed by Simon Hausmann.
+
+ Implements the activity triggered garbage collector.
+
+ * runtime/GCActivityCallback.cpp:
+ (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback):
+ (JSC::DefaultGCActivityCallback::scheduleTimer):
+ (JSC::DefaultGCActivityCallback::cancelTimer):
+ * runtime/GCActivityCallback.h:
+ (GCActivityCallback):
+ (DefaultGCActivityCallback):
+
+2013-01-29 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+
+ Compilation warning in JSC
+ https://bugs.webkit.org/show_bug.cgi?id=108178
+
+ Reviewed by Kentaro Hara.
+
+ Fixed 'comparison between signed and unsigned integer' warning in JSC::Structure constructor.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+
+2013-01-29 Jocelyn Turcotte <jocelyn.turcotte@digia.com>
+
+ [Qt] Fix the JSC build on Mac
+
+ Unreviewed, build fix.
+
+ * heap/HeapTimer.h:
+ Qt on Mac has USE(CF) true, and should use the CF HeapTimer in that case.
+
+2013-01-29 Allan Sandfeld Jensen <allan.jensen@digia.com>
+
+ [Qt] Implement IncrementalSweeper and HeapTimer
+ https://bugs.webkit.org/show_bug.cgi?id=103996
+
+ Reviewed by Simon Hausmann.
+
+ Implements the incremental sweeping garbage collection for the Qt platform.
+
+ * heap/HeapTimer.cpp:
+ (JSC::HeapTimer::HeapTimer):
+ (JSC::HeapTimer::~HeapTimer):
+ (JSC::HeapTimer::timerEvent):
+ (JSC::HeapTimer::synchronize):
+ (JSC::HeapTimer::invalidate):
+ (JSC::HeapTimer::didStartVMShutdown):
+ * heap/HeapTimer.h:
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::IncrementalSweeper):
+ (JSC::IncrementalSweeper::scheduleTimer):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+
+2013-01-28 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not use a graph that is a vector, Nodes shouldn't move after allocation, and we should always refer to nodes by Node*
+ https://bugs.webkit.org/show_bug.cgi?id=106868
+
+ Reviewed by Oliver Hunt.
+
+ This adds a pool allocator for Nodes, and uses that instead of a Vector. Changes all
+ uses of Node& and NodeIndex to be simply Node*. Nodes no longer have an index except
+ for debugging (Node::index(), which is not guaranteed to be O(1)).
+
+ 1% speed-up on SunSpider, presumably because this improves compile times.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/DataFormat.h:
+ (JSC::dataFormatToString):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ (JSC::DFG::AbstractState::booleanResult):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ (JSC::DFG::AbstractState::mergeVariableBetweenBlocks):
+ (JSC::DFG::AbstractState::dump):
+ * dfg/DFGAbstractState.h:
+ (DFG):
+ (JSC::DFG::AbstractState::forNode):
+ (AbstractState):
+ (JSC::DFG::AbstractState::speculateInt32Unary):
+ (JSC::DFG::AbstractState::speculateNumberUnary):
+ (JSC::DFG::AbstractState::speculateBooleanUnary):
+ (JSC::DFG::AbstractState::speculateInt32Binary):
+ (JSC::DFG::AbstractState::speculateNumberBinary):
+ (JSC::DFG::AbstractState::trySetConstant):
+ * dfg/DFGAbstractValue.h:
+ (AbstractValue):
+ * dfg/DFGAdjacencyList.h:
+ (JSC::DFG::AdjacencyList::AdjacencyList):
+ (JSC::DFG::AdjacencyList::initialize):
+ * dfg/DFGAllocator.h: Added.
+ (DFG):
+ (Allocator):
+ (JSC::DFG::Allocator::Region::size):
+ (JSC::DFG::Allocator::Region::headerSize):
+ (JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
+ (JSC::DFG::Allocator::Region::data):
+ (JSC::DFG::Allocator::Region::isInThisRegion):
+ (JSC::DFG::Allocator::Region::regionFor):
+ (Region):
+ (JSC::DFG::::Allocator):
+ (JSC::DFG::::~Allocator):
+ (JSC::DFG::::allocate):
+ (JSC::DFG::::free):
+ (JSC::DFG::::freeAll):
+ (JSC::DFG::::reset):
+ (JSC::DFG::::indexOf):
+ (JSC::DFG::::allocatorOf):
+ (JSC::DFG::::bumpAllocate):
+ (JSC::DFG::::freeListAllocate):
+ (JSC::DFG::::allocateSlow):
+ (JSC::DFG::::freeRegionsStartingAt):
+ (JSC::DFG::::startBumpingIn):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
+ (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses):
+ (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse):
+ (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize):
+ (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::originalArrayStructure):
+ (JSC::DFG::ArrayMode::alreadyChecked):
+ * dfg/DFGArrayMode.h:
+ (ArrayMode):
+ * dfg/DFGArrayifySlowPathGenerator.h:
+ (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::node):
+ (JSC::DFG::BasicBlock::isInPhis):
+ (JSC::DFG::BasicBlock::isInBlock):
+ (BasicBlock):
+ * dfg/DFGBasicBlockInlines.h:
+ (DFG):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::getDirect):
+ (JSC::DFG::ByteCodeParser::get):
+ (JSC::DFG::ByteCodeParser::setDirect):
+ (JSC::DFG::ByteCodeParser::set):
+ (JSC::DFG::ByteCodeParser::setPair):
+ (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
+ (JSC::DFG::ByteCodeParser::getLocal):
+ (JSC::DFG::ByteCodeParser::setLocal):
+ (JSC::DFG::ByteCodeParser::getArgument):
+ (JSC::DFG::ByteCodeParser::setArgument):
+ (JSC::DFG::ByteCodeParser::flushDirect):
+ (JSC::DFG::ByteCodeParser::getToInt32):
+ (JSC::DFG::ByteCodeParser::toInt32):
+ (JSC::DFG::ByteCodeParser::getJSConstantForValue):
+ (JSC::DFG::ByteCodeParser::getJSConstant):
+ (JSC::DFG::ByteCodeParser::getCallee):
+ (JSC::DFG::ByteCodeParser::getThis):
+ (JSC::DFG::ByteCodeParser::setThis):
+ (JSC::DFG::ByteCodeParser::isJSConstant):
+ (JSC::DFG::ByteCodeParser::isInt32Constant):
+ (JSC::DFG::ByteCodeParser::valueOfJSConstant):
+ (JSC::DFG::ByteCodeParser::valueOfInt32Constant):
+ (JSC::DFG::ByteCodeParser::constantUndefined):
+ (JSC::DFG::ByteCodeParser::constantNull):
+ (JSC::DFG::ByteCodeParser::one):
+ (JSC::DFG::ByteCodeParser::constantNaN):
+ (JSC::DFG::ByteCodeParser::cellConstant):
+ (JSC::DFG::ByteCodeParser::addToGraph):
+ (JSC::DFG::ByteCodeParser::insertPhiNode):
+ (JSC::DFG::ByteCodeParser::addVarArgChild):
+ (JSC::DFG::ByteCodeParser::addCall):
+ (JSC::DFG::ByteCodeParser::addStructureTransitionCheck):
+ (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
+ (JSC::DFG::ByteCodeParser::getPrediction):
+ (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
+ (JSC::DFG::ByteCodeParser::makeSafe):
+ (JSC::DFG::ByteCodeParser::makeDivSafe):
+ (JSC::DFG::ByteCodeParser::ConstantRecord::ConstantRecord):
+ (ConstantRecord):
+ (JSC::DFG::ByteCodeParser::PhiStackEntry::PhiStackEntry):
+ (PhiStackEntry):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::setIntrinsicResult):
+ (JSC::DFG::ByteCodeParser::handleMinMax):
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ (JSC::DFG::ByteCodeParser::getScope):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::processPhiStack):
+ (JSC::DFG::ByteCodeParser::linkBlock):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ (JSC::DFG::ByteCodeParser::parse):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal):
+ (JSC::DFG::CFGSimplificationPhase::fixPhis):
+ (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference):
+ (JSC::DFG::CFGSimplificationPhase::OperandSubstitution::OperandSubstitution):
+ (JSC::DFG::CFGSimplificationPhase::OperandSubstitution::dump):
+ (OperandSubstitution):
+ (JSC::DFG::CFGSimplificationPhase::skipGetLocal):
+ (JSC::DFG::CFGSimplificationPhase::recordNewTarget):
+ (JSC::DFG::CFGSimplificationPhase::fixTailOperand):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::canonicalize):
+ (JSC::DFG::CSEPhase::endIndexForPureCSE):
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::constantCSE):
+ (JSC::DFG::CSEPhase::weakConstantCSE):
+ (JSC::DFG::CSEPhase::getCalleeLoadElimination):
+ (JSC::DFG::CSEPhase::getArrayLengthElimination):
+ (JSC::DFG::CSEPhase::globalVarLoadElimination):
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (JSC::DFG::CSEPhase::globalVarWatchpointElimination):
+ (JSC::DFG::CSEPhase::globalVarStoreElimination):
+ (JSC::DFG::CSEPhase::scopedVarStoreElimination):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkFunctionElimination):
+ (JSC::DFG::CSEPhase::checkExecutableElimination):
+ (JSC::DFG::CSEPhase::checkStructureElimination):
+ (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+ (JSC::DFG::CSEPhase::putByOffsetStoreElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::checkArrayElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getMyScopeLoadElimination):
+ (JSC::DFG::CSEPhase::getLocalLoadElimination):
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ (JSC::DFG::CSEPhase::performSubstitution):
+ (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::eliminate):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+ (CSEPhase):
+ * dfg/DFGCommon.cpp: Added.
+ (DFG):
+ (JSC::DFG::NodePointerTraits::dump):
+ * dfg/DFGCommon.h:
+ (DFG):
+ (JSC::DFG::NodePointerTraits::defaultValue):
+ (NodePointerTraits):
+ (JSC::DFG::verboseCompilationEnabled):
+ (JSC::DFG::shouldDumpGraphAtEachPhase):
+ (JSC::DFG::validationEnabled):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::isCapturedAtOrAfter):
+ (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+ (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::Disassembler):
+ (JSC::DFG::Disassembler::createDumpList):
+ (JSC::DFG::Disassembler::dumpDisassembly):
+ * dfg/DFGDisassembler.h:
+ (JSC::DFG::Disassembler::setForNode):
+ (Disassembler):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGEdge.cpp: Added.
+ (DFG):
+ (JSC::DFG::Edge::dump):
+ * dfg/DFGEdge.h:
+ (JSC::DFG::Edge::Edge):
+ (JSC::DFG::Edge::node):
+ (JSC::DFG::Edge::operator*):
+ (JSC::DFG::Edge::operator->):
+ (Edge):
+ (JSC::DFG::Edge::setNode):
+ (JSC::DFG::Edge::useKind):
+ (JSC::DFG::Edge::setUseKind):
+ (JSC::DFG::Edge::isSet):
+ (JSC::DFG::Edge::shift):
+ (JSC::DFG::Edge::makeWord):
+ (JSC::DFG::operator==):
+ (JSC::DFG::operator!=):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupBlock):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ (JSC::DFG::FixupPhase::fixIntEdge):
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+ (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
+ (FixupPhase):
+ * dfg/DFGGenerationInfo.h:
+ (JSC::DFG::GenerationInfo::GenerationInfo):
+ (JSC::DFG::GenerationInfo::initConstant):
+ (JSC::DFG::GenerationInfo::initInteger):
+ (JSC::DFG::GenerationInfo::initJSValue):
+ (JSC::DFG::GenerationInfo::initCell):
+ (JSC::DFG::GenerationInfo::initBoolean):
+ (JSC::DFG::GenerationInfo::initDouble):
+ (JSC::DFG::GenerationInfo::initStorage):
+ (GenerationInfo):
+ (JSC::DFG::GenerationInfo::node):
+ (JSC::DFG::GenerationInfo::noticeOSRBirth):
+ (JSC::DFG::GenerationInfo::use):
+ (JSC::DFG::GenerationInfo::appendFill):
+ (JSC::DFG::GenerationInfo::appendSpill):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::Graph):
+ (JSC::DFG::Graph::~Graph):
+ (DFG):
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ (JSC::DFG::Graph::amountOfNodeWhiteSpace):
+ (JSC::DFG::Graph::printNodeWhiteSpace):
+ (JSC::DFG::Graph::dump):
+ (JSC::DFG::Graph::dumpBlockHeader):
+ (JSC::DFG::Graph::refChildren):
+ (JSC::DFG::Graph::derefChildren):
+ (JSC::DFG::Graph::predictArgumentTypes):
+ (JSC::DFG::Graph::collectGarbage):
+ (JSC::DFG::Graph::determineReachability):
+ (JSC::DFG::Graph::resetExitStates):
+ * dfg/DFGGraph.h:
+ (Graph):
+ (JSC::DFG::Graph::ref):
+ (JSC::DFG::Graph::deref):
+ (JSC::DFG::Graph::changeChild):
+ (JSC::DFG::Graph::compareAndSwap):
+ (JSC::DFG::Graph::clearAndDerefChild):
+ (JSC::DFG::Graph::clearAndDerefChild1):
+ (JSC::DFG::Graph::clearAndDerefChild2):
+ (JSC::DFG::Graph::clearAndDerefChild3):
+ (JSC::DFG::Graph::convertToConstant):
+ (JSC::DFG::Graph::getJSConstantSpeculation):
+ (JSC::DFG::Graph::addSpeculationMode):
+ (JSC::DFG::Graph::valueAddSpeculationMode):
+ (JSC::DFG::Graph::arithAddSpeculationMode):
+ (JSC::DFG::Graph::addShouldSpeculateInteger):
+ (JSC::DFG::Graph::mulShouldSpeculateInteger):
+ (JSC::DFG::Graph::negateShouldSpeculateInteger):
+ (JSC::DFG::Graph::isConstant):
+ (JSC::DFG::Graph::isJSConstant):
+ (JSC::DFG::Graph::isInt32Constant):
+ (JSC::DFG::Graph::isDoubleConstant):
+ (JSC::DFG::Graph::isNumberConstant):
+ (JSC::DFG::Graph::isBooleanConstant):
+ (JSC::DFG::Graph::isCellConstant):
+ (JSC::DFG::Graph::isFunctionConstant):
+ (JSC::DFG::Graph::isInternalFunctionConstant):
+ (JSC::DFG::Graph::valueOfJSConstant):
+ (JSC::DFG::Graph::valueOfInt32Constant):
+ (JSC::DFG::Graph::valueOfNumberConstant):
+ (JSC::DFG::Graph::valueOfBooleanConstant):
+ (JSC::DFG::Graph::valueOfFunctionConstant):
+ (JSC::DFG::Graph::valueProfileFor):
+ (JSC::DFG::Graph::methodOfGettingAValueProfileFor):
+ (JSC::DFG::Graph::numSuccessors):
+ (JSC::DFG::Graph::successor):
+ (JSC::DFG::Graph::successorForCondition):
+ (JSC::DFG::Graph::isPredictedNumerical):
+ (JSC::DFG::Graph::byValIsPure):
+ (JSC::DFG::Graph::clobbersWorld):
+ (JSC::DFG::Graph::varArgNumChildren):
+ (JSC::DFG::Graph::numChildren):
+ (JSC::DFG::Graph::varArgChild):
+ (JSC::DFG::Graph::child):
+ (JSC::DFG::Graph::voteNode):
+ (JSC::DFG::Graph::voteChildren):
+ (JSC::DFG::Graph::substitute):
+ (JSC::DFG::Graph::substituteGetLocal):
+ (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
+ (JSC::DFG::Graph::mulImmediateShouldSpeculateInteger):
+ * dfg/DFGInsertionSet.h:
+ (JSC::DFG::Insertion::Insertion):
+ (JSC::DFG::Insertion::element):
+ (Insertion):
+ (JSC::DFG::InsertionSet::insert):
+ (InsertionSet):
+ * dfg/DFGJITCompiler.cpp:
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::setForNode):
+ (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+ (JSC::DFG::JITCompiler::noticeOSREntry):
+ * dfg/DFGLongLivedState.cpp: Added.
+ (DFG):
+ (JSC::DFG::LongLivedState::LongLivedState):
+ (JSC::DFG::LongLivedState::~LongLivedState):
+ (JSC::DFG::LongLivedState::shrinkToFit):
+ * dfg/DFGLongLivedState.h: Added.
+ (DFG):
+ (LongLivedState):
+ * dfg/DFGMinifiedID.h:
+ (JSC::DFG::MinifiedID::MinifiedID):
+ (JSC::DFG::MinifiedID::node):
+ * dfg/DFGMinifiedNode.cpp:
+ (JSC::DFG::MinifiedNode::fromNode):
+ * dfg/DFGMinifiedNode.h:
+ (MinifiedNode):
+ * dfg/DFGNode.cpp: Added.
+ (DFG):
+ (JSC::DFG::Node::index):
+ (WTF):
+ (WTF::printInternal):
+ * dfg/DFGNode.h:
+ (DFG):
+ (JSC::DFG::Node::Node):
+ (Node):
+ (JSC::DFG::Node::convertToGetByOffset):
+ (JSC::DFG::Node::convertToPutByOffset):
+ (JSC::DFG::Node::ref):
+ (JSC::DFG::Node::shouldSpeculateInteger):
+ (JSC::DFG::Node::shouldSpeculateIntegerForArithmetic):
+ (JSC::DFG::Node::shouldSpeculateIntegerExpectingDefined):
+ (JSC::DFG::Node::shouldSpeculateDoubleForArithmetic):
+ (JSC::DFG::Node::shouldSpeculateNumber):
+ (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
+ (JSC::DFG::Node::shouldSpeculateFinalObject):
+ (JSC::DFG::Node::shouldSpeculateArray):
+ (JSC::DFG::Node::dumpChildren):
+ (WTF):
+ * dfg/DFGNodeAllocator.h: Added.
+ (DFG):
+ (operator new ):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ (SpeculationFailureDebugInfo):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGPhase.cpp:
+ (DFG):
+ (JSC::DFG::Phase::beginPhase):
+ (JSC::DFG::Phase::endPhase):
+ * dfg/DFGPhase.h:
+ (Phase):
+ (JSC::DFG::runAndLog):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::setPrediction):
+ (JSC::DFG::PredictionPropagationPhase::mergePrediction):
+ (JSC::DFG::PredictionPropagationPhase::isNotNegZero):
+ (JSC::DFG::PredictionPropagationPhase::isNotZero):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoForConstant):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoNonRecursive):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwo):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags):
+ (JSC::DFG::PredictionPropagationPhase::propagateForward):
+ (JSC::DFG::PredictionPropagationPhase::propagateBackward):
+ (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGScoreBoard.h:
+ (JSC::DFG::ScoreBoard::ScoreBoard):
+ (JSC::DFG::ScoreBoard::use):
+ (JSC::DFG::ScoreBoard::useIfHasResult):
+ (ScoreBoard):
+ * dfg/DFGSilentRegisterSavePlan.h:
+ (JSC::DFG::SilentRegisterSavePlan::SilentRegisterSavePlan):
+ (JSC::DFG::SilentRegisterSavePlan::node):
+ (SilentRegisterSavePlan):
+ * dfg/DFGSlowPathGenerator.h:
+ (JSC::DFG::SlowPathGenerator::SlowPathGenerator):
+ (JSC::DFG::SlowPathGenerator::generate):
+ (SlowPathGenerator):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+ (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+ (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
+ (JSC::DFG::SpeculativeJIT::silentSpill):
+ (JSC::DFG::SpeculativeJIT::silentFill):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ (JSC::DFG::SpeculativeJIT::fillStorage):
+ (JSC::DFG::SpeculativeJIT::useChildren):
+ (JSC::DFG::SpeculativeJIT::isStrictInt32):
+ (JSC::DFG::SpeculativeJIT::isKnownInteger):
+ (JSC::DFG::SpeculativeJIT::isKnownNumeric):
+ (JSC::DFG::SpeculativeJIT::isKnownCell):
+ (JSC::DFG::SpeculativeJIT::isKnownNotCell):
+ (JSC::DFG::SpeculativeJIT::isKnownNotInteger):
+ (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
+ (JSC::DFG::SpeculativeJIT::writeBarrier):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompare):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
+ (JSC::DFG::GPRTemporary::GPRTemporary):
+ (JSC::DFG::FPRTemporary::FPRTemporary):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::noticeOSRBirth):
+ (JSC::DFG::SpeculativeJIT::compileMovHint):
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+ (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+ (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+ (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
+ (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32):
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
+ (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+ (JSC::DFG::SpeculativeJIT::compileSoftModulo):
+ (JSC::DFG::SpeculativeJIT::compileAdd):
+ (JSC::DFG::SpeculativeJIT::compileArithSub):
+ (JSC::DFG::SpeculativeJIT::compileArithNegate):
+ (JSC::DFG::SpeculativeJIT::compileArithMul):
+ (JSC::DFG::SpeculativeJIT::compileIntegerArithDivForX86):
+ (JSC::DFG::SpeculativeJIT::compileArithMod):
+ (JSC::DFG::SpeculativeJIT::compare):
+ (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+ (JSC::DFG::SpeculativeJIT::compileStrictEq):
+ (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
+ (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
+ (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+ (JSC::DFG::SpeculativeJIT::compileNewFunctionNoCheck):
+ (JSC::DFG::SpeculativeJIT::compileNewFunctionExpression):
+ (JSC::DFG::SpeculativeJIT::compileRegExpExec):
+ (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+ (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::canReuse):
+ (JSC::DFG::SpeculativeJIT::isFilled):
+ (JSC::DFG::SpeculativeJIT::isFilledDouble):
+ (JSC::DFG::SpeculativeJIT::use):
+ (JSC::DFG::SpeculativeJIT::isConstant):
+ (JSC::DFG::SpeculativeJIT::isJSConstant):
+ (JSC::DFG::SpeculativeJIT::isInt32Constant):
+ (JSC::DFG::SpeculativeJIT::isDoubleConstant):
+ (JSC::DFG::SpeculativeJIT::isNumberConstant):
+ (JSC::DFG::SpeculativeJIT::isBooleanConstant):
+ (JSC::DFG::SpeculativeJIT::isFunctionConstant):
+ (JSC::DFG::SpeculativeJIT::valueOfInt32Constant):
+ (JSC::DFG::SpeculativeJIT::valueOfNumberConstant):
+ (JSC::DFG::SpeculativeJIT::valueOfNumberConstantAsInt32):
+ (JSC::DFG::SpeculativeJIT::addressOfDoubleConstant):
+ (JSC::DFG::SpeculativeJIT::valueOfJSConstant):
+ (JSC::DFG::SpeculativeJIT::valueOfBooleanConstant):
+ (JSC::DFG::SpeculativeJIT::valueOfFunctionConstant):
+ (JSC::DFG::SpeculativeJIT::isNullConstant):
+ (JSC::DFG::SpeculativeJIT::valueOfJSConstantAsImm64):
+ (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
+ (JSC::DFG::SpeculativeJIT::integerResult):
+ (JSC::DFG::SpeculativeJIT::noResult):
+ (JSC::DFG::SpeculativeJIT::cellResult):
+ (JSC::DFG::SpeculativeJIT::booleanResult):
+ (JSC::DFG::SpeculativeJIT::jsValueResult):
+ (JSC::DFG::SpeculativeJIT::storageResult):
+ (JSC::DFG::SpeculativeJIT::doubleResult):
+ (JSC::DFG::SpeculativeJIT::initConstantInfo):
+ (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheck):
+ (JSC::DFG::SpeculativeJIT::isInteger):
+ (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
+ (JSC::DFG::SpeculativeJIT::setNodeForOperand):
+ (JSC::DFG::IntegerOperand::IntegerOperand):
+ (JSC::DFG::IntegerOperand::node):
+ (JSC::DFG::IntegerOperand::gpr):
+ (JSC::DFG::IntegerOperand::use):
+ (IntegerOperand):
+ (JSC::DFG::DoubleOperand::DoubleOperand):
+ (JSC::DFG::DoubleOperand::node):
+ (JSC::DFG::DoubleOperand::fpr):
+ (JSC::DFG::DoubleOperand::use):
+ (DoubleOperand):
+ (JSC::DFG::JSValueOperand::JSValueOperand):
+ (JSC::DFG::JSValueOperand::node):
+ (JSC::DFG::JSValueOperand::gpr):
+ (JSC::DFG::JSValueOperand::fill):
+ (JSC::DFG::JSValueOperand::use):
+ (JSValueOperand):
+ (JSC::DFG::StorageOperand::StorageOperand):
+ (JSC::DFG::StorageOperand::node):
+ (JSC::DFG::StorageOperand::gpr):
+ (JSC::DFG::StorageOperand::use):
+ (StorageOperand):
+ (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateIntegerOperand::node):
+ (JSC::DFG::SpeculateIntegerOperand::gpr):
+ (JSC::DFG::SpeculateIntegerOperand::use):
+ (SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateStrictInt32Operand::SpeculateStrictInt32Operand):
+ (JSC::DFG::SpeculateStrictInt32Operand::node):
+ (JSC::DFG::SpeculateStrictInt32Operand::gpr):
+ (JSC::DFG::SpeculateStrictInt32Operand::use):
+ (SpeculateStrictInt32Operand):
+ (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateDoubleOperand::node):
+ (JSC::DFG::SpeculateDoubleOperand::fpr):
+ (JSC::DFG::SpeculateDoubleOperand::use):
+ (SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::node):
+ (JSC::DFG::SpeculateCellOperand::gpr):
+ (JSC::DFG::SpeculateCellOperand::use):
+ (SpeculateCellOperand):
+ (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
+ (JSC::DFG::SpeculateBooleanOperand::node):
+ (JSC::DFG::SpeculateBooleanOperand::gpr):
+ (JSC::DFG::SpeculateBooleanOperand::use):
+ (SpeculateBooleanOperand):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToNumber):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToInt32):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeUInt32ToNumber):
+ (JSC::DFG::SpeculativeJIT::cachedPutById):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileIntegerCompare):
+ (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
+ (JSC::DFG::SpeculativeJIT::compileValueAdd):
+ (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToNumber):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToInt32):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeUInt32ToNumber):
+ (JSC::DFG::SpeculativeJIT::cachedPutById):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileIntegerCompare):
+ (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
+ (JSC::DFG::SpeculativeJIT::compileValueAdd):
+ (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureAbstractValue.h:
+ (StructureAbstractValue):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * dfg/DFGValidate.cpp:
+ (DFG):
+ (Validate):
+ (JSC::DFG::Validate::validate):
+ (JSC::DFG::Validate::reportValidationContext):
+ * dfg/DFGValidate.h:
+ * dfg/DFGValueSource.cpp:
+ (JSC::DFG::ValueSource::dump):
+ * dfg/DFGValueSource.h:
+ (JSC::DFG::ValueSource::ValueSource):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ (JSC::DFG::VirtualRegisterAllocationPhase::run):
+ * runtime/FunctionExecutableDump.cpp: Added.
+ (JSC):
+ (JSC::FunctionExecutableDump::dump):
+ * runtime/FunctionExecutableDump.h: Added.
+ (JSC):
+ (FunctionExecutableDump):
+ (JSC::FunctionExecutableDump::FunctionExecutableDump):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (DFG):
+ (JSGlobalData):
+ * runtime/Options.h:
+ (JSC):
+
+2013-01-28 Laszlo Gombos <l.gombos@samsung.com>
+
+ Collapse testing for a list of PLATFORM() into OS() and USE() tests
+ https://bugs.webkit.org/show_bug.cgi?id=108018
+
+ Reviewed by Eric Seidel.
+
+ No functional change as "OS(DARWIN) && USE(CF)" equals to the
+ following platforms: MAC, WX, QT and CHROMIUM. CHROMIUM
+ is not using JavaScriptCore.
+
+ * runtime/DatePrototype.cpp:
+ (JSC):
+
+2013-01-28 Geoffrey Garen <ggaren@apple.com>
+
+ Static size inference for JavaScript objects
+ https://bugs.webkit.org/show_bug.cgi?id=108093
+
+ Reviewed by Phil Pizlo.
+
+ * API/JSObjectRef.cpp:
+ * JavaScriptCore.order:
+ * JavaScriptCore.xcodeproj/project.pbxproj: Pay the tax man.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode): op_new_object and op_create_this now
+ have an extra inferredInlineCapacity argument. This is the statically
+ inferred inline capacity, just from analyzing source text. op_new_object
+ also gets a pointer to an allocation profile. (For op_create_this, the
+ profile is in the construtor function.)
+
+ (JSC::CodeBlock::CodeBlock): Link op_new_object.
+
+ (JSC::CodeBlock::stronglyVisitStrongReferences): Mark our profiles.
+
+ * bytecode/CodeBlock.h:
+ (CodeBlock): Removed some dead code. Added object allocation profiles.
+
+ * bytecode/Instruction.h:
+ (JSC): New union type, since an instruction operand may point to an
+ object allocation profile now.
+
+ * bytecode/ObjectAllocationProfile.h: Added.
+ (JSC):
+ (ObjectAllocationProfile):
+ (JSC::ObjectAllocationProfile::offsetOfAllocator):
+ (JSC::ObjectAllocationProfile::offsetOfStructure):
+ (JSC::ObjectAllocationProfile::ObjectAllocationProfile):
+ (JSC::ObjectAllocationProfile::isNull):
+ (JSC::ObjectAllocationProfile::initialize):
+ (JSC::ObjectAllocationProfile::structure):
+ (JSC::ObjectAllocationProfile::inlineCapacity):
+ (JSC::ObjectAllocationProfile::clear):
+ (JSC::ObjectAllocationProfile::visitAggregate):
+ (JSC::ObjectAllocationProfile::possibleDefaultPropertyCount): New class
+ for tracking a prediction about object allocation: structure, inline
+ capacity, allocator to use.
+
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName): Updated instruction sizes.
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC):
+ (JSC::UnlinkedCodeBlock::addObjectAllocationProfile):
+ (JSC::UnlinkedCodeBlock::numberOfObjectAllocationProfiles):
+ (UnlinkedCodeBlock): Unlinked support for allocation profiles.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate): Kill all remaining analyses at the
+ end of codegen, since this is our last opportunity.
+
+ (JSC::BytecodeGenerator::BytecodeGenerator): Added a static property
+ analyzer to bytecode generation. It tracks initializing assignments and
+ makes a guess about how many will happen.
+
+ (JSC::BytecodeGenerator::newObjectAllocationProfile):
+ (JSC):
+ (JSC::BytecodeGenerator::emitProfiledOpcode):
+ (JSC::BytecodeGenerator::emitMove):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithThis):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitDirectPutById):
+ (JSC::BytecodeGenerator::emitPutGetterSetter):
+ (JSC::BytecodeGenerator::emitGetArgumentByVal):
+ (JSC::BytecodeGenerator::emitGetByVal): Added hooks to the static property
+ analyzer, so it can observe allocations and stores.
+
+ (JSC::BytecodeGenerator::emitCreateThis): Factored this into a helper
+ function because it was a significant amount of logic, and I wanted to
+ add to it.
+
+ (JSC::BytecodeGenerator::emitNewObject):
+ (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitCallVarargs):
+ (JSC::BytecodeGenerator::emitConstruct): Added a hook to profiled opcodes
+ to track their stores, in case a store kills a profiled allocation. Since
+ profiled opcodes are basically the only interesting stores we do, this
+ is a convenient place to notice any store that might kill an allocation.
+
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator): As above.
+
+ * bytecompiler/StaticPropertyAnalysis.h: Added.
+ (JSC):
+ (StaticPropertyAnalysis):
+ (JSC::StaticPropertyAnalysis::create):
+ (JSC::StaticPropertyAnalysis::addPropertyIndex):
+ (JSC::StaticPropertyAnalysis::record):
+ (JSC::StaticPropertyAnalysis::propertyIndexCount):
+ (JSC::StaticPropertyAnalysis::StaticPropertyAnalysis): Simple helper
+ class for tracking allocations and stores.
+
+ * bytecompiler/StaticPropertyAnalyzer.h: Added.
+ (StaticPropertyAnalyzer):
+ (JSC::StaticPropertyAnalyzer::StaticPropertyAnalyzer):
+ (JSC::StaticPropertyAnalyzer::createThis):
+ (JSC::StaticPropertyAnalyzer::newObject):
+ (JSC::StaticPropertyAnalyzer::putById):
+ (JSC::StaticPropertyAnalyzer::mov):
+ (JSC::StaticPropertyAnalyzer::kill): Helper class for observing allocations
+ and stores and making an inline capacity guess. The heuristics here are
+ intentionally minimal because we don't want this one class to try to
+ re-create something like a DFG or a runtime analysis. If we discover that
+ we need those kinds of analyses, we should just replace this class with
+ something else.
+
+ This class tracks multiple registers that alias the same object -- that
+ happens a lot, when moving locals into temporary registers -- but it
+ doesn't track control flow or multiple objects that alias the same register.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute): Updated for rename.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock): Updated for inline capacity and
+ allocation profile.
+
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasInlineCapacity):
+ (Node):
+ (JSC::DFG::Node::inlineCapacity):
+ (JSC::DFG::Node::hasFunction): Give the graph a good way to represent
+ inline capacity for an allocation.
+
+ * dfg/DFGNodeType.h:
+ (DFG): Updated for rename.
+
+ * dfg/DFGOperations.cpp: Updated for interface change.
+
+ * dfg/DFGOperations.h: We pass the inline capacity to the slow case as
+ an argument. This is the simplest way, since it's stored as a bytecode operand.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate): Updated for rename.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID): Fixed a horrible off-by-one-half bug that only
+ appears when doing an inline cached load for property number 64 on a 32-bit
+ system. In JSVALUE32_64 land, "offsetRelativeToPatchedStorage" is the
+ offset of the 64bit JSValue -- but we'll actually issue two loads, one for
+ the payload at that offset, and one for the tag at that offset + 4. We need
+ to ensure that both loads have a compact representation, or we'll corrupt
+ the instruction stream.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSObject):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Lots of refactoring to support
+ passing an allocator to our allocation function, and/or passing a Structure
+ as a register instead of an immediate.
+
+ * heap/MarkedAllocator.h:
+ (DFG):
+ (MarkedAllocator):
+ (JSC::MarkedAllocator::offsetOfFreeListHead): Added an accessor to simplify
+ JIT code generation of allocation from an arbitrary allocator.
+
+ * jit/JIT.h:
+ (JSC):
+ * jit/JITInlines.h:
+ (JSC):
+ (JSC::JIT::emitAllocateJSObject):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_object):
+ (JSC::JIT::emitSlow_op_new_object):
+ (JSC::JIT::emit_op_create_this):
+ (JSC::JIT::emitSlow_op_create_this):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_new_object):
+ (JSC::JIT::emitSlow_op_new_object):
+ (JSC::JIT::emit_op_create_this):
+ (JSC::JIT::emitSlow_op_create_this): Same refactoring as done for the DFG.
+
+ * jit/JITStubs.cpp:
+ (JSC::tryCacheGetByID): Fixed the same bug mentioned above.
+
+ (JSC::DEFINE_STUB_FUNCTION): Updated for interface changes.
+
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions): Updated for interface changes.
+
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm: Same refactoring as for the JITs.
+
+ * profiler/ProfilerBytecode.cpp:
+ * profiler/ProfilerBytecodes.cpp:
+ * profiler/ProfilerCompilation.cpp:
+ * profiler/ProfilerCompiledBytecode.cpp:
+ * profiler/ProfilerDatabase.cpp:
+ * profiler/ProfilerOSRExit.cpp:
+ * profiler/ProfilerOrigin.cpp:
+ * profiler/ProfilerProfiledBytecodes.cpp: Include ObjectConstructor.h
+ because that's where createEmptyObject() lives now.
+
+ * runtime/Executable.h:
+ (JSC::JSFunction::JSFunction): Updated for rename.
+
+ * runtime/JSCellInlines.h:
+ (JSC::allocateCell): Updated to match the allocator selection code in
+ the JIT, so it's clearer that both are correct.
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::createAllocationProfile):
+ (JSC::JSFunction::visitChildren):
+ (JSC::JSFunction::getOwnPropertySlot):
+ (JSC::JSFunction::put):
+ (JSC::JSFunction::defineOwnProperty):
+ (JSC::JSFunction::getConstructData):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::offsetOfScopeChain):
+ (JSC::JSFunction::offsetOfExecutable):
+ (JSC::JSFunction::offsetOfAllocationProfile):
+ (JSC::JSFunction::allocationProfile):
+ (JSFunction):
+ (JSC::JSFunction::tryGetAllocationProfile):
+ (JSC::JSFunction::addAllocationProfileWatchpoint): Changed inheritorID
+ data member to be an ObjectAllocationProfile, which includes a pointer
+ to the desired allocator. This simplifies JIT code, since we don't have
+ to compute the allocator on the fly. I verified by code inspection that
+ JSFunction is still only 64 bytes.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::dateStructure): No direct pointer to the empty
+ object structure anymore, because now clients need to specify how much
+ inline capacity they want.
+
+ * runtime/JSONObject.cpp:
+ * runtime/JSObject.h:
+ (JSC):
+ (JSFinalObject):
+ (JSC::JSFinalObject::defaultInlineCapacity):
+ (JSC::JSFinalObject::maxInlineCapacity):
+ (JSC::JSFinalObject::createStructure): A little refactoring to try to
+ clarify where some of these constants derive from.
+
+ (JSC::maxOffsetRelativeToPatchedStorage): Used for bug fix, above.
+
+ * runtime/JSProxy.cpp:
+ (JSC::JSProxy::setTarget): Ugly, but effective.
+
+ * runtime/LiteralParser.cpp:
+ * runtime/ObjectConstructor.cpp:
+ (JSC::constructObject):
+ (JSC::constructWithObjectConstructor):
+ (JSC::callObjectConstructor):
+ (JSC::objectConstructorCreate): Updated for interface changes.
+
+ * runtime/ObjectConstructor.h:
+ (JSC::constructEmptyObject): Clarified your options for how to allocate
+ an empty object, to emphasize what things can actually vary.
+
+ * runtime/PropertyOffset.h: These constants have moved because they're
+ really higher level concepts to do with the layout of objects and the
+ collector. PropertyOffset is just an abstract number line, independent
+ of those things.
+
+ * runtime/PrototypeMap.cpp:
+ (JSC::PrototypeMap::emptyObjectStructureForPrototype):
+ (JSC::PrototypeMap::clearEmptyObjectStructureForPrototype):
+ * runtime/PrototypeMap.h:
+ (PrototypeMap): The map key is now a pair of prototype and inline capacity,
+ since Structure encodes inline capacity.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::nonPropertyTransition):
+ (JSC::Structure::copyPropertyTableForPinning):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::totalStorageSize):
+ (JSC::Structure::transitionCount):
+ (JSC::Structure::create): Fixed a nasty refactoring bug that only shows
+ up after enabling variable-sized inline capacities: we were passing our
+ type info where our inline capacity was expected. The compiler didn't
+ notice because both have type int :(.
+
+2013-01-28 Oliver Hunt <oliver@apple.com>
+
+ Add more assertions to the property storage use in arrays
+ https://bugs.webkit.org/show_bug.cgi?id=107728
+
+ Reviewed by Filip Pizlo.
+
+ Add a bunch of assertions to array and object butterfly
+ usage. This should make debugging somewhat easier.
+
+ I also converted a couple of assertions to release asserts
+ as they were so low cost it seemed a sensible thing to do.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::sortVector):
+ (JSC::JSArray::compactForSorting):
+ * runtime/JSObject.h:
+ (JSC::JSObject::getHolyIndexQuickly):
+
+2013-01-28 Adam Barth <abarth@webkit.org>
+
+ Remove webkitNotifications.createHTMLNotification
+ https://bugs.webkit.org/show_bug.cgi?id=107598
+
+ Reviewed by Benjamin Poulain.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-28 Michael Saboff <msaboff@apple.com>
+
+ Cleanup ARM version of debugName() in DFGFPRInfo.h
+ https://bugs.webkit.org/show_bug.cgi?id=108090
+
+ Reviewed by David Kilzer.
+
+ Fixed debugName() so it will compile by adding static_cast<int> and missing commas.
+
+ * dfg/DFGFPRInfo.h:
+ (JSC::DFG::FPRInfo::debugName):
+
+2013-01-27 Andreas Kling <akling@apple.com>
+
+ JSC: FunctionParameters are memory hungry.
+ <http://webkit.org/b/108033>
+ <rdar://problem/13094803>
+
+ Reviewed by Sam Weinig.
+
+ Instead of inheriting from Vector<Identifier>, make FunctionParameters a simple fixed-size array
+ with a custom-allocating create() function. Removes one step of indirection and cuts memory usage
+ roughly in half.
+
+ 2.73 MB progression on Membuster3.
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedFunctionExecutable::paramString):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * parser/Nodes.cpp:
+ (JSC::FunctionParameters::create):
+ (JSC::FunctionParameters::FunctionParameters):
+ (JSC::FunctionParameters::~FunctionParameters):
+ * parser/Nodes.h:
+ (FunctionParameters):
+ (JSC::FunctionParameters::size):
+ (JSC::FunctionParameters::at):
+ (JSC::FunctionParameters::identifiers):
+
+2013-01-27 Andreas Kling <akling@apple.com>
+
+ JSC: SourceProviderCache is memory hungry.
+ <http://webkit.org/b/108029>
+ <rdar://problem/13094806>
+
+ Reviewed by Sam Weinig.
+
+ Use fixed-size arrays for SourceProviderCacheItem's lists of captured variables.
+ Since the lists never change after the object is created, there's no need to keep them in Vectors
+ and we can instead create the whole cache item in a single allocation.
+
+ 13.37 MB progression on Membuster3.
+
+ * parser/Parser.cpp:
+ (JSC::::parseFunctionInfo):
+ * parser/Parser.h:
+ (JSC::Scope::copyCapturedVariablesToVector):
+ (JSC::Scope::fillParametersForSourceProviderCache):
+ (JSC::Scope::restoreFromSourceProviderCache):
+ * parser/SourceProviderCacheItem.h:
+ (SourceProviderCacheItemCreationParameters):
+ (SourceProviderCacheItem):
+ (JSC::SourceProviderCacheItem::approximateByteSize):
+ (JSC::SourceProviderCacheItem::usedVariables):
+ (JSC::SourceProviderCacheItem::writtenVariables):
+ (JSC::SourceProviderCacheItem::~SourceProviderCacheItem):
+ (JSC::SourceProviderCacheItem::create):
+ (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
+
+2013-01-27 Zoltan Arvai <zarvai@inf.u-szeged.hu>
+
+ Fixing atomicIncrement implementation for Windows by dropping support before XP SP2.
+ https://bugs.webkit.org/show_bug.cgi?id=106740
+
+ Reviewed by Benjamin Poulain.
+
+ * config.h:
+
+2013-01-25 Filip Pizlo <fpizlo@apple.com>
+
+ DFG variable event stream shouldn't use NodeIndex
+ https://bugs.webkit.org/show_bug.cgi?id=107996
+
+ Reviewed by Oliver Hunt.
+
+ Introduce the notion of a DFG::MinifiedID, which is just a unique ID of a DFG Node.
+ Internally it currently uses a NodeIndex, but we could change this without having
+ to recode all of the users of MinifiedID. This effectively decouples the OSR exit
+ compiler's way of identifying nodes from the speculative JIT's way of identifying
+ nodes, and should make it easier to make changes to the speculative JIT's internals
+ in the future.
+
+ Also changed variable event stream logging to exclude information about births and
+ deaths of constants, since the OSR exit compiler never cares about which register
+ holds a constant; if a value is constant then the OSR exit compiler can reify it.
+
+ Also changed the variable event stream's value recovery computation to use a
+ HashMap keyed by MinifiedID rather than a Vector indexed by NodeIndex.
+
+ This appears to be performance-neutral. It's primarily meant as a small step
+ towards https://bugs.webkit.org/show_bug.cgi?id=106868.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGGenerationInfo.h:
+ (JSC::DFG::GenerationInfo::GenerationInfo):
+ (JSC::DFG::GenerationInfo::initConstant):
+ (JSC::DFG::GenerationInfo::initInteger):
+ (JSC::DFG::GenerationInfo::initJSValue):
+ (JSC::DFG::GenerationInfo::initCell):
+ (JSC::DFG::GenerationInfo::initBoolean):
+ (JSC::DFG::GenerationInfo::initDouble):
+ (JSC::DFG::GenerationInfo::initStorage):
+ (JSC::DFG::GenerationInfo::noticeOSRBirth):
+ (JSC::DFG::GenerationInfo::use):
+ (JSC::DFG::GenerationInfo::appendFill):
+ (JSC::DFG::GenerationInfo::appendSpill):
+ (GenerationInfo):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ * dfg/DFGMinifiedGraph.h:
+ (JSC::DFG::MinifiedGraph::at):
+ (MinifiedGraph):
+ * dfg/DFGMinifiedID.h: Added.
+ (DFG):
+ (MinifiedID):
+ (JSC::DFG::MinifiedID::MinifiedID):
+ (JSC::DFG::MinifiedID::operator!):
+ (JSC::DFG::MinifiedID::nodeIndex):
+ (JSC::DFG::MinifiedID::operator==):
+ (JSC::DFG::MinifiedID::operator!=):
+ (JSC::DFG::MinifiedID::operator<):
+ (JSC::DFG::MinifiedID::operator>):
+ (JSC::DFG::MinifiedID::operator<=):
+ (JSC::DFG::MinifiedID::operator>=):
+ (JSC::DFG::MinifiedID::hash):
+ (JSC::DFG::MinifiedID::dump):
+ (JSC::DFG::MinifiedID::isHashTableDeletedValue):
+ (JSC::DFG::MinifiedID::invalidID):
+ (JSC::DFG::MinifiedID::otherInvalidID):
+ (JSC::DFG::MinifiedID::fromBits):
+ (JSC::DFG::MinifiedIDHash::hash):
+ (JSC::DFG::MinifiedIDHash::equal):
+ (MinifiedIDHash):
+ (WTF):
+ * dfg/DFGMinifiedNode.cpp:
+ (JSC::DFG::MinifiedNode::fromNode):
+ * dfg/DFGMinifiedNode.h:
+ (JSC::DFG::MinifiedNode::id):
+ (JSC::DFG::MinifiedNode::child1):
+ (JSC::DFG::MinifiedNode::getID):
+ (JSC::DFG::MinifiedNode::compareByNodeIndex):
+ (MinifiedNode):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileMovHint):
+ (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::setNodeIndexForOperand):
+ * dfg/DFGValueSource.cpp:
+ (JSC::DFG::ValueSource::dump):
+ * dfg/DFGValueSource.h:
+ (JSC::DFG::ValueSource::ValueSource):
+ (JSC::DFG::ValueSource::isSet):
+ (JSC::DFG::ValueSource::kind):
+ (JSC::DFG::ValueSource::id):
+ (ValueSource):
+ (JSC::DFG::ValueSource::idFromKind):
+ (JSC::DFG::ValueSource::kindFromID):
+ * dfg/DFGVariableEvent.cpp:
+ (JSC::DFG::VariableEvent::dump):
+ (JSC::DFG::VariableEvent::dumpFillInfo):
+ (JSC::DFG::VariableEvent::dumpSpillInfo):
+ * dfg/DFGVariableEvent.h:
+ (JSC::DFG::VariableEvent::fillGPR):
+ (JSC::DFG::VariableEvent::fillPair):
+ (JSC::DFG::VariableEvent::fillFPR):
+ (JSC::DFG::VariableEvent::spill):
+ (JSC::DFG::VariableEvent::death):
+ (JSC::DFG::VariableEvent::movHint):
+ (JSC::DFG::VariableEvent::id):
+ (VariableEvent):
+ * dfg/DFGVariableEventStream.cpp:
+ (DFG):
+ (JSC::DFG::VariableEventStream::tryToSetConstantRecovery):
+ (JSC::DFG::VariableEventStream::reconstruct):
+ * dfg/DFGVariableEventStream.h:
+ (VariableEventStream):
+
+2013-01-25 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Rename LLInt projects folder and make appropriate changes to solutions.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.sln:
+ * JavaScriptCore.vcxproj/LLInt: Copied from JavaScriptCore.vcxproj/LLInt.vcproj.
+ * JavaScriptCore.vcxproj/LLInt.vcproj: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/LLIntAssembly.make: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/LLIntAssembly.vcxproj: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/LLIntAssembly.vcxproj.user: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/build-LLIntAssembly.sh: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj.user: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj.user: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props: Removed.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props: Removed.
+
+2013-01-24 Roger Fong <roger_fong@apple.com>
+
+ VS2010 JavascriptCore: Clean up property sheets, add a JSC solution, add testRegExp and testAPI projects.
+ https://bugs.webkit.org/show_bug.cgi?id=106987
+
+ Reviewed by Brent Fulgham.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.sln: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreCF.props:
+ * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props:
+ * JavaScriptCore.vcxproj/JavaScriptCorePreLink.cmd:
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props:
+ * JavaScriptCore.vcxproj/jsc/jscCommon.props:
+ * JavaScriptCore.vcxproj/jsc/jscDebug.props:
+ * JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd:
+ * JavaScriptCore.vcxproj/jsc/jscPreLink.cmd:
+ * JavaScriptCore.vcxproj/testRegExp: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj.filters: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpDebug.props: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd: Added.
+ * JavaScriptCore.vcxproj/testRegExp/testRegExpRelease.props: Added.
+ * JavaScriptCore.vcxproj/testapi: Added.
+ * JavaScriptCore.vcxproj/testapi/testapi.vcxproj: Added.
+ * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters: Added.
+ * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiCommon.props: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiDebug.props: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiPostBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiPreLink.cmd: Added.
+ * JavaScriptCore.vcxproj/testapi/testapiRelease.props: Added.
+
+2013-01-24 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+
+2013-01-24 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::JITCompiler::getSpeculation() methods are badly named and superfluous
+ https://bugs.webkit.org/show_bug.cgi?id=107860
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGJITCompiler.h:
+ (JITCompiler):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+
+2013-01-24 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Rename JSValue.h/APIJSValue.h to JSCJSValue.h/JSValue.h
+ https://bugs.webkit.org/show_bug.cgi?id=107327
+
+ Reviewed by Filip Pizlo.
+
+ We're renaming these two files, so we have to replace the names everywhere.
+
+ * API/APICast.h:
+ * API/APIJSValue.h: Removed.
+ * API/JSBlockAdaptor.mm:
+ * API/JSStringRefCF.cpp:
+ * API/JSValue.h: Copied from Source/JavaScriptCore/API/APIJSValue.h.
+ * API/JSValue.mm:
+ * API/JSValueInternal.h:
+ * API/JSValueRef.cpp:
+ * API/JSWeakObjectMapRefPrivate.cpp:
+ * API/JavaScriptCore.h:
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CallLinkStatus.h:
+ * bytecode/CodeBlock.cpp:
+ * bytecode/MethodOfGettingAValueProfile.h:
+ * bytecode/ResolveGlobalStatus.cpp:
+ * bytecode/ResolveGlobalStatus.h:
+ * bytecode/SpeculatedType.h:
+ * bytecode/ValueRecovery.h:
+ * dfg/DFGByteCodeParser.cpp:
+ * dfg/DFGJITCompiler.cpp:
+ * dfg/DFGNode.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ * dfg/DFGSpeculativeJIT64.cpp:
+ * heap/CopiedBlock.h:
+ * heap/HandleStack.cpp:
+ * heap/HandleTypes.h:
+ * heap/WeakImpl.h:
+ * interpreter/Interpreter.h:
+ * interpreter/Register.h:
+ * interpreter/VMInspector.h:
+ * jit/HostCallReturnValue.cpp:
+ * jit/HostCallReturnValue.h:
+ * jit/JITCode.h:
+ * jit/JITExceptions.cpp:
+ * jit/JITExceptions.h:
+ * jit/JSInterfaceJIT.h:
+ * llint/LLIntCLoop.h:
+ * llint/LLIntData.h:
+ * llint/LLIntSlowPaths.cpp:
+ * profiler/ProfilerBytecode.h:
+ * profiler/ProfilerBytecodeSequence.h:
+ * profiler/ProfilerBytecodes.h:
+ * profiler/ProfilerCompilation.h:
+ * profiler/ProfilerCompiledBytecode.h:
+ * profiler/ProfilerDatabase.h:
+ * profiler/ProfilerOSRExit.h:
+ * profiler/ProfilerOSRExitSite.h:
+ * profiler/ProfilerOrigin.h:
+ * profiler/ProfilerOriginStack.h:
+ * runtime/ArgList.cpp:
+ * runtime/CachedTranscendentalFunction.h:
+ * runtime/CallData.h:
+ * runtime/Completion.h:
+ * runtime/ConstructData.h:
+ * runtime/DateConstructor.cpp:
+ * runtime/DateInstance.cpp:
+ * runtime/DatePrototype.cpp:
+ * runtime/JSAPIValueWrapper.h:
+ * runtime/JSCJSValue.cpp: Copied from Source/JavaScriptCore/runtime/JSValue.cpp.
+ * runtime/JSCJSValue.h: Copied from Source/JavaScriptCore/runtime/JSValue.h.
+ (JSValue):
+ * runtime/JSCJSValueInlines.h: Copied from Source/JavaScriptCore/runtime/JSValueInlines.h.
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/JSStringJoiner.h:
+ * runtime/JSValue.cpp: Removed.
+ * runtime/JSValue.h: Removed.
+ * runtime/JSValueInlines.h: Removed.
+ * runtime/LiteralParser.h:
+ * runtime/Operations.h:
+ * runtime/PropertyDescriptor.h:
+ * runtime/PropertySlot.h:
+ * runtime/Protect.h:
+ * runtime/RegExpPrototype.cpp:
+ * runtime/Structure.h:
+
+2013-01-23 Oliver Hunt <oliver@apple.com>
+
+ Harden JSC a bit with RELEASE_ASSERT
+ https://bugs.webkit.org/show_bug.cgi?id=107766
+
+ Reviewed by Mark Hahnenberg.
+
+ Went through and replaced a pile of ASSERTs that were covering
+ significantly important details (bounds checks, etc) where
+ having the checks did not impact release performance in any
+ measurable way.
+
+ * API/JSContextRef.cpp:
+ (JSContextCreateBacktrace):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::branchAdd32):
+ (JSC::MacroAssembler::branchMul32):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::handlerForBytecodeOffset):
+ (JSC::CodeBlock::lineNumberForBytecodeOffset):
+ (JSC::CodeBlock::bytecodeOffset):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::bytecodeOffsetForCallAtIndex):
+ (JSC::CodeBlock::bytecodeOffset):
+ (JSC::CodeBlock::exceptionHandler):
+ (JSC::CodeBlock::codeOrigin):
+ (JSC::CodeBlock::immediateSwitchJumpTable):
+ (JSC::CodeBlock::characterSwitchJumpTable):
+ (JSC::CodeBlock::stringSwitchJumpTable):
+ (JSC::CodeBlock::setIdentifiers):
+ (JSC::baselineCodeBlockForInlineCallFrame):
+ (JSC::ExecState::uncheckedR):
+ * bytecode/CodeOrigin.cpp:
+ (JSC::CodeOrigin::inlineStack):
+ * bytecode/CodeOrigin.h:
+ (JSC::CodeOrigin::CodeOrigin):
+ * dfg/DFGCSEPhase.cpp:
+ * dfg/DFGOSRExit.cpp:
+ * dfg/DFGScratchRegisterAllocator.h:
+ (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer):
+ (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::allocate):
+ (JSC::DFG::SpeculativeJIT::spill):
+ (JSC::DFG::SpeculativeJIT::integerResult):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGValueSource.h:
+ (JSC::DFG::dataFormatToValueSourceKind):
+ (JSC::DFG::ValueSource::ValueSource):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::BlockAllocator):
+ (JSC::BlockAllocator::releaseFreeRegions):
+ (JSC::BlockAllocator::blockFreeingThreadMain):
+ * heap/Heap.cpp:
+ (JSC::Heap::lastChanceToFinalize):
+ (JSC::Heap::collect):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ * jit/GCAwareJITStubRoutine.cpp:
+ (JSC::GCAwareJITStubRoutine::observeZeroRefCount):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JITExceptions.cpp:
+ (JSC::genericThrow):
+ * jit/JITInlines.h:
+ (JSC::JIT::emitLoad):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_end):
+ (JSC::JIT::emit_resolve_operations):
+ * jit/JITStubRoutine.cpp:
+ (JSC::JITStubRoutine::observeZeroRefCount):
+ * jit/JITStubs.cpp:
+ (JSC::returnToThrowTrampoline):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::getOwnPropertySlot):
+ (JSC::Arguments::getOwnPropertyDescriptor):
+ (JSC::Arguments::deleteProperty):
+ (JSC::Arguments::defineOwnProperty):
+ (JSC::Arguments::didTearOffActivation):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::shift):
+ (JSC::unshift):
+ (JSC::arrayProtoFuncLastIndexOf):
+ * runtime/ButterflyInlines.h:
+ (JSC::Butterfly::growPropertyStorage):
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/CodeCache.h:
+ (JSC::CacheMap::add):
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::EvalExecutable::unlinkCalls):
+ (JSC::ProgramExecutable::compileOptimized):
+ (JSC::ProgramExecutable::unlinkCalls):
+ (JSC::ProgramExecutable::initializeGlobalProperties):
+ (JSC::FunctionExecutable::baselineCodeBlockFor):
+ (JSC::FunctionExecutable::compileOptimizedForCall):
+ (JSC::FunctionExecutable::compileOptimizedForConstruct):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ (JSC::FunctionExecutable::unlinkCalls):
+ (JSC::NativeExecutable::hashFor):
+ * runtime/Executable.h:
+ (JSC::EvalExecutable::compile):
+ (JSC::ProgramExecutable::compile):
+ (JSC::FunctionExecutable::compileForCall):
+ (JSC::FunctionExecutable::compileForConstruct):
+ * runtime/IndexingHeader.h:
+ (JSC::IndexingHeader::setVectorLength):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::pop):
+ (JSC::JSArray::shiftCountWithArrayStorage):
+ (JSC::JSArray::shiftCountWithAnyIndexingType):
+ (JSC::JSArray::unshiftCountWithArrayStorage):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::jsStrDecimalLiteral):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly):
+ (JSC::JSObject::defineOwnIndexedProperty):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ * runtime/JSString.cpp:
+ (JSC::JSRopeString::getIndexSlowCase):
+ * yarr/YarrInterpreter.cpp:
+ (JSC::Yarr::Interpreter::popParenthesesDisjunctionContext):
+
+2013-01-23 Filip Pizlo <fpizlo@apple.com>
+
+ Constant folding an access to an uncaptured variable that is captured later in the same basic block shouldn't lead to assertion failures
+ https://bugs.webkit.org/show_bug.cgi?id=107750
+ <rdar://problem/12387265>
+
+ Reviewed by Mark Hahnenberg.
+
+ The point of this assertion was that if there is no variable capturing going on, then there should only be one GetLocal
+ for the variable anywhere in the basic block. But if there is some capturing, then we'll have an unbounded number of
+ GetLocals. The assertion was too imprecise for the latter case. I want to keep this assertion, so I introduced a
+ checker that verifies this precisely: if there are any captured accesses to the variable anywhere at or after the
+ GetLocal we are eliminating, then we allow redundant GetLocals.
+
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (ConstantFoldingPhase):
+ (JSC::DFG::ConstantFoldingPhase::isCapturedAtOrAfter):
+
+2013-01-23 Oliver Hunt <oliver@apple.com>
+
+ Replace ASSERT_NOT_REACHED with RELEASE_ASSERT_NOT_REACHED in JSC
+ https://bugs.webkit.org/show_bug.cgi?id=107736
+
+ Reviewed by Mark Hahnenberg.
+
+ Mechanical change with no performance impact.
+
+ * API/JSBlockAdaptor.mm:
+ (BlockArgumentTypeDelegate::typeVoid):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::construct):
+ (JSC::::call):
+ * API/JSScriptRef.cpp:
+ * API/ObjCCallbackFunction.mm:
+ (ArgumentTypeDelegate::typeVoid):
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::link):
+ (JSC::ARMv7Assembler::replaceWithLoad):
+ (JSC::ARMv7Assembler::replaceWithAddressComputation):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::invert):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::countLeadingZeros32):
+ (JSC::MacroAssemblerARM::divDouble):
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::absDouble):
+ (JSC::MacroAssemblerMIPS::replaceWithJump):
+ (JSC::MacroAssemblerMIPS::maxJumpReplacementSize):
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::absDouble):
+ (JSC::MacroAssemblerSH4::replaceWithJump):
+ (JSC::MacroAssemblerSH4::maxJumpReplacementSize):
+ * assembler/SH4Assembler.h:
+ (JSC::SH4Assembler::shllImm8r):
+ (JSC::SH4Assembler::shlrImm8r):
+ (JSC::SH4Assembler::cmplRegReg):
+ (JSC::SH4Assembler::branch):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::replaceWithLoad):
+ (JSC::X86Assembler::replaceWithAddressComputation):
+ * bytecode/CallLinkInfo.cpp:
+ (JSC::CallLinkInfo::unlink):
+ * bytecode/CodeBlock.cpp:
+ (JSC::debugHookName):
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::CodeBlock::printGetByIdCacheStatus):
+ (JSC::CodeBlock::visitAggregate):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::usesOpcode):
+ * bytecode/DataFormat.h:
+ (JSC::needDataFormatConversion):
+ * bytecode/ExitKind.cpp:
+ (JSC::exitKindToString):
+ (JSC::exitKindIsCountable):
+ * bytecode/MethodOfGettingAValueProfile.cpp:
+ (JSC::MethodOfGettingAValueProfile::getSpecFailBucket):
+ * bytecode/Opcode.h:
+ (JSC::opcodeLength):
+ * bytecode/PolymorphicPutByIdList.cpp:
+ (JSC::PutByIdAccess::fromStructureStubInfo):
+ (JSC::PutByIdAccess::visitWeak):
+ * bytecode/StructureStubInfo.cpp:
+ (JSC::StructureStubInfo::deref):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::ResolveResult::checkValidity):
+ (JSC::BytecodeGenerator::emitGetLocalVar):
+ (JSC::BytecodeGenerator::beginSwitch):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::emitReadModifyAssignment):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::makeSafe):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal):
+ (JSC::DFG::CFGSimplificationPhase::fixTailOperand):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::canHandleOpcodes):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::useKindToString):
+ * dfg/DFGDoubleFormatState.h:
+ (JSC::DFG::mergeDoubleFormatStates):
+ (JSC::DFG::doubleFormatStateToString):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::clobbersWorld):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::valueOfJSConstant):
+ (JSC::DFG::Node::successor):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::nodeFlagsAsString):
+ * dfg/DFGNodeType.h:
+ (JSC::DFG::defaultFlags):
+ * dfg/DFGRepatch.h:
+ (JSC::DFG::dfgResetGetByID):
+ (JSC::DFG::dfgResetPutByID):
+ * dfg/DFGSlowPathGenerator.h:
+ (JSC::DFG::SlowPathGenerator::call):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+ (JSC::DFG::SpeculativeJIT::silentSpill):
+ (JSC::DFG::SpeculativeJIT::silentFill):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::bitOp):
+ (JSC::DFG::SpeculativeJIT::shiftOp):
+ (JSC::DFG::SpeculativeJIT::integerResult):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * dfg/DFGValueSource.h:
+ (JSC::DFG::ValueSource::valueRecovery):
+ * dfg/DFGVariableEvent.cpp:
+ (JSC::DFG::VariableEvent::dump):
+ * dfg/DFGVariableEventStream.cpp:
+ (JSC::DFG::VariableEventStream::reconstruct):
+ * heap/BlockAllocator.h:
+ (JSC::BlockAllocator::regionSetFor):
+ * heap/GCThread.cpp:
+ (JSC::GCThread::gcThreadMain):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::sweepHelper):
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::isLive):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::inlineCallFrame):
+ * interpreter/Interpreter.cpp:
+ (JSC::getCallerInfo):
+ (JSC::getStackFrameCodeType):
+ (JSC::Interpreter::execute):
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::FixedVMPoolExecutableAllocator::notifyPageIsFree):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emitSlow_op_mod):
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emitBinaryDoubleOp):
+ (JSC::JIT::emitSlow_op_mod):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::isDirectPutById):
+ * jit/JITStubs.cpp:
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ * parser/Lexer.cpp:
+ (JSC::::lex):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::emitBytecodeInConditionContext):
+ * parser/Parser.h:
+ (JSC::Parser::getTokenName):
+ (JSC::Parser::updateErrorMessageSpecialCase):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::operatorStackPop):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::tearOffForInlineCallFrame):
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ * runtime/Executable.cpp:
+ (JSC::samplingDescription):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::unlinkCalls):
+ * runtime/Identifier.cpp:
+ (JSC):
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::getCallData):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::push):
+ (JSC::JSArray::sort):
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::defaultValue):
+ (JSC::JSCell::getOwnPropertyNames):
+ (JSC::JSCell::getOwnNonIndexPropertyNames):
+ (JSC::JSCell::className):
+ (JSC::JSCell::getPropertyNames):
+ (JSC::JSCell::customHasInstance):
+ (JSC::JSCell::putDirectVirtual):
+ (JSC::JSCell::defineOwnProperty):
+ (JSC::JSCell::getOwnPropertyDescriptor):
+ * runtime/JSCell.h:
+ (JSCell):
+ * runtime/JSNameScope.cpp:
+ (JSC::JSNameScope::put):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getOwnPropertySlotByIndex):
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::ensureArrayStorageSlow):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::putByIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectIndexBeyondVectorLength):
+ (JSC::JSObject::getOwnPropertyDescriptor):
+ * runtime/JSObject.h:
+ (JSC::JSObject::canGetIndexQuickly):
+ (JSC::JSObject::getIndexQuickly):
+ (JSC::JSObject::tryGetIndexQuickly):
+ (JSC::JSObject::canSetIndexQuickly):
+ (JSC::JSObject::canSetIndexQuicklyForPutDirect):
+ (JSC::JSObject::setIndexQuickly):
+ (JSC::JSObject::initializeIndex):
+ (JSC::JSObject::hasSparseMap):
+ (JSC::JSObject::inSparseIndexingMode):
+ * runtime/JSScope.cpp:
+ (JSC::JSScope::isDynamicScope):
+ * runtime/JSSymbolTableObject.cpp:
+ (JSC::JSSymbolTableObject::putDirectVirtual):
+ * runtime/JSSymbolTableObject.h:
+ (JSSymbolTableObject):
+ * runtime/LiteralParser.cpp:
+ (JSC::::parse):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::compile):
+ (JSC::RegExp::compileMatchOnly):
+ * runtime/StructureTransitionTable.h:
+ (JSC::newIndexingType):
+ * tools/CodeProfile.cpp:
+ (JSC::CodeProfile::sample):
+ * yarr/YarrCanonicalizeUCS2.h:
+ (JSC::Yarr::getCanonicalPair):
+ (JSC::Yarr::areCanonicallyEquivalent):
+ * yarr/YarrInterpreter.cpp:
+ (JSC::Yarr::Interpreter::matchCharacterClass):
+ (JSC::Yarr::Interpreter::matchBackReference):
+ (JSC::Yarr::Interpreter::backtrackParenthesesTerminalEnd):
+ (JSC::Yarr::Interpreter::matchParentheses):
+ (JSC::Yarr::Interpreter::backtrackParentheses):
+ (JSC::Yarr::Interpreter::matchDisjunction):
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::generateTerm):
+ (JSC::Yarr::YarrGenerator::backtrackTerm):
+ * yarr/YarrParser.h:
+ (JSC::Yarr::Parser::CharacterClassParserDelegate::assertionWordBoundary):
+ (JSC::Yarr::Parser::CharacterClassParserDelegate::atomBackReference):
+ * yarr/YarrPattern.cpp:
+ (JSC::Yarr::YarrPatternConstructor::atomCharacterClassBuiltIn):
+
+2013-01-23 Tony Chang <tony@chromium.org>
+
+ Unreviewed, set svn:eol-style to CRLF on Windows .sln files.
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln: Modified property svn:eol-style.
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Modified property svn:eol-style.
+
+2013-01-23 Oliver Hunt <oliver@apple.com>
+
+ Replace numerous manual CRASH's in JSC with RELEASE_ASSERT
+ https://bugs.webkit.org/show_bug.cgi?id=107726
+
+ Reviewed by Filip Pizlo.
+
+ Fairly manual change from if (foo) CRASH(); to RELEASE_ASSERT(!foo);
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::branchAdd32):
+ (JSC::MacroAssembler::branchMul32):
+ * bytecode/CodeBlockHash.cpp:
+ (JSC::CodeBlockHash::CodeBlockHash):
+ * heap/BlockAllocator.h:
+ (JSC::Region::create):
+ (JSC::Region::createCustomSize):
+ * heap/GCAssertions.h:
+ * heap/HandleSet.cpp:
+ (JSC::HandleSet::visitStrongHandles):
+ (JSC::HandleSet::writeBarrier):
+ * heap/HandleSet.h:
+ (JSC::HandleSet::allocate):
+ * heap/Heap.cpp:
+ (JSC::Heap::collect):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::validate):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * jit/ExecutableAllocator.cpp:
+ (JSC::DemandExecutableAllocator::allocateNewSpace):
+ (JSC::ExecutableAllocator::allocate):
+ * jit/ExecutableAllocator.h:
+ (JSC::roundUpAllocationSize):
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator):
+ (JSC::ExecutableAllocator::allocate):
+ * runtime/ButterflyInlines.h:
+ (JSC::Butterfly::createUninitialized):
+ * runtime/Completion.cpp:
+ (JSC::evaluate):
+ * runtime/JSArray.h:
+ (JSC::constructArray):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::slowValidateCell):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+ (JSC::JSObject::createArrayStorage):
+ * tools/TieredMMapArray.h:
+ (JSC::TieredMMapArray::append):
+ * yarr/YarrInterpreter.cpp:
+ (JSC::Yarr::Interpreter::allocDisjunctionContext):
+ (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext):
+ (JSC::Yarr::Interpreter::InputStream::readChecked):
+ (JSC::Yarr::Interpreter::InputStream::uncheckInput):
+ (JSC::Yarr::Interpreter::InputStream::atEnd):
+ (JSC::Yarr::Interpreter::interpret):
+
+2013-01-22 Filip Pizlo <fpizlo@apple.com>
+
+ Convert CSE phase to not rely too much on NodeIndex
+ https://bugs.webkit.org/show_bug.cgi?id=107616
+
+ Reviewed by Geoffrey Garen.
+
+ - Instead of looping over the graph (which assumes that you can simply loop over all
+ nodes without considering blocks first) to reset node.replacement, do that in the
+ loop that sets up relevantToOSR, just before running CSE on the block.
+
+ - Instead of having a relevantToOSR bitvector indexed by NodeIndex, made
+ NodeRelevantToOSR be a NodeFlag. We had exactly one bit left in NodeFlags, so I did
+ some reshuffling to fit it in.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::CSEPhase):
+ (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+ (CSEPhase):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGNodeType.h:
+ (DFG):
+
+2013-01-21 Kentaro Hara <haraken@chromium.org>
+
+ Implement UIEvent constructor
+ https://bugs.webkit.org/show_bug.cgi?id=107430
+
+ Reviewed by Adam Barth.
+
+ Editor's draft: https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm
+
+ UIEvent constructor is implemented under a DOM4_EVENTS_CONSTRUCTOR flag,
+ which is enabled on Safari and Chromium for now.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-22 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed VS2010 build fix following r140259.
+
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+
+2013-01-22 Roger Fong <roger_fong@apple.com>
+
+ JavaScriptCore property sheets, project files and modified build scripts.
+ https://bugs.webkit.org/show_bug.cgi?id=106987
+
+ Reviewed by Brent Fulgham.
+
+ * JavaScriptCore.vcxproj: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCore.resources: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCore.resources/Info.plist: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreCF.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreCommon.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreDebug.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreExports.def: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGeneratedCommon.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGeneratedDebug.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreGeneratedRelease.props: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCorePreLink.cmd: Added.
+ * JavaScriptCore.vcxproj/JavaScriptCoreRelease.props: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/LLIntAssembly.make: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/LLIntAssembly.vcxproj: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/LLIntAssembly.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntAssembly/build-LLIntAssembly.sh: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props: Added.
+ * JavaScriptCore.vcxproj/LLInt.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props: Added.
+ * JavaScriptCore.vcxproj/build-generated-files.sh: Added.
+ * JavaScriptCore.vcxproj/copy-files.cmd: Added.
+ * JavaScriptCore.vcxproj/jsc: Added.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj: Added.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters: Added.
+ * JavaScriptCore.vcxproj/jsc/jsc.vcxproj.user: Added.
+ * JavaScriptCore.vcxproj/jsc/jscCommon.props: Added.
+ * JavaScriptCore.vcxproj/jsc/jscDebug.props: Added.
+ * JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd: Added.
+ * JavaScriptCore.vcxproj/jsc/jscPreLink.cmd: Added.
+ * JavaScriptCore.vcxproj/jsc/jscRelease.props: Added.
+ * config.h:
+
+2013-01-22 Joseph Pecoraro <pecoraro@apple.com>
+
+ [Mac] Enable Page Visibility (PAGE_VISIBILITY_API)
+ https://bugs.webkit.org/show_bug.cgi?id=107230
+
+ Reviewed by David Kilzer.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-22 Tobias Netzel <tobias.netzel@googlemail.com>
+
+ Yarr JIT isn't big endian compatible
+ https://bugs.webkit.org/show_bug.cgi?id=102897
+
+ Reviewed by Oliver Hunt.
+
+ This patch was tested in the current mozilla codebase only and has passed the regexp tests there.
+
+ * yarr/YarrJIT.cpp:
+ (JSC::Yarr::YarrGenerator::generatePatternCharacterOnce):
+
+2013-01-22 David Kilzer <ddkilzer@apple.com>
+
+ Fix DateMath.cpp to compile with -Wshorten-64-to-32
+ <http://webkit.org/b/107503>
+
+ Reviewed by Darin Adler.
+
+ * runtime/JSDateMath.cpp:
+ (JSC::parseDateFromNullTerminatedCharacters): Remove unneeded
+ static_cast<int>().
+
+2013-01-22 Tim Horton <timothy_horton@apple.com>
+
+ PDFPlugin: Build PDFPlugin everywhere, enable at runtime
+ https://bugs.webkit.org/show_bug.cgi?id=107117
+
+ Reviewed by Alexey Proskuryakov.
+
+ Since PDFLayerController SPI is all forward-declared, the plugin should build
+ on all Mac platforms, and can be enabled at runtime.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-21 Justin Schuh <jschuh@chromium.org>
+
+ [CHROMIUM] Suppress c4267 build warnings for Win64 targets
+ https://bugs.webkit.org/show_bug.cgi?id=107499
+
+ Reviewed by Abhishek Arya.
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2013-01-21 Dirk Schulze <dschulze@adobe.com>
+
+ Add build flag for Canvas's Path object (disabled by default)
+ https://bugs.webkit.org/show_bug.cgi?id=107473
+
+ Reviewed by Dean Jackson.
+
+ Add CANVAS_PATH build flag to build systems.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-20 Geoffrey Garen <ggaren@apple.com>
+
+ Weak GC maps should be easier to use
+ https://bugs.webkit.org/show_bug.cgi?id=107312
+
+ Reviewed by Sam Weinig.
+
+ Follow-up fix.
+
+ * runtime/PrototypeMap.cpp:
+ (JSC::PrototypeMap::emptyObjectStructureForPrototype): Restored this
+ ASSERT, which was disabled because of a bug in WeakGCMap.
+
+ * runtime/WeakGCMap.h:
+ (JSC::WeakGCMap::add): We can't pass our passed-in value to add() because
+ a PassWeak() clears itself when passed to another function. So, we pass
+ nullptr instead, and fix things up afterwards.
+
+2013-01-20 Geoffrey Garen <ggaren@apple.com>
+
+ Unreviewed.
+
+ Temporarily disabling this ASSERT to get the bots green
+ while I investigate a fix.
+
+ * runtime/PrototypeMap.cpp:
+ (JSC::PrototypeMap::emptyObjectStructureForPrototype):
+
+2013-01-20 Filip Pizlo <fpizlo@apple.com>
+
+ Inserting a node into the DFG graph should not require five lines of code
+ https://bugs.webkit.org/show_bug.cgi?id=107381
+
+ Reviewed by Sam Weinig.
+
+ This adds fairly comprehensive support for inserting a node into a DFG graph in one
+ method call. A common example of this is:
+
+ m_insertionSet.insertNode(indexInBlock, DontRefChildren, DontRefNode, SpecNone, ForceOSRExit, codeOrigin);
+
+ The arguments to insert() specify what reference counting you need to have happen
+ (RefChildren => recursively refs all children, RefNode => non-recursively refs the node
+ that was created), the prediction to set (SpecNone is a common default), followed by
+ the arguments to the Node() constructor. InsertionSet::insertNode() and similar methods
+ (Graph::addNode() and BasicBlock::appendNode()) all use a common variadic template
+ function macro from DFGVariadicFunction.h. Also, all of these methods will automatically
+ non-recursively ref() the node being created if the flags say NodeMustGenerate.
+
+ In all, this new mechanism retains the flexibility of the old approach (you get to
+ manage ref counts yourself, albeit in less code) while ensuring that most code that adds
+ nodes to the graph now needs less code to do it.
+
+ In the future, we should revisit the reference counting methodology in the DFG: we could
+ do like most compilers and get rid of it entirely, or we could make it automatic. This
+ patch doesn't attempt to make any such major changes, and only seeks to simplify the
+ technique we were already using (manual ref counting).
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/Operands.h:
+ (JSC::dumpOperands):
+ * dfg/DFGAdjacencyList.h:
+ (AdjacencyList):
+ (JSC::DFG::AdjacencyList::kind):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGBasicBlock.h:
+ (DFG):
+ (BasicBlock):
+ * dfg/DFGBasicBlockInlines.h: Added.
+ (DFG):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ * dfg/DFGCommon.h:
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::ConstantFoldingPhase):
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+ (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
+ (ConstantFoldingPhase):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::FixupPhase):
+ (JSC::DFG::FixupPhase::fixupBlock):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::ref):
+ (Graph):
+ * dfg/DFGInsertionSet.h:
+ (DFG):
+ (JSC::DFG::Insertion::Insertion):
+ (JSC::DFG::Insertion::element):
+ (Insertion):
+ (JSC::DFG::InsertionSet::InsertionSet):
+ (JSC::DFG::InsertionSet::insert):
+ (InsertionSet):
+ (JSC::DFG::InsertionSet::execute):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::Node):
+ (Node):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * dfg/DFGVariadicFunction.h: Added.
+
+2013-01-19 Geoffrey Garen <ggaren@apple.com>
+
+ Track inheritance structures in a side table, instead of using a private
+ name in each prototype
+ https://bugs.webkit.org/show_bug.cgi?id=107378
+
+ Reviewed by Sam Weinig and Phil Pizlo.
+
+ This is a step toward object size inference.
+
+ Using a side table frees us to use a more complex key (a pair of
+ prototype and expected inline capacity).
+
+ It also avoids ruining inline caches for prototypes. (Adding a new private
+ name for a new inline capacity would change the prototype's structure,
+ possibly firing watchpoints, making inline caches go polymorphic, and
+ generally causing us to have a bad time.)
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri: Buildage.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::finishCreation): Updated to use new side table API.
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::cacheInheritorID): Updated to use new side table API.
+
+ (JSC::JSFunction::visitChildren): Fixed a long-standing bug where JSFunction
+ forgot to visit one of its data members (m_cachedInheritorID). This
+ wasn't a user-visible problem before because JSFunction would always
+ visit its .prototype property, which visited its m_cachedInheritorID.
+ But now, function.prototype only weakly owns function.m_cachedInheritorID.
+
+ * runtime/JSGlobalData.h:
+ (JSGlobalData): Added the map, taking care to make sure that its
+ destructor would run after the heap destructor.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset): Updated to use new side table API.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::notifyPresenceOfIndexedAccessors):
+ (JSC::JSObject::setPrototype):
+ * runtime/JSObject.h:
+ (JSObject): Updated to use new side table API, and removed lots of code
+ that used to manage the per-object private name.
+
+ * runtime/JSProxy.cpp:
+ (JSC::JSProxy::setTarget):
+ * runtime/ObjectConstructor.cpp:
+ (JSC::objectConstructorCreate):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::ObjectPrototype::finishCreation): Updated to use new side table API.
+
+ * runtime/PrototypeMap.cpp: Added.
+ (JSC):
+ (JSC::PrototypeMap::addPrototype):
+ (JSC::PrototypeMap::emptyObjectStructureForPrototype):
+ * runtime/PrototypeMap.h: Added.
+ (PrototypeMap):
+ (JSC::PrototypeMap::isPrototype):
+ (JSC::PrototypeMap::clearEmptyObjectStructureForPrototype): New side table.
+ This is a simple weak map, mapping an object to the structure you should
+ use when inheriting from that object. (In future, inline capacity will
+ be a part of the mapping.)
+
+ I used two maps to preserve existing behavior that allowed us to speculate
+ about an object becoming a prototype, even if it wasn't one at the moment.
+ However, I suspect that behavior can be removed without harm.
+
+ * runtime/WeakGCMap.h:
+ (JSC::WeakGCMap::contains):
+ (WeakGCMap): I would rate myself a 6 / 10 in C++.
+
+2013-01-18 Dan Bernstein <mitz@apple.com>
+
+ Removed duplicate references to two headers in the project files.
+
+ Rubber-stamped by Mark Rowe.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-01-18 Michael Saboff <msaboff@apple.com>
+
+ Unreviewed build fix for building JSC with DFG_ENABLE_DEBUG_PROPAGATION_VERBOSE enabled in DFGCommon.h.
+ Fixes the case where the argument node in fixupNode is freed due to the Vector storage being reallocated.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+
+2013-01-18 Michael Saboff <msaboff@apple.com>
+
+ Unreviewed build fix for release builds when DFG_ENABLE_DEBUG_PROPAGATION_VERBOSE is set to 1 in DFGCommon.h.
+
+ * dfg/DFGCFAPhase.cpp: Added #include "Operations.h"
+
+2013-01-18 Michael Saboff <msaboff@apple.com>
+
+ Change set r140201 broke editing/selection/move-by-word-visually-multi-line.html
+ https://bugs.webkit.org/show_bug.cgi?id=107340
+
+ Reviewed by Filip Pizlo.
+
+ Due to the change landed in r140201, more nodes might end up
+ generating Int32ToDouble nodes. Therefore, changed the JSVALUE64
+ constant path of compileInt32ToDouble() to use the more
+ restrictive isInt32Constant() check on the input. This check was
+ the same as the existing ASSERT() so the ASSERT was eliminated.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+
+2013-01-18 Viatcheslav Ostapenko <sl.ostapenko@samsung.com>
+
+ Weak GC maps should be easier to use
+ https://bugs.webkit.org/show_bug.cgi?id=107312
+
+ Reviewed by Ryosuke Niwa.
+
+ Build fix for linux platforms after r140194.
+
+ * runtime/WeakGCMap.h:
+ (WeakGCMap):
+
+2013-01-18 Michael Saboff <msaboff@apple.com>
+
+ Harden ArithDiv of integers fix-up by inserting Int32ToDouble node directly
+ https://bugs.webkit.org/show_bug.cgi?id=107321
+
+ Reviewed by Filip Pizlo.
+
+ Split out the Int32ToDouble node insertion from fixDoubleEdge() and used it directly when we're fixing up
+ an ArithDiv node with integer inputs and output for platforms that don't have integer division.
+ Since we are checking that our inputs should be ints, we can just insert the Int32ToDouble node
+ without any further checks.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
+
+2013-01-18 Michael Saboff <msaboff@apple.com>
+
+ Fix up of ArithDiv nodes for non-x86 CPUs is broken
+ https://bugs.webkit.org/show_bug.cgi?id=107309
+
+ Reviewed by Filip Pizlo.
+
+ Changed the logic so that we insert an Int32ToDouble node when the existing edge is not SpecDouble.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+
+2013-01-18 Dan Bernstein <mitz@apple.com>
+
+ Tried to fix the build after r140194.
+
+ * API/JSWrapperMap.mm:
+ (-[JSWrapperMap wrapperForObject:]):
+
+2013-01-18 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Update documentation for JSValue and JSContext
+ https://bugs.webkit.org/show_bug.cgi?id=107313
+
+ Reviewed by Geoffrey Garen.
+
+ After changing the semantics of object lifetime we need to update the API documentation to reflect the new semantics.
+
+ * API/APIJSValue.h:
+ * API/JSContext.h:
+
+2013-01-18 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ r134080 causes heap problem on linux systems where PAGESIZE != 4096
+ https://bugs.webkit.org/show_bug.cgi?id=102828
+
+ Reviewed by Mark Hahnenberg.
+
+ Make MarkStackSegment::blockSize as the capacity of segments of a MarkStackArray.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
+ * heap/MarkStack.cpp:
+ (JSC):
+ (JSC::MarkStackArray::MarkStackArray):
+ (JSC::MarkStackArray::expand):
+ (JSC::MarkStackArray::donateSomeCellsTo):
+ (JSC::MarkStackArray::stealSomeCellsFrom):
+ * heap/MarkStack.h:
+ (JSC::MarkStackSegment::data):
+ (CapacityFromSize):
+ (MarkStackArray):
+ * heap/MarkStackInlines.h:
+ (JSC::MarkStackArray::setTopForFullSegment):
+ (JSC::MarkStackArray::append):
+ (JSC::MarkStackArray::isEmpty):
+ (JSC::MarkStackArray::size):
+ * runtime/Options.h:
+ (JSC):
+
+2013-01-18 Geoffrey Garen <ggaren@apple.com>
+
+ Weak GC maps should be easier to use
+ https://bugs.webkit.org/show_bug.cgi?id=107312
+
+ Reviewed by Sam Weinig.
+
+ This patch changes WeakGCMap to not use a WeakImpl finalizer to remove
+ items from the map, and to instead have the map automatically remove
+ stale items itself upon insertion. This has a few advantages:
+
+ (1) WeakGCMap is now compatible with all the specializations you would
+ use for HashMap.
+
+ (2) There's no need for clients to write special finalization munging
+ functions.
+
+ (3) Clients can specify custom value finalizers if they like.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def: Def!
+
+ * API/JSWeakObjectMapRefPrivate.cpp: Setter no longer requires a global
+ data, since we've reduced interdependency.
+
+ * heap/Handle.h: No more need to forward declare, since we've reduced
+ interdependency.
+
+ * heap/Weak.h:
+ (Weak): Use explicit so we can assign directly to a weak map iterator
+ without ambiguity between Weak<T> and PassWeak<T>.
+
+ * runtime/Structure.cpp:
+ (JSC::StructureTransitionTable::add): See above.
+
+ * runtime/Structure.h:
+ (JSC):
+ * runtime/StructureTransitionTable.h:
+ (StructureTransitionTable): Bad code goes away, programmer happy.
+
+ * runtime/WeakGCMap.h:
+ (JSC):
+ (WeakGCMap):
+ (JSC::WeakGCMap::WeakGCMap):
+ (JSC::WeakGCMap::set):
+ (JSC::WeakGCMap::add):
+ (JSC::WeakGCMap::find):
+ (JSC::WeakGCMap::contains):
+ (JSC::WeakGCMap::gcMap):
+ (JSC::WeakGCMap::gcMapIfNeeded): Inherit from HashMap and override any
+ function that might observe a Weak<T> that has died, just enough to
+ make such items appear as if they are not in the table.
+
+2013-01-18 Michael Saboff <msaboff@apple.com>
+
+ Refactor isPowerOf2() and add getLSBSet()
+ https://bugs.webkit.org/show_bug.cgi?id=107306
+
+ Reviewed by Filip Pizlo.
+
+ Moved implementation of isPowerOf2() to new hasOneBitSet() in wtf/MathExtras.h.
+
+ * runtime/PropertyMapHashTable.h:
+ (JSC::isPowerOf2):
+
+2013-01-17 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Clean up JSValue.mm
+ https://bugs.webkit.org/show_bug.cgi?id=107163
+
+ Reviewed by Darin Adler.
+
+ m_context is no longer weak, so there is now a lot of dead code in in JSValue.mm, and a wasted message send
+ on every API call. In the head of just about every method in JSValue.mm we're doing:
+
+ JSContext *context = [self context];
+ if (!context)
+ return nil;
+
+ This is getting a retained copy of the context, which is no longer necessary now m_context is no longer weak.
+ We can just delete all these lines from all functions doing this, and where they were referring to the local
+ variable 'context', instead we can just access m_context directly.
+
+ Since we're already going to be modifying most of JSValue.mm, we'll also do the following:
+
+ 1) context @property is no longer weak – the context property is declared as:
+
+ @property(readonly, weak) JSContext *context;
+
+ This is really only informative (since we're not presently synthesizing the ivar), but it is now misleading.
+ We should change it to:
+
+ @property(readonly, retain) JSContext *context;
+
+ 2) the JSContext ivar and accessor can be automatically generated. Since we're no longer doing anything
+ special with m_context, we can just let the compiler handle the ivar for us. We'll delete:
+
+ JSContext *m_context;
+
+ and:
+
+ - (JSContext *)context
+ {
+ return m_context;
+
+ }
+
+ and find&replace "m_context" to "_context" in JSValue.mm.
+
+ * API/APIJSValue.h:
+ * API/JSValue.mm:
+ (-[JSValue toObject]):
+ (-[JSValue toBool]):
+ (-[JSValue toDouble]):
+ (-[JSValue toNumber]):
+ (-[JSValue toString]):
+ (-[JSValue toDate]):
+ (-[JSValue toArray]):
+ (-[JSValue toDictionary]):
+ (-[JSValue valueForProperty:]):
+ (-[JSValue setValue:forProperty:]):
+ (-[JSValue deleteProperty:]):
+ (-[JSValue hasProperty:]):
+ (-[JSValue defineProperty:descriptor:]):
+ (-[JSValue valueAtIndex:]):
+ (-[JSValue setValue:atIndex:]):
+ (-[JSValue isUndefined]):
+ (-[JSValue isNull]):
+ (-[JSValue isBoolean]):
+ (-[JSValue isNumber]):
+ (-[JSValue isString]):
+ (-[JSValue isObject]):
+ (-[JSValue isEqualToObject:]):
+ (-[JSValue isEqualWithTypeCoercionToObject:]):
+ (-[JSValue isInstanceOf:]):
+ (-[JSValue callWithArguments:]):
+ (-[JSValue constructWithArguments:]):
+ (-[JSValue invokeMethod:withArguments:]):
+ (-[JSValue objectForKeyedSubscript:]):
+ (-[JSValue setObject:forKeyedSubscript:]):
+ (-[JSValue initWithValue:inContext:]):
+ (-[JSValue dealloc]):
+ (-[JSValue description]):
+
+2013-01-17 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C API: Clean up JSValue
+ https://bugs.webkit.org/show_bug.cgi?id=107156
+
+ Reviewed by Oliver Hunt.
+
+ JSContext m_protectCounts, protect, unprotect are all now unnecessary overhead, and should all be removed.
+ These exist to handle the context going away before the value does; the context needs to be able to unprotect
+ values early. Since the value is now keeping the context alive there is no longer any danger of this happening;
+ instead we should just protect/unprotect the value in JSValue's init/dealloc methods.
+
+ * API/JSContext.mm:
+ (-[JSContext dealloc]):
+ * API/JSContextInternal.h:
+ * API/JSValue.mm:
+ (-[JSValue initWithValue:inContext:]):
+ (-[JSValue dealloc]):
+
+2013-01-17 Filip Pizlo <fpizlo@apple.com>
+
+ DFG Node::ref() and Node::deref() should not return bool, and should have postfixRef variants
+ https://bugs.webkit.org/show_bug.cgi?id=107147
+
+ Reviewed by Mark Hahnenberg.
+
+ This small refactoring will enable a world where ref() returns Node*, which is useful for
+ https://bugs.webkit.org/show_bug.cgi?id=106868. Also, while this refactoring does lead to
+ slightly less terse code, it's also slightly more self-explanatory. I could never quite
+ remember what the meaning of the bool return from ref() and deref() was.
+
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::collectGarbage):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::ref):
+ (JSC::DFG::Graph::deref):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::ref):
+ (Node):
+ (JSC::DFG::Node::postfixRef):
+ (JSC::DFG::Node::deref):
+ (JSC::DFG::Node::postfixDeref):
+
+2013-01-17 Alexey Proskuryakov <ap@apple.com>
+
+ Added svn:ignore=*.pyc, so that ud_opcode.pyc and ud_optable.pyc don't show up
+ in svn stat.
+
+ * disassembler/udis86: Added property svn:ignore.
+
+2013-01-16 Filip Pizlo <fpizlo@apple.com>
+
+ DFG 32_64 backend doesn't check for hasArrayStorage() in NewArrayWithSize
+ https://bugs.webkit.org/show_bug.cgi?id=107081
+
+ Reviewed by Michael Saboff.
+
+ This bug led to the 32_64 backend emitting contiguous allocation code to allocate
+ ArrayStorage arrays. This then led to all manner of heap corruption, since
+ subsequent array accesses would be accessing the contiguous array "as if" it was
+ an arraystorage array.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-01-16 Jonathan Liu <net147@gmail.com>
+
+ Add missing sys/mman.h include on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=98089
+
+ Reviewed by Darin Adler.
+
+ The madvise function and MADV_FREE constant require sys/mman.h.
+
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+
+2013-01-15 Michael Saboff <msaboff@apple.com>
+
+ DFG X86: division in the used-as-int case doesn't correctly check for -2^31/-1
+ https://bugs.webkit.org/show_bug.cgi?id=106978
+
+ Reviewed by Filip Pizlo.
+
+ Changed the numerator equal to -2^31 check to just return if we expect an integer
+ result, since the check is after we have determined that the denominator is -1.
+ The int result of -2^31 / -1 is -2^31, so just return the numerator as the result.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileIntegerArithDivForX86):
+
+2013-01-15 Levi Weintraub <leviw@chromium.org>
+
+ Unreviewed, rolling out r139792.
+ http://trac.webkit.org/changeset/139792
+ https://bugs.webkit.org/show_bug.cgi?id=106970
+
+ Broke the windows build.
+
+ * bytecode/GlobalResolveInfo.h: Removed property svn:mergeinfo.
+
+2013-01-15 Pratik Solanki <psolanki@apple.com>
+
+ Use MADV_FREE_REUSABLE to return JIT memory to OS
+ https://bugs.webkit.org/show_bug.cgi?id=106830
+ <rdar://problem/11437701>
+
+ Reviewed by Geoffrey Garen.
+
+ Use MADV_FREE_REUSABLE to return JIT memory on OSes that have the underlying madvise bug
+ fixed.
+
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::FixedVMPoolExecutableAllocator::notifyPageIsFree):
+
+2013-01-15 Levi Weintraub <leviw@chromium.org>
+
+ Unreviewed, rolling out r139790.
+ http://trac.webkit.org/changeset/139790
+ https://bugs.webkit.org/show_bug.cgi?id=106948
+
+ The patch is failing its own test.
+
+ * bytecode/GlobalResolveInfo.h: Removed property svn:mergeinfo.
+
+2013-01-15 Zan Dobersek <zandobersek@gmail.com>
+
+ [Autotools] Unify JavaScriptCore sources list, regardless of target OS
+ https://bugs.webkit.org/show_bug.cgi?id=106007
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Include the Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp target
+ in the general sources list as it is guarded by the ENABLE_EXECUTABLE_ALLOCATOR_FIXED
+ feature define. This define is only used on 64-bit architecture and indirectly depends
+ on enabling either JIT or YARR JIT feature. Both of these defines are disabled on
+ Windows OS when using 64-bit architecture so there's no need to add this target to
+ sources only when the target OS is Windows.
+
+ * GNUmakefile.list.am:
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not forget that it had proved something to be a constant during a merge just because it's merging against the empty value
+ https://bugs.webkit.org/show_bug.cgi?id=106727
+
+ Reviewed by Oliver Hunt.
+
+ The problem was this statement:
+
+ if (m_value != other.m_value)
+ m_value = JSValue();
+
+ This is well-intentioned, in the sense that if we want our abstract value (i.e. this) to become the superset of the other
+ abstract value, and the two abstract values have proven different constants, then our abstract value should rescind its
+ claim that it has been proven to be constant. But this misses the special case that if the other abstract value is
+ completely clear (meaning that it wishes to contribute zero information and so the superset operation shouldn't change
+ this), it will have a clear m_value. So, the code prior to this patch would rescind the constant proof even though it
+ didn't have to.
+
+ This comes up rarely and I don't believe it will be a performance win, but it is good to have the CFA been consistently
+ precise as often as possible.
+
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::merge):
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ Python implementation reports "MemoryError" instead of doing things
+ https://bugs.webkit.org/show_bug.cgi?id=106690
+
+ Reviewed by Oliver Hunt.
+
+ The bug was that the CFA was assuming that a variable is dead at the end of a basic block and hence doesn't need to
+ be merged to the next block if the last mention of the variable was dead. This is almost correct, except that it
+ doesn't work if the last mention is a GetLocal - the GetLocal itself may be dead, but that doesn't mean that the
+ variable is dead - it may still be live. The appropriate thing to do is to look at the GetLocal's Phi. If the
+ variable is used in the next block then the next block will have a reference to the last mention in our block unless
+ that last mention is a GetLocal, in which case it will link to the Phi. Doing it this way captures everything that
+ the CFA wants: if the last use is a live GetLocal then the CFA needs to consider the GetLocal itself for possible
+ refinements to the proof of the value in the variable, but if the GetLocal is dead, then this must mean that the
+ variable is not mentioned in the block but may still be "passed through" it, which is what the Phi will tell us.
+ Note that it is not possible for the GetLocal to refer to anything other than a Phi, and it is also not possible
+ for the last mention of a variable to be a dead GetLocal while there are other mentions that aren't dead - if
+ there had been SetLocals or GetLocals prior to the dead one then the dead one wouldn't have been emitted by the
+ parser.
+
+ This also fixes a similar bug in the handling of captured variables. If a variable is captured, then it doesn't
+ matter if the last mention is dead, or not. Either way, we already know that a captured variable will be live in
+ the next block, so we must merge it no matter what.
+
+ Finally, this change makes the output of Operands dumping a bit more verbose: it now prints the variable name next
+ to each variable's dump. I've often found the lack of this information confusing particularly for operand dumps
+ that involve a lot of variables.
+
+ * bytecode/Operands.h:
+ (JSC::dumpOperands):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+
+2013-01-14 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Fix vcproj file. Missing file tag after http://trac.webkit.org/changeset/139541.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2013-01-13 Filip Pizlo <fpizlo@apple.com>
+
+ DFG phases that store per-node information should store it in Node itself rather than using a secondary vector
+ https://bugs.webkit.org/show_bug.cgi?id=106753
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::AbstractState):
+ (JSC::DFG::AbstractState::beginBasicBlock):
+ (JSC::DFG::AbstractState::dump):
+ * dfg/DFGAbstractState.h:
+ (JSC::DFG::AbstractState::forNode):
+ (AbstractState):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::CSEPhase):
+ (JSC::DFG::CSEPhase::performSubstitution):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (CSEPhase):
+ * dfg/DFGNode.h:
+ (Node):
+
+2013-01-12 Tim Horton <timothy_horton@apple.com>
+
+ Unreviewed build fix.
+
+ * API/JSBlockAdaptor.mm:
+ * API/JSContext.mm:
+ * API/JSValue.mm:
+
+2013-01-12 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed 64 bit buildfix after r139496.
+
+ * dfg/DFGOperations.cpp:
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, speculative build fix.
+
+ * API/JSWrapperMap.mm:
+
+2013-01-10 Filip Pizlo <fpizlo@apple.com>
+
+ JITThunks should not compile only because of luck
+ https://bugs.webkit.org/show_bug.cgi?id=105696
+
+ Rubber stamped by Sam Weinig and Geoffrey Garen.
+
+ This patch was supposed to just move JITThunks into its own file. But then I
+ realized that there is a horrible circular dependency chain between JSCell,
+ JSGlobalData, CallFrame, and Weak, which only works because of magical include
+ order in JITStubs.h, and the fact that JSGlobalData.h includes JITStubs.h
+ before it includes JSCell or JSValue.
+
+ I first tried to just get JITThunks.h to just magically do the same pointless
+ includes that JITStubs.h had, but then I decided to actually fix the underflying
+ problem, which was that JSCell needed CallFrame, CallFrame needed JSGlobalData,
+ JSGlobalData needed JITThunks, JITThunks needed Weak, and Weak needed JSCell.
+ Now, all of JSCell's outgoing dependencies are placed in JSCellInlines.h. This
+ also gave me an opportunity to move JSValue inline methods from JSCell.h into
+ JSValueInlines.h. But to make this really work, I needed to remove includes of
+ *Inlines.h from other headers (CodeBlock.h for example included JSValueInlines.h,
+ which defeats the whole entire purpose of having an Inlines.h file), and I needed
+ to add includes of *Inlines.h into a bunch of .cpp files. I did this mostly by
+ having .cpp files include Operations.h. In future, if you're adding a .cpp file
+ to JSC, you'll almost certainly have to include Operations.h unless you enjoy
+ link errors.
+
+ * API/JSBase.cpp:
+ * API/JSCallbackConstructor.cpp:
+ * API/JSCallbackFunction.cpp:
+ * API/JSCallbackObject.cpp:
+ * API/JSClassRef.cpp:
+ * API/JSContextRef.cpp:
+ * API/JSObjectRef.cpp:
+ * API/JSScriptRef.cpp:
+ * API/JSWeakObjectMapRefPrivate.cpp:
+ * JSCTypedArrayStubs.h:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/ArrayAllocationProfile.cpp:
+ * bytecode/CodeBlock.cpp:
+ * bytecode/GetByIdStatus.cpp:
+ * bytecode/LazyOperandValueProfile.cpp:
+ * bytecode/ResolveGlobalStatus.cpp:
+ * bytecode/SpeculatedType.cpp:
+ * bytecode/UnlinkedCodeBlock.cpp:
+ * bytecompiler/BytecodeGenerator.cpp:
+ * debugger/Debugger.cpp:
+ * debugger/DebuggerActivation.cpp:
+ * debugger/DebuggerCallFrame.cpp:
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ * dfg/DFGArrayMode.cpp:
+ * dfg/DFGByteCodeParser.cpp:
+ * dfg/DFGConstantFoldingPhase.cpp:
+ * dfg/DFGDriver.cpp:
+ * dfg/DFGFixupPhase.cpp:
+ * dfg/DFGGraph.cpp:
+ * dfg/DFGJITCompiler.cpp:
+ * dfg/DFGOSREntry.cpp:
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ * dfg/DFGOSRExitCompiler64.cpp:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
+ (JSC::DFG::SpeculativeJIT::silentSpill):
+ (JSC::DFG::SpeculativeJIT::silentFill):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ * dfg/DFGSpeculativeJIT64.cpp:
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ * dfg/DFGVariableEventStream.cpp:
+ * heap/CopiedBlock.h:
+ * heap/CopiedSpace.cpp:
+ * heap/HandleSet.cpp:
+ * heap/Heap.cpp:
+ * heap/HeapStatistics.cpp:
+ * heap/SlotVisitor.cpp:
+ * heap/WeakBlock.cpp:
+ * interpreter/CallFrame.cpp:
+ * interpreter/CallFrame.h:
+ * jit/ClosureCallStubRoutine.cpp:
+ * jit/GCAwareJITStubRoutine.cpp:
+ * jit/JIT.cpp:
+ * jit/JITArithmetic.cpp:
+ * jit/JITArithmetic32_64.cpp:
+ * jit/JITCall.cpp:
+ * jit/JITCall32_64.cpp:
+ * jit/JITCode.h:
+ * jit/JITExceptions.cpp:
+ * jit/JITStubs.h:
+ * jit/JITThunks.h:
+ * jsc.cpp:
+ * llint/LLIntExceptions.cpp:
+ * profiler/LegacyProfiler.cpp:
+ * profiler/ProfileGenerator.cpp:
+ * profiler/ProfilerBytecode.cpp:
+ * profiler/ProfilerBytecodeSequence.cpp:
+ * profiler/ProfilerBytecodes.cpp:
+ * profiler/ProfilerCompilation.cpp:
+ * profiler/ProfilerCompiledBytecode.cpp:
+ * profiler/ProfilerDatabase.cpp:
+ * profiler/ProfilerOSRExit.cpp:
+ * profiler/ProfilerOSRExitSite.cpp:
+ * profiler/ProfilerOrigin.cpp:
+ * profiler/ProfilerOriginStack.cpp:
+ * profiler/ProfilerProfiledBytecodes.cpp:
+ * runtime/ArgList.cpp:
+ * runtime/Arguments.cpp:
+ * runtime/ArrayConstructor.cpp:
+ * runtime/BooleanConstructor.cpp:
+ * runtime/BooleanObject.cpp:
+ * runtime/BooleanPrototype.cpp:
+ * runtime/CallData.cpp:
+ * runtime/CodeCache.cpp:
+ * runtime/Completion.cpp:
+ * runtime/ConstructData.cpp:
+ * runtime/DateConstructor.cpp:
+ * runtime/DateInstance.cpp:
+ * runtime/DatePrototype.cpp:
+ * runtime/Error.cpp:
+ * runtime/ErrorConstructor.cpp:
+ * runtime/ErrorInstance.cpp:
+ * runtime/ErrorPrototype.cpp:
+ * runtime/ExceptionHelpers.cpp:
+ * runtime/Executable.cpp:
+ * runtime/FunctionConstructor.cpp:
+ * runtime/FunctionPrototype.cpp:
+ * runtime/GetterSetter.cpp:
+ * runtime/Identifier.cpp:
+ * runtime/InternalFunction.cpp:
+ * runtime/JSActivation.cpp:
+ * runtime/JSBoundFunction.cpp:
+ * runtime/JSCell.cpp:
+ * runtime/JSCell.h:
+ (JSC):
+ * runtime/JSCellInlines.h: Added.
+ (JSC):
+ (JSC::JSCell::JSCell):
+ (JSC::JSCell::finishCreation):
+ (JSC::JSCell::structure):
+ (JSC::JSCell::visitChildren):
+ (JSC::allocateCell):
+ (JSC::isZapped):
+ (JSC::JSCell::isObject):
+ (JSC::JSCell::isString):
+ (JSC::JSCell::isGetterSetter):
+ (JSC::JSCell::isProxy):
+ (JSC::JSCell::isAPIValueWrapper):
+ (JSC::JSCell::setStructure):
+ (JSC::JSCell::methodTable):
+ (JSC::JSCell::inherits):
+ (JSC::JSCell::fastGetOwnPropertySlot):
+ (JSC::JSCell::fastGetOwnProperty):
+ (JSC::JSCell::toBoolean):
+ * runtime/JSDateMath.cpp:
+ * runtime/JSFunction.cpp:
+ * runtime/JSFunction.h:
+ (JSC):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSLock.cpp:
+ * runtime/JSNameScope.cpp:
+ * runtime/JSNotAnObject.cpp:
+ * runtime/JSONObject.cpp:
+ * runtime/JSObject.h:
+ (JSC):
+ * runtime/JSProxy.cpp:
+ * runtime/JSScope.cpp:
+ * runtime/JSSegmentedVariableObject.cpp:
+ * runtime/JSString.h:
+ (JSC):
+ * runtime/JSStringJoiner.cpp:
+ * runtime/JSSymbolTableObject.cpp:
+ * runtime/JSValue.cpp:
+ * runtime/JSValueInlines.h:
+ (JSC::JSValue::toInt32):
+ (JSC::JSValue::toUInt32):
+ (JSC):
+ (JSC::JSValue::isUInt32):
+ (JSC::JSValue::asUInt32):
+ (JSC::JSValue::asNumber):
+ (JSC::jsNaN):
+ (JSC::JSValue::JSValue):
+ (JSC::JSValue::encode):
+ (JSC::JSValue::decode):
+ (JSC::JSValue::operator bool):
+ (JSC::JSValue::operator==):
+ (JSC::JSValue::operator!=):
+ (JSC::JSValue::isEmpty):
+ (JSC::JSValue::isUndefined):
+ (JSC::JSValue::isNull):
+ (JSC::JSValue::isUndefinedOrNull):
+ (JSC::JSValue::isCell):
+ (JSC::JSValue::isInt32):
+ (JSC::JSValue::isDouble):
+ (JSC::JSValue::isTrue):
+ (JSC::JSValue::isFalse):
+ (JSC::JSValue::tag):
+ (JSC::JSValue::payload):
+ (JSC::JSValue::asInt32):
+ (JSC::JSValue::asDouble):
+ (JSC::JSValue::asCell):
+ (JSC::JSValue::isNumber):
+ (JSC::JSValue::isBoolean):
+ (JSC::JSValue::asBoolean):
+ (JSC::reinterpretDoubleToInt64):
+ (JSC::reinterpretInt64ToDouble):
+ (JSC::JSValue::isString):
+ (JSC::JSValue::isPrimitive):
+ (JSC::JSValue::isGetterSetter):
+ (JSC::JSValue::isObject):
+ (JSC::JSValue::getString):
+ (JSC::::getString):
+ (JSC::JSValue::getObject):
+ (JSC::JSValue::getUInt32):
+ (JSC::JSValue::toPrimitive):
+ (JSC::JSValue::getPrimitiveNumber):
+ (JSC::JSValue::toNumber):
+ (JSC::JSValue::toObject):
+ (JSC::JSValue::isFunction):
+ (JSC::JSValue::inherits):
+ (JSC::JSValue::toThisObject):
+ (JSC::JSValue::get):
+ (JSC::JSValue::put):
+ (JSC::JSValue::putByIndex):
+ (JSC::JSValue::structureOrUndefined):
+ (JSC::JSValue::equal):
+ (JSC::JSValue::equalSlowCaseInline):
+ (JSC::JSValue::strictEqualSlowCaseInline):
+ (JSC::JSValue::strictEqual):
+ * runtime/JSVariableObject.cpp:
+ * runtime/JSWithScope.cpp:
+ * runtime/JSWrapperObject.cpp:
+ * runtime/LiteralParser.cpp:
+ * runtime/Lookup.cpp:
+ * runtime/NameConstructor.cpp:
+ * runtime/NameInstance.cpp:
+ * runtime/NamePrototype.cpp:
+ * runtime/NativeErrorConstructor.cpp:
+ * runtime/NativeErrorPrototype.cpp:
+ * runtime/NumberConstructor.cpp:
+ * runtime/NumberObject.cpp:
+ * runtime/ObjectConstructor.cpp:
+ * runtime/ObjectPrototype.cpp:
+ * runtime/Operations.h:
+ (JSC):
+ * runtime/PropertySlot.cpp:
+ * runtime/RegExp.cpp:
+ * runtime/RegExpCache.cpp:
+ * runtime/RegExpCachedResult.cpp:
+ * runtime/RegExpConstructor.cpp:
+ * runtime/RegExpMatchesArray.cpp:
+ * runtime/RegExpObject.cpp:
+ * runtime/RegExpPrototype.cpp:
+ * runtime/SmallStrings.cpp:
+ * runtime/SparseArrayValueMap.cpp:
+ * runtime/StrictEvalActivation.cpp:
+ * runtime/StringConstructor.cpp:
+ * runtime/StringObject.cpp:
+ * runtime/StringRecursionChecker.cpp:
+ * runtime/Structure.h:
+ (JSC):
+ * runtime/StructureChain.cpp:
+ * runtime/TimeoutChecker.cpp:
+ * testRegExp.cpp:
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ If you use Phantom to force something to be live across an OSR exit, you should put it after the OSR exit
+ https://bugs.webkit.org/show_bug.cgi?id=106724
+
+ Reviewed by Oliver Hunt.
+
+ In cases where we were getting it wrong, I think it was benign because we would either already have an
+ OSR exit prior to there, or the operand would be a constant. But still, it's good to get this right.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ Phantom(GetLocal) should be treated as relevant to OSR
+ https://bugs.webkit.org/show_bug.cgi?id=106715
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performBlockCSE):
+
+2013-01-11 Pratik Solanki <psolanki@apple.com>
+
+ Fix function name typo ProgramExecutable::initalizeGlobalProperties()
+ https://bugs.webkit.org/show_bug.cgi?id=106701
+
+ Reviewed by Geoffrey Garen.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * runtime/Executable.cpp:
+ (JSC::ProgramExecutable::initializeGlobalProperties):
+ * runtime/Executable.h:
+
+2013-01-11 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ testapi is failing with a block-related error in the Objc API
+ https://bugs.webkit.org/show_bug.cgi?id=106055
+
+ Reviewed by Filip Pizlo.
+
+ Same bug as in testapi.mm. We need to actually call the static block, rather than casting the block to a bool.
+
+ * API/ObjCCallbackFunction.mm:
+ (blockSignatureContainsClass):
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ Add a run-time option to print bytecode at DFG compile time
+ https://bugs.webkit.org/show_bug.cgi?id=106704
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * runtime/Options.h:
+ (JSC):
+
+2013-01-11 Filip Pizlo <fpizlo@apple.com>
+
+ It should be possible to enable verbose printing of each OSR exit at run-time (rather than compile-time) and it should print register state
+ https://bugs.webkit.org/show_bug.cgi?id=106700
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGAssemblyHelpers.h:
+ (DFG):
+ (JSC::DFG::AssemblyHelpers::debugCall):
+ * dfg/DFGCommon.h:
+ * dfg/DFGOSRExit.h:
+ (DFG):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * runtime/Options.h:
+ (JSC):
+
+2013-01-11 Geoffrey Garen <ggaren@apple.com>
+
+ Removed getDirectLocation and offsetForLocation and all their uses
+ https://bugs.webkit.org/show_bug.cgi?id=106692
+
+ Reviewed by Filip Pizlo.
+
+ getDirectLocation() and its associated offsetForLocation() relied on
+ detailed knowledge of the rules of PropertyOffset, JSObject, and
+ Structure, which is a hard thing to reverse-engineer reliably. Luckily,
+ it wasn't needed, and all clients either wanted a true value or a
+ PropertyOffset. So, I refactored accordingly.
+
+ * dfg/DFGOperations.cpp: Renamed putDirectOffset to putDirect, to clarify
+ that we are not putting an offset.
+
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::getOwnPropertySlot): Get a value instead of a value
+ pointer, since we never wanted a pointer to begin with.
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::getOwnPropertySlot): Use a PropertyOffset instead of a pointer,
+ so we don't have to reverse-engineer the offset from the pointer.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::put):
+ (JSC::JSObject::resetInheritorID):
+ (JSC::JSObject::inheritorID):
+ (JSC::JSObject::removeDirect):
+ (JSC::JSObject::fillGetterPropertySlot):
+ (JSC::JSObject::getOwnPropertyDescriptor): Renamed getDirectOffset and
+ putDirectOffset, as explaind above. We want to use the name "getDirectOffset"
+ for when the thing you're getting is the offset.
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::getDirect):
+ (JSC::JSObject::getDirectOffset): Changed getDirectLocation to getDirectOffset,
+ since clients really wants PropertyOffsets and not locations.
+
+ (JSObject::offsetForLocation): Removed this function because it was hard
+ to get right.
+
+ (JSC::JSObject::putDirect):
+ (JSC::JSObject::putDirectUndefined):
+ (JSC::JSObject::inlineGetOwnPropertySlot):
+ (JSC::JSObject::putDirectInternal):
+ (JSC::JSObject::putDirectWithoutTransition):
+ * runtime/JSScope.cpp:
+ (JSC::executeResolveOperations):
+ (JSC::JSScope::resolvePut):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::putToPrimitive): Updated for renames.
+
+ * runtime/Lookup.cpp:
+ (JSC::setUpStaticFunctionSlot): Use a PropertyOffset instead of a pointer,
+ so we don't have to reverse-engineer the offset from the pointer.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::flattenDictionaryStructure): Updated for renames.
+
+2013-01-11 Geoffrey Garen <ggaren@apple.com>
+
+ Removed an unused version of getDirectLocation
+ https://bugs.webkit.org/show_bug.cgi?id=106691
+
+ Reviewed by Gavin Barraclough.
+
+ getDirectLocation is a weird operation. Removing the unused version is
+ the easy part.
+
+ * runtime/JSObject.h:
+ (JSObject):
+
+2013-01-11 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Objective-C objects that are passed to JavaScript leak (until the JSContext is destroyed)
+ https://bugs.webkit.org/show_bug.cgi?id=106056
+
+ Reviewed by Darin Adler.
+
+ * API/APIJSValue.h:
+ * API/JSValue.mm: Make the reference to the JSContext strong.
+ (-[JSValue context]):
+ (-[JSValue initWithValue:inContext:]):
+ (-[JSValue dealloc]):
+ * API/JSWrapperMap.mm: Make the reference back from wrappers to Obj-C objects weak instead of strong.
+ Also add an explicit WeakGCMap in the JSWrapperMap rather than using Obj-C associated object API which
+ was causing memory leaks.
+ (wrapperClass):
+ (-[JSObjCClassInfo wrapperForObject:]):
+ (-[JSWrapperMap initWithContext:]):
+ (-[JSWrapperMap dealloc]):
+ (-[JSWrapperMap wrapperForObject:]):
+
+2013-01-11 Geoffrey Garen <ggaren@apple.com>
+
+ Fixed some bogus PropertyOffset ASSERTs
+ https://bugs.webkit.org/show_bug.cgi?id=106686
+
+ Reviewed by Gavin Barraclough.
+
+ The ASSERTs were passing a JSType instead of an inlineCapacity, due to
+ an incomplete refactoring.
+
+ The compiler didn't catch this because both types are int underneath.
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::getDirect):
+ (JSC::JSObject::getDirectLocation):
+ (JSC::JSObject::offsetForLocation):
+ * runtime/Structure.cpp:
+ (JSC::Structure::addPropertyTransitionToExistingStructure): Validate against
+ our inline capacity, as we intended.
+
+2013-01-11 Geoffrey Garen <ggaren@apple.com>
+
+ Rename propertyOffsetFor => offsetForPropertyNumber
+ https://bugs.webkit.org/show_bug.cgi?id=106685
+
+ Reviewed by Gavin Barraclough.
+
+ Since the argument is just a typedef and not an object, I wanted to clarify the meaning.
+
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyTable::nextOffset): Updated for rename.
+
+ * runtime/PropertyOffset.h:
+ (JSC::offsetForPropertyNumber): Renamed. Also changed some PropertyOffset variables
+ to plain ints, because they're not actually on the PropertyOffsets number line.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::flattenDictionaryStructure):
+ * runtime/Structure.h:
+ (JSC::Structure::lastValidOffset): Updated for rename.
+
+2013-01-10 Zan Dobersek <zandobersek@gmail.com>
+
+ Remove the ENABLE_ANIMATION_API feature define occurences
+ https://bugs.webkit.org/show_bug.cgi?id=106544
+
+ Reviewed by Simon Fraser.
+
+ The Animation API code was removed in r137243. The ENABLE_ANIMATION_API
+ feature define handling still lingers in various build systems and configurations
+ but is of no use, so it should be removed.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-09 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Just move the JavaScriptCore exports file around in the vcproj to make things clearer.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2013-01-09 Filip Pizlo <fpizlo@apple.com>
+
+ Dont use a node reference after appending to the graph.
+ https://bugs.webkit.org/show_bug.cgi?id=103305
+ <rdar://problem/12753096>
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+
+2013-01-09 Roger Fong <roger_fong@apple.com>
+
+ Rename export files to make them more easily findable.
+ https://bugs.webkit.org/show_bug.cgi?id=98695.
+
+ Reviewed by Timothy Horton.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Removed.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def: Copied from Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def.
+
+2013-01-09 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add mips.rb to offlineasm_nosources.
+
+2013-01-08 Oliver Hunt <oliver@apple.com>
+
+ Support op_typeof in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=98898
+
+ Reviewed by Filip Pizlo.
+
+ Adds a TypeOf node to the DFG to support op_typeof.
+
+ To avoid adding too much GC horror, this also makes the
+ common strings portion of the SmallString cache strongly
+ referenced.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ We try to determine the result early here, and substitute in a constant.
+ Otherwise we leave the node intact, and set the result type to SpecString.
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ Parse op_typeof
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ TypeOf nodes can be subjected to pure CSE
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ We can handle typeof.
+ * dfg/DFGNodeType.h:
+ (DFG):
+ Define the node.
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ Add operationTypeOf to support the non-trivial cases.
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ Actual codegen
+ * runtime/Operations.cpp:
+ (JSC::jsTypeStringForValue):
+ (JSC):
+ * runtime/Operations.h:
+ (JSC):
+ Some refactoring to allow us to get the type string for an
+ object without needing a callframe.
+
+
+2013-01-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG shouldn't treat the 'this' argument as being captured if a code block uses arguments
+ https://bugs.webkit.org/show_bug.cgi?id=106398
+ <rdar://problem/12439776>
+
+ Reviewed by Mark Hahnenberg.
+
+ This is a possible optimization for inlined calls, and fixes crashes for inlined constructors, in the case
+ that the inlined code used arguments. The problem was that assuming that 'this' was captured implies the
+ assumption that it was initialized by the caller, which is wrong for constructors and this.
+
+ Also added a pretty essential DFG IR validation rule: we shouldn't have any live locals at the top of the
+ root block. This helps to catch this bug: our assumption that 'this' was captured in an inlined constructor
+ that used arguments led to liveness for the temporary that would have held 'this' in the caller being
+ propagated all the way up to the entrypoint of the function.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isCaptured):
+ * dfg/DFGValidate.cpp:
+ (JSC::DFG::Validate::validate):
+ (JSC::DFG::Validate::reportValidationContext):
+ (Validate):
+ (JSC::DFG::Validate::dumpGraphIfAppropriate):
+
+2013-01-08 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION (r138921): Crash in JSC::Arguments::create
+ https://bugs.webkit.org/show_bug.cgi?id=106329
+ <rdar://problem/12974196>
+
+ Reviewed by Mark Hahnenberg.
+
+ Arguments::finishCreation() that takes an InlineCallFrame* needs to understand that the callee can
+ be unset, indicating that the callee needs to be loaded from the true call frame. This adds a
+ method to InlineCallFrame to do just that.
+
+ * bytecode/CodeOrigin.cpp:
+ (JSC::InlineCallFrame::calleeForCallFrame):
+ * bytecode/CodeOrigin.h:
+ (InlineCallFrame):
+ * runtime/Arguments.h:
+ (JSC::Arguments::finishCreation):
+
+2013-01-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG initrinsic handling should ensure that we backwards propagate the fact that all operands may escape
+ https://bugs.webkit.org/show_bug.cgi?id=106365
+
+ Reviewed by Mark Hahnenberg.
+
+ Use the fact that Phantom means that things escaped, and just insert Phantoms for all
+ of the operands.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleCall):
+
+2013-01-08 Filip Pizlo <fpizlo@apple.com>
+
+ If array allocation profiling causes a new_array to allocate double arrays, then the holes should end up being correctly initialized
+ https://bugs.webkit.org/show_bug.cgi?id=106363
+
+ Reviewed by Mark Hahnenberg.
+
+ * runtime/JSArray.h:
+ (JSC::JSArray::tryCreateUninitialized):
+
+2013-01-07 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should backwards-propagate NodeUsedAsValue for Phantom
+ https://bugs.webkit.org/show_bug.cgi?id=106299
+
+ Reviewed by Mark Hahnenberg.
+
+ This is currently benign because Phantom is only inserted by the bytecode parser for
+ things that already happen to be used in contexts that backwards propagate
+ NodeUsedAsValue. But that doesn't change the fact that the semantics of Phantom are
+ that the value can be arbitrarily used by the baseline JIT.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
+2013-01-07 Filip Pizlo <fpizlo@apple.com>
+
+ Rationalize closure call heuristics and profiling
+ https://bugs.webkit.org/show_bug.cgi?id=106270
+
+ Reviewed by Oliver Hunt.
+
+ Did a number of things:
+
+ - CallLinkInfo now remembers if it was ever a closure call, and CallLinkStatus uses
+ this. Reduces the likelihood that we will inline a closure call as if it was a
+ normal call.
+
+ - Made InlineCallFrame print inferred function names, and refactored
+ CodeBlock::inferredName() to better use FunctionExecutable's API.
+
+ - Made bytecode dumping print frequent exit sites that led to recompilation.
+
+ - Made bytecode dumping for op_call and op_construct print what the CallLinkStatus
+ saw.
+
+ * bytecode/CallLinkInfo.h:
+ (JSC::CallLinkInfo::CallLinkInfo):
+ (CallLinkInfo):
+ * bytecode/CallLinkStatus.cpp:
+ (JSC::CallLinkStatus::computeFor):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::inferredName):
+ (JSC::CodeBlock::dumpBytecodeCommentAndNewLine):
+ (JSC::CodeBlock::printCallOp):
+ * bytecode/CodeOrigin.cpp:
+ (JSC::CodeOrigin::dump):
+ (JSC::InlineCallFrame::inferredName):
+ (JSC):
+ (JSC::InlineCallFrame::dumpBriefFunctionInformation):
+ (JSC::InlineCallFrame::dump):
+ * bytecode/CodeOrigin.h:
+ (InlineCallFrame):
+ * bytecode/DFGExitProfile.cpp:
+ (JSC::DFG::ExitProfile::exitSitesFor):
+ (DFG):
+ * bytecode/DFGExitProfile.h:
+ (ExitProfile):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2013-01-07 Ryosuke Niwa <rniwa@webkit.org>
+
+ Sorted the xcodeproj file.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-01-07 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, it should be possible to build JSC on ARM.
+
+ * API/JSBase.h:
+ * jit/JITStubs.cpp:
+ (JSC::performPlatformSpecificJITAssertions):
+ (JSC):
+ * jit/JITStubs.h:
+ (JSC):
+ * jit/JITThunks.cpp:
+ (JSC::JITThunks::JITThunks):
+ * jit/JITThunks.h:
+ (JITThunks):
+ * offlineasm/armv7.rb:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+2013-01-07 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ MIPS LLInt implementation.
+ https://bugs.webkit.org/show_bug.cgi?id=99706
+
+ Reviewed by Filip Pizlo.
+
+ LLInt implementation for MIPS.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::jump):
+ * dfg/DFGOperations.cpp:
+ (JSC):
+ * jit/JITStubs.cpp:
+ (JSC):
+ * jit/JITStubs.h:
+ (JITStackFrame):
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * offlineasm/backends.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/mips.rb: Added.
+
+2013-01-07 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ testapi is failing with a block-related error in the Objc API
+ https://bugs.webkit.org/show_bug.cgi?id=106055
+
+ Reviewed by Geoffrey Garen.
+
+ Casting a block to a bool will always return true, which isn't the behavior that is intended here.
+ Instead we need to call the block, but C semantics don't allow this, so we need to change
+ testapi.m to be Objective-C++ and therefore testapi.mm.
+
+ * API/tests/testapi.m: Removed.
+ * API/tests/testapi.mm: Copied from Source/JavaScriptCore/API/tests/testapi.m.
+ (blockSignatureContainsClass):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2013-01-06 Filip Pizlo <fpizlo@apple.com>
+
+ Simplify slow case profiling
+ https://bugs.webkit.org/show_bug.cgi?id=106208
+
+ Reviewed by Mark Rowe.
+
+ Removing the minimum execution ratio portion of slow case profiling, which allows
+ the removal of a field from CodeBlock. This appears to be performance neutral,
+ implying that the complexity incurred by the previous heuristic was purely
+ harmful: it made the code more complicated, and it made CodeBlock larger, without
+ resulting in any measurable benefits.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::likelyToTakeSlowCase):
+ (JSC::CodeBlock::couldTakeSlowCase):
+ (JSC::CodeBlock::likelyToTakeSpecialFastCase):
+ (JSC::CodeBlock::couldTakeSpecialFastCase):
+ (JSC::CodeBlock::likelyToTakeDeepestSlowCase):
+ (JSC::CodeBlock::likelyToTakeAnySlowCase):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * runtime/Options.h:
+
+2013-01-05 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should inline closure calls
+ https://bugs.webkit.org/show_bug.cgi?id=106067
+
+ Reviewed by Gavin Barraclough.
+
+ This adds initial support for inlining closure calls to the DFG. A call is considered
+ to be a closure call when the JSFunction* varies, but always has the same executable.
+ We already have closure call inline caching in both JITs, which works by checking that
+ the callee has an expected structure (as a cheap way of detecting that it is in fact
+ a JSFunction) and an expected executable. Closure call inlining uses profiling data
+ aggregated by CallLinkStatus to decide when to specialize the call to the particular
+ structure/executable, and inline the call rather than emitting a call sequence. When
+ we choose to do a closure inline rather than an ordinary inline, a number of things
+ change about how inlining is performed:
+
+ - The inline is guarded by a CheckStructure/CheckExecutable rather than a
+ CheckFunction.
+
+ - Instead of propagating a constant value for the scope, we emit GetMyScope every time
+ that the scope is needed, which loads the scope from a local variable. We do similar
+ things for the callee.
+
+ - The prologue of the inlined code includes SetMyScope and SetCallee nodes to eagerly
+ plant the scope and callee into the "true call frame", i.e. the place on the stack
+ where the call frame would have been if the call had been actually performed. This
+ allows GetMyScope/GetCallee to work as they would if the code wasn't inlined. It
+ also allows for trivial handling of scope and callee for call frame reconstruction
+ upon stack introspection and during OSR.
+
+ - A new node called GetScope is introduced, which just gets the scope of a function.
+ This node has the expected CSE support. This allows for the
+ SetMyScope(GetScope(@function)) sequence to set up the scope in the true call frame.
+
+ - GetMyScope/GetCallee CSE can match against SetMyScope/SetCallee, which means that
+ the GetMyScope/GetCallee nodes emitted during parsing are often removed during CSE,
+ if we can prove that it is safe to do so.
+
+ - Inlining heuristics are adjusted to grok the cost of inlining a closure. We are
+ less likely to inline a closure call than we are to inline a normal call, since we
+ end up emitting more code for closures due to CheckStructure, CheckExecutable,
+ GetScope, SetMyScope, and SetCallee.
+
+ Additionally, I've fixed the VariableEventStream to ensure that we don't attempt to
+ plant Undefined into the true call frames. This was previously a harmless oversight,
+ but it becomes quite bad if OSR is relying on the scope/callee already having been
+ set and not subsequently clobbered by the OSR itself.
+
+ This is a ~60% speed-up on programs that frequently make calls to closures. It's
+ neutral on V8v7 and other major benchmark suites.
+
+ The lack of a definite speed-up is likely due the fact that closure inlining currently
+ does not do any cardinality [1] optimizations. We don't observe when a closure was
+ constructed within its caller, and so used the scope from its caller; and furthermore
+ we have no facility to detect when the scope is single. All scoped variable accesses
+ are assumed to be multiple instead. A subsequent step will be to ensure that closure
+ call inlining will be single and loving it.
+
+ [1] Single and loving it: Must-alias analysis for higher-order languages. Suresh
+ Jagannathan, Peter Thiemann, Stephen Weeks, and Andrew Wright. In POPL '98.
+
+ * bytecode/CallLinkStatus.cpp:
+ (JSC::CallLinkStatus::dump):
+ * bytecode/CallLinkStatus.h:
+ (JSC::CallLinkStatus::isClosureCall):
+ (CallLinkStatus):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::globalObjectFor):
+ (JSC):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecode/CodeOrigin.cpp:
+ (JSC::InlineCallFrame::dump):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::emitFunctionChecks):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::pureCSE):
+ (CSEPhase):
+ (JSC::DFG::CSEPhase::getCalleeLoadElimination):
+ (JSC::DFG::CSEPhase::checkExecutableElimination):
+ (JSC::DFG::CSEPhase::getMyScopeLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::mightInlineFunctionForClosureCall):
+ * dfg/DFGCapabilities.h:
+ (DFG):
+ (JSC::DFG::mightInlineFunctionForClosureCall):
+ (JSC::DFG::canInlineFunctionForClosureCall):
+ (JSC::DFG::canInlineFunctionFor):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::hasExecutable):
+ (JSC::DFG::Node::executable):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGVariableEventStream.cpp:
+ (JSC::DFG::VariableEventStream::reconstruct):
+ * runtime/Options.h:
+ (JSC):
+
+2013-01-05 Filip Pizlo <fpizlo@apple.com>
+
+ Data flow paths that carry non-numbers, non-undefined, non-null values should not cause subtractions and arithmetic additions (i.e. ++) to speculate double
+ https://bugs.webkit.org/show_bug.cgi?id=106190
+
+ Reviewed by Sam Weinig.
+
+ The problem is that the DFG logic for deciding when to speculate integer was
+ confusing the special case of ValueAdd (where non-numeric values should cause us
+ to not speculate integer, because we want to fall off into the generic case) with
+ the more normal case of ArithAdd and ArithSub (where we want to speculate integer
+ unless we have evidence that the operands are doubles, since the DFG doesn't have
+ generic handling of non-numeric arithmetic). Prior to this change doing a - b where
+ either a or b were possibly non-numeric would always force the subtraction to be
+ done using doubles.
+
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::addSpeculationMode):
+ (Graph):
+ (JSC::DFG::Graph::valueAddSpeculationMode):
+ (JSC::DFG::Graph::arithAddSpeculationMode):
+ (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
+
+2013-01-04 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should trust array profiling over value profiling
+ https://bugs.webkit.org/show_bug.cgi?id=106155
+
+ Reviewed by Gavin Barraclough.
+
+ The real problem is that prediction propagation is not flow-sensitive. We had code
+ like:
+
+ var a = (some load from memory); // returns either an array or false
+ if (a)
+ a[i] = v;
+
+ Because 'a' could be 'false', we were emitting a fully generic unoptimized PutByVal.
+ This patch changes ArrayMode to ignore the type of the base of an array access, if
+ array profiling tells us that the array access can be optimized.
+
+ In the future, we could probably make this work even better with some flow
+ sensitivity in the prediction propagator, but I also tend to think that this is a
+ more robust overall solution. If we ever did want to support array accesses on
+ array-or-false then we should change the array profiler to be able to tell us that
+ this is what is going on.
+
+ 3.7% speed-up on V8/earley.
+
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::refine):
+
+2013-01-04 Filip Pizlo <fpizlo@apple.com>
+
+ Rationalize exit site profiling for calls
+ https://bugs.webkit.org/show_bug.cgi?id=106150
+
+ Reviewed by Sam Weinig.
+
+ This adds two new exit kinds for calls: BadFunction and BadExecutable. The latter is not used
+ yet, but is already integrated with profiling. CheckFunction uses a BadFunction speculation
+ instead of BadCache, now. This allows CallLinkStatus to turn itself into a closure call status
+ if we had a BadFunction exit site but the CallLinkInfo told us to use a non-closure call. This
+ might happen if we had call unlinking that led to information loss along the way.
+
+ No performance impact. This is meant as another step towards inlining closure calls.
+
+ * bytecode/CallLinkStatus.cpp:
+ * bytecode/CallLinkStatus.h:
+ (JSC::CallLinkStatus::setIsProved):
+ (JSC::CallLinkStatus::setHasBadFunctionExitSite):
+ (CallLinkStatus):
+ (JSC::CallLinkStatus::setHasBadCacheExitSite):
+ (JSC::CallLinkStatus::setHasBadExecutableExitSite):
+ * bytecode/ExitKind.cpp:
+ (JSC::exitKindToString):
+ * bytecode/ExitKind.h:
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleCall):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2013-01-03 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not elide CheckStructure if it's needed to perform a cell check
+ https://bugs.webkit.org/show_bug.cgi?id=106074
+
+ Reviewed by Ryosuke Niwa.
+
+ The problem here was that the constant folding phase was misinterpreting the meaning of the sets
+ in DFG::AbstractValue. AbstractValue describes a constraint on the values that a variable (i.e.
+ a DFG Node, or a virtual register, i.e. local or argument) may have. It does so by containing
+ four sets: the set of JSValues (either empty, the singleton set containing one JSValue, or the
+ set of all JSValues); the set of "current known" structures, i.e. the set of structures that you
+ already know that this value may have right now (also either empty, the singleton set, or the set
+ of all structures); the set of "future possible" structures, i.e. the set of structures that this
+ value could have in the future if none of the structure transition watchpoints for those
+ structures had fired (also empty, singleton, or all); and the set of types, which is a
+ SpeculatedType bitmask. The correct way to interpret the sets is to think of the AbstractValue as
+ the intersection of these three sets of values:
+
+ - The set of JSValues that have a type that belongs to the m_type set.
+ - If m_value is not the empty value then: the set of all JSValues that are == m_value;
+ else: the set of all JSValues.
+ where '==' is as defined by JSValue::operator==.
+ - Union of { the set of all cells that have a structure that belongs to m_currentKnownStructure }
+ and { the set of all JSValues that are not cells }.
+
+ You can then further intersect this set with the following set, if you guard the code with
+ watchpoints on all structures in the m_futurePossibleStructure:
+
+ - Union of { the set of all cells that have a structure that belongs to m_futurePossibleStructure }
+ and { the set of all JSValues that are not cells }.
+
+ One way to think of this is that m_currentKnownStructure is filtered by m_futurePossibleStructure
+ (i.e. is set to the intersection of m_currentKnownStructure and m_futurePossibleStructure), if the
+ code for which you're doing this is always preceded by watchpoints on all structures in
+ m_futurePossibleStructure, and is always before any side-effects that could change the structures
+ of objects.
+
+ The incorrect optimization related to CheckStructure. CheckStructure checks that the value is a
+ cell, and that it has a particular structure. It was incorrectly assuming that you could eliminate
+ the CheckStructure, if m_currentKnownStructure contained the structure that CheckStructure was
+ checking. But this is not the case, since m_currentKnownStructure does not prove that the value is
+ a cell with a particular structure; it only proves that if the value was a cell then it would have
+ a particular structure. Hence, to eliminate CheckStructure, it is also necessary to check that
+ AbstractValue::m_type contains only cells (i.e. isCellSpeculation(m_type) == true).
+
+ It wasn't doing that, and this changes makes sure that it does do that.
+
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2013-01-04 Adam Klein <adamk@chromium.org>
+
+ Remove ENABLE_MUTATION_OBSERVERS #define
+ https://bugs.webkit.org/show_bug.cgi?id=105459
+
+ Reviewed by Ryosuke Niwa.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2013-01-03 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::ByteCodeCache serves little or no purpose ever since we decided to keep bytecode around permanently
+ https://bugs.webkit.org/show_bug.cgi?id=106058
+
+ Reviewed by Michael Saboff.
+
+ All baseline code blocks now always have bytecode, so the bytecode cache's ability to minimize the
+ number of times that the DFG produces bytecode sequences for code blocks is superfluous.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGByteCodeCache.h: Removed.
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ * runtime/Executable.cpp:
+ (JSC):
+ * runtime/Executable.h:
+ (FunctionExecutable):
+
+2013-01-03 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix build for DFG JIT disabled.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpValueProfiling):
+ (JSC::CodeBlock::dumpArrayProfiling):
+ * runtime/Executable.cpp:
+ (JSC):
+ (JSC::ExecutableBase::intrinsic):
+
+2013-01-03 Filip Pizlo <fpizlo@apple.com>
+
+ CallLinkStatus should be aware of closure calls, and the DFG bytecode parser should use that as its sole internal notion of how to optimize calls
+ https://bugs.webkit.org/show_bug.cgi?id=106027
+
+ Reviewed by Mark Hahnenberg.
+
+ Previously, the DFG bytecode parser had its own internal notion of exactly what CallLinkStatus was
+ meant to do, in the form of a CallType, expectedFunction, intrinsic, etc. This change makes CallLinkStatus
+ smart enough to do all of that, and also gives it the ability to understand closure calls.
+
+ * bytecode/CallLinkStatus.cpp:
+ (JSC::CallLinkStatus::CallLinkStatus):
+ (JSC):
+ (JSC::CallLinkStatus::function):
+ (JSC::CallLinkStatus::internalFunction):
+ (JSC::CallLinkStatus::intrinsicFor):
+ (JSC::CallLinkStatus::setIsProved):
+ (JSC::CallLinkStatus::computeFromLLInt):
+ (JSC::CallLinkStatus::computeFor):
+ (JSC::CallLinkStatus::dump):
+ * bytecode/CallLinkStatus.h:
+ (JSC):
+ (JSC::CallLinkStatus::CallLinkStatus):
+ (CallLinkStatus):
+ (JSC::CallLinkStatus::takesSlowPath):
+ (JSC::CallLinkStatus::isSet):
+ (JSC::CallLinkStatus::isClosureCall):
+ (JSC::CallLinkStatus::callTarget):
+ (JSC::CallLinkStatus::executable):
+ (JSC::CallLinkStatus::structure):
+ (JSC::CallLinkStatus::isProved):
+ (JSC::CallLinkStatus::canOptimize):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleCall):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::valueOfFunctionConstant):
+
+2013-01-02 Simon Hausmann <simon.hausmann@digia.com>
+
+ [MinGW-w64] Centralize workaround for pow() implementation
+ https://bugs.webkit.org/show_bug.cgi?id=105925
+
+ Reviewed by Sam Weinig.
+
+ As suggested by Sam, move the MinGW-w64 workaround into MathExtras.h
+ away from the JSC usage.
+
+ * runtime/MathObject.cpp:
+ (JSC::mathPow):
+
+2013-01-02 Gavin Barraclough <barraclough@apple.com>
+
+ Objective-C API for JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=105889
+
+ Reviewed by Geoff Garen.
+
+ Fixes for more issues raised by Darin.
+
+ * API/JSBlockAdaptor.mm:
+ (BlockArgument):
+ (BlockArgumentStruct::BlockArgumentStruct):
+ (BlockArgumentTypeDelegate::typeStruct):
+ (BlockResult):
+ (BlockResultStruct::BlockResultStruct):
+ (buildBlockSignature):
+ (-[JSBlockAdaptor initWithBlockSignatureFromProtocol:]):
+ (-[JSBlockAdaptor blockFromValue:inContext:withException:]):
+ - fix * position for Objective-C types
+ * API/JSContext.h:
+ - fix * position for Objective-C types
+ * API/JSContext.mm:
+ (-[JSContext initWithVirtualMachine:]):
+ (-[JSContext virtualMachine]):
+ (contextInternalContext):
+ - fix * position for Objective-C types
+ (-[JSContext dealloc]):
+ (-[JSContext protect:]):
+ (-[JSContext unprotect:]):
+ - HashMap<JSValueRef, size_t> -> HashCountedSet<JSValueRef>
+ * API/JSContextInternal.h:
+ (WeakContextRef):
+ - fix * position for Objective-C types
+ * API/JSValue.mm:
+ (valueToString):
+ - fix * position for Objective-C types
+ (isNSBoolean):
+ - Added helper to check for booleans.
+ (objectToValueWithoutCopy):
+ - Added contextRef
+ - fix * position for Objective-C types
+ - Remove @YES, @NO literal usage, use isNSBoolean instead
+ (objectToValue):
+ - Added contextRef
+ (+[JSValue valueWithValue:inContext:]):
+ (-[JSValue initWithValue:inContext:]):
+ - fix * position for Objective-C types
+ (createStructHandlerMap):
+ (handerForStructTag):
+ - getStructTagHandler -> handerForStructTag
+ - Split out createStructHandlerMap
+ - strncmp -> memcmp
+ - String(type).impl() -> StringImpl::create(type)
+ (+[JSValue selectorForStructToValue:]):
+ (+[JSValue selectorForValueToStruct:]):
+ - getStructTagHandler -> handerForStructTag
+ (typeToValueInvocationFor):
+ (valueToTypeInvocationFor):
+ - fix * position for Objective-C types
+ * API/JSValueInternal.h:
+ - fix * position for Objective-C types
+ * API/JSVirtualMachineInternal.h:
+ - fix * position for Objective-C types
+ * API/JSWrapperMap.h:
+ - fix * position for Objective-C types
+ * API/JSWrapperMap.mm:
+ (selectorToPropertyName):
+ (createObjectWithCustomBrand):
+ (createRenameMap):
+ (putNonEnumerable):
+ (copyMethodsToObject):
+ (copyPrototypeProperties):
+ (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]):
+ (-[JSWrapperMap initWithContext:]):
+ (-[JSWrapperMap wrapperForObject:]):
+ (getJSExportProtocol):
+ - fix * position for Objective-C types
+ * API/ObjCCallbackFunction.h:
+ - fix * position for Objective-C types
+ * API/ObjCCallbackFunction.mm:
+ (CallbackArgument):
+ (CallbackArgumentStruct::CallbackArgumentStruct):
+ - fix * position for Objective-C types
+ (CallbackArgumentBlockCallback::createAdoptingJSBlockAdaptor):
+ - Added to make adopt explicit
+ (CallbackArgumentBlockCallback):
+ (CallbackArgumentBlockCallback::CallbackArgumentBlockCallback):
+ (ArgumentTypeDelegate::typeBlock):
+ - Call createAdoptingJSBlockAdaptor
+ (ArgumentTypeDelegate::typeStruct):
+ (CallbackResult):
+ (CallbackResultStruct::CallbackResultStruct):
+ (ResultTypeDelegate::typeStruct):
+ (ObjCCallbackFunction::ObjCCallbackFunction):
+ (ObjCCallbackFunction::context):
+ (objCCallbackFunctionForInvocation):
+ (objCCallbackFunctionForMethod):
+ (objCCallbackFunctionForBlock):
+ - fix * position for Objective-C types
+ * API/ObjcRuntimeExtras.h:
+ (protocolImplementsProtocol):
+ (forEachProtocolImplementingProtocol):
+ (forEachMethodInProtocol):
+ (forEachPropertyInProtocol):
+ - fix * position for Objective-C types
+ * API/tests/testapi.m:
+ (-[TestObject testArgumentTypesWithInt:double:boolean:string:number:array:dictionary:]):
+ (testObjectiveCAPI):
+ - fix * position for Objective-C types
+
+2013-01-02 Geoffrey Garen <ggaren@apple.com>
+
+ Some renaming in the CodeCache
+ https://bugs.webkit.org/show_bug.cgi?id=105966
+
+ Reviewed by Gavin Barraclough.
+
+ CodeBlockKey => SourceCodeKey because the key is not a CodeBlock.
+
+ m_recentlyUsedFunctionCode => m_recentlyUsedFunctions to match other names.
+
+ GlobalFunctionKey => FunctionKey because the key is not unique to globalness.
+
+ m_cachedGlobalFunctions => m_globalFunctions because "cached" is redundant
+ for data members in an object called "CodeCache".
+
+ kMaxRootCodeBlockEntries => kMaxRootEntries because there are no non-CodeBlock
+ entries in a CodeBlock cache.
+
+ kMaxFunctionCodeBlocks => kMaxChildFunctionEntries to clarify that this
+ number models a parent-child relationship.
+
+ Also removed the initial "k" from enum constants. That's an interesting
+ style for calling out constants, but it's not the WebKit style.
+
+ Finally, a behavior change: Use MaxRootEntries for the limit on global
+ functions, and not MaxChildFunctionEntries. Previously, there was an
+ unused constant that seemed to have been intended for this purpose.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::makeSourceCodeKey):
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::generateFunctionCodeBlock):
+ (JSC::CodeCache::makeFunctionKey):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ (JSC::CodeCache::usedFunctionCode):
+ * runtime/CodeCache.h:
+ (JSC::CodeCache::clear):
+
+2013-01-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG inlining machinery should be robust against the inline callee varying while the executable stays the same
+ https://bugs.webkit.org/show_bug.cgi?id=105953
+
+ Reviewed by Mark Hahnenberg.
+
+ This institutes the policy that if InlineCallFrame::callee is null, then the callee and scope have already
+ been stored into the true call frame (i.e. the place where the call frame of the inlined call would have
+ been) and so any attempt to access the callee or scope should do a load instead of assuming that the value
+ is constant. This wires the changes through the bytecode parser, the stack scanning logic, and the compiler
+ optimization phases and backends.
+
+ * bytecode/CodeOrigin.cpp:
+ (JSC::InlineCallFrame::dump):
+ * bytecode/CodeOrigin.h:
+ (CodeOrigin):
+ (InlineCallFrame):
+ (JSC::InlineCallFrame::isClosureCall):
+ (JSC::CodeOrigin::stackOffset):
+ (JSC):
+ * dfg/DFGAssemblyHelpers.h:
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::get):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::getScope):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCSEPhase.cpp:
+ (CSEPhase):
+ (JSC::DFG::CSEPhase::genericPureCSE):
+ (JSC::DFG::CSEPhase::pureCSE):
+ (JSC::DFG::CSEPhase::pureCSERequiringSameInlineCallFrame):
+ (JSC::DFG::CSEPhase::getMyScopeLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::trueCallFrame):
+
+2013-01-02 Gavin Barraclough <barraclough@apple.com>
+
+ Objective-C API for JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=105889
+
+ Reviewed by Geoff Garen.
+
+ Fixes for a number of issues raised by Darin.
+
+ * API/APIJSValue.h:
+ - Fix typos in comment
+ - Add newline before NS_CLASS_AVAILABLE(10_9, NA)
+ - cls -> expectedClass
+ - key type for -setObject:forKeyedSubscript: is now NSObject <NSCopying> *
+ * API/JSBase.h:
+ - JS_OBJC_API_ENABLED no longer implies __OBJC__
+ * API/JSBlockAdaptor.mm:
+ (BlockArgumentStruct::BlockArgumentStruct):
+ (BlockArgumentStruct):
+ - mark virtual functions as virtual, override, and private
+ - refactor out buffer allocation for struct types
+ (BlockArgumentTypeDelegate::typeVoid):
+ (BlockArgumentTypeDelegate::typeBlock):
+ (BlockArgumentTypeDelegate::typeStruct):
+ - return nil -> return 0
+ (BlockResultStruct::BlockResultStruct):
+ (BlockResultStruct):
+ - mark virtual functions as virtual, override, and private
+ - refactor out buffer allocation for struct types
+ (buildBlockSignature):
+ - %lu is not an appropriate format specifier for NSInteger
+ (-[JSBlockAdaptor initWithBlockSignatureFromProtocol:]):
+ - nil check [super init]
+ (-[JSBlockAdaptor blockMatchesSignature:]):
+ (-[JSBlockAdaptor blockFromValue:inContext:withException:]):
+ - ctx -> contextRef
+ * API/JSContext.h:
+ - Fix typos in comment
+ - Add newline before NS_CLASS_AVAILABLE(10_9, NA)
+ - key type for -setObject:forKeyedSubscript: is now NSObject <NSCopying> *
+ * API/JSContext.mm:
+ (-[JSContext initWithVirtualMachine:]):
+ - nil check [super init]
+ (+[JSContext currentArguments]):
+ - args -> argumentArray
+ (-[JSContext setObject:forKeyedSubscript:]):
+ - key type for -setObject:forKeyedSubscript: is now NSObject <NSCopying> *
+ (-[JSContext dealloc]):
+ (-[JSContext protect:]):
+ (-[JSContext unprotect:]):
+ - m_protected -> m_protectCounts
+ * API/JSValue.mm:
+ (-[JSValue toObjectOfClass:]):
+ - cls -> expectedClass
+ (-[JSValue toBool]):
+ (-[JSValue deleteProperty:]):
+ (-[JSValue hasProperty:]):
+ (-[JSValue isUndefined]):
+ (-[JSValue isNull]):
+ (-[JSValue isBoolean]):
+ (-[JSValue isNumber]):
+ (-[JSValue isString]):
+ (-[JSValue isObject]):
+ (-[JSValue isEqualToObject:]):
+ (-[JSValue isEqualWithTypeCoercionToObject:]):
+ (-[JSValue isInstanceOf:]):
+ - removed ? YES : NO
+ (-[JSValue callWithArguments:]):
+ (-[JSValue constructWithArguments:]):
+ (-[JSValue invokeMethod:withArguments:]):
+ - args -> argumentArray
+ (+[JSValue valueWithPoint:inContext:]):
+ (+[JSValue valueWithRange:inContext:]):
+ (+[JSValue valueWithRect:inContext:]):
+ (+[JSValue valueWithSize:inContext:]):
+ - [NSNumber numberWithFloat:] -> @()
+ (-[JSValue objectForKeyedSubscript:]):
+ (-[JSValue setObject:forKeyedSubscript:]):
+ - key type for -setObject:forKeyedSubscript: is now NSObject <NSCopying> *
+ (JSContainerConvertor):
+ (JSContainerConvertor::isWorkListEmpty):
+ (JSContainerConvertor::convert):
+ (ObjcContainerConvertor):
+ (ObjcContainerConvertor::isWorkListEmpty):
+ - remove WTF::
+ - isWorkListEmpty is const
+ (objectToValue):
+ - use fast enumeration
+ (-[JSValue initWithValue:inContext:]):
+ - nil check [super init]
+ (getStructTagHandler):
+ - m_structHandlers -> structHandlers
+ * API/JSVirtualMachine.h:
+ - Add newline before NS_CLASS_AVAILABLE(10_9, NA)
+ * API/JSVirtualMachine.mm:
+ (-[JSVirtualMachine init]):
+ - nil check [super init]
+ * API/JSWrapperMap.mm:
+ (selectorToPropertyName):
+ (copyPrototypeProperties):
+ - remove WTF::
+ - use static_cast
+ (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]):
+ (-[JSWrapperMap initWithContext:]):
+ - nil check [super init]
+ (-[JSWrapperMap wrapperForObject:]):
+ (tryUnwrapObjcObject):
+ - enable ASSERT
+ (getJSExportProtocol):
+ (getNSBlockClass):
+ - remove if check on initializing static
+ * API/JavaScriptCore.h:
+ - JS_OBJC_API_ENABLED no longer implies __OBJC__
+ * API/ObjCCallbackFunction.mm:
+ (CallbackArgumentOfClass):
+ (CallbackArgumentOfClass::~CallbackArgumentOfClass):
+ (CallbackArgumentStruct::CallbackArgumentStruct):
+ (CallbackArgumentStruct):
+ (CallbackArgumentBlockCallback):
+ - mark virtual functions as virtual, override, and private
+ - refactor out buffer allocation for struct types
+ (ArgumentTypeDelegate::typeVoid):
+ (ArgumentTypeDelegate::typeOfClass):
+ (ArgumentTypeDelegate::typeStruct):
+ - return nil -> return 0
+ (CallbackResultStruct::CallbackResultStruct):
+ (CallbackResultStruct):
+ - mark virtual functions as virtual, override, and private
+ - refactor out buffer allocation for struct types
+ (ResultTypeDelegate::typeStruct):
+ - return nil -> return 0
+ (ObjCCallbackFunction):
+ - remove WTF::
+ (objCCallbackFunctionFinalize):
+ - use static_cast
+ (objCCallbackFunctionCallAsFunction):
+ - Fix typos in comment
+ (createObjCCallbackFunctionClass):
+ (objCCallbackFunctionClass):
+ - Split out createObjCCallbackFunctionClass from objCCallbackFunctionClass
+ (ObjCCallbackFunction::call):
+ - ctx -> contextRef
+ (blockSignatureContainsClass):
+ - Remove tri-state enum.
+ (skipNumber):
+ - isdigit -> isASCIIDigit
+ (objCCallbackFunctionForInvocation):
+ - clean up & comment blockSignatureContainsClass() usage
+ (tryUnwrapBlock):
+ - use static_cast
+ * API/ObjcRuntimeExtras.h:
+ (forEachProtocolImplementingProtocol):
+ (forEachMethodInClass):
+ (forEachMethodInProtocol):
+ (forEachPropertyInProtocol):
+ - Remove WTF::
+ - Remove if (count) checks
+ (skipPair):
+ - NSUInteger -> size_t
+ (StringRange):
+ (StringRange::operator const char*):
+ (StringRange::get):
+ (StructBuffer):
+ (StructBuffer::StructBuffer):
+ (StructBuffer::~StructBuffer):
+ (StructBuffer::operator void*):
+ - Added helper for creating an aligned buffer, used by struct conversion invocations.
+ (parseObjCType):
+ - *(position++) -> *position++
+ * API/tests/testapi.c:
+ - PLATFORM(MAC) -> JS_OBJC_API_ENABLED
+ * API/tests/testapi.m:
+ (blockSignatureContainsClass):
+ - Remove tri-state enum.
+ (testObjectiveCAPI):
+ - Added more result type checks.
+
+2013-01-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not use the InlineCallFrame's callee when it could have used the executable istead
+ https://bugs.webkit.org/show_bug.cgi?id=105947
+
+ Reviewed by Mark Hahnenberg.
+
+ We shouldn't use the callee to get the executable when we have the executable already. Not only
+ does this make the logic more clear, but it also allows for a world where the executable is known
+ but the callee isn't.
+
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::strictModeFor):
+
+2013-01-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG inliner should not use the callee's bytecode variable for resolving references to the callee in inlined code
+ https://bugs.webkit.org/show_bug.cgi?id=105938
+
+ Reviewed by Mark Hahnenberg.
+
+ This simplifies a bunch of code for referring to the callee. It also ought to simplify how we do
+ closure call inlining: for inlined closure call frames we will simply require that the callee is
+ already stashed on the stack in the Callee slot in the inline call frame header.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::getDirect):
+ (JSC::DFG::ByteCodeParser::get):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::parse):
+
+2013-01-02 Ryosuke Niwa <rniwa@webkit.org>
+
+ Another Windows port build fix attempt. Try not exporting this symbol from JSC
+ since it's also compiled in WebCore.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2013-01-02 Csaba Osztrogonác <ossy@webkit.org>
+
+ One more unreviewed buildfix after r138609.
+
+ * jit/JITCall.cpp: Add a missing include.
+
+2013-01-02 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed buildfix after r138609.
+
+ * jit/JITCall32_64.cpp: Add a missing include.
+
+2013-01-01 Filip Pizlo <fpizlo@apple.com>
+
+ Baseline JIT should have closure call caching
+ https://bugs.webkit.org/show_bug.cgi?id=105900
+
+ Reviewed by Gavin Barraclough.
+
+ This is not a speed-up by itself, but is meant to allow the DFG inliner to
+ accurately discern between closure calls and non-closure calls, so that it can
+ do closure call inlining in the future.
+
+ * bytecode/CallLinkStatus.cpp:
+ (JSC::CallLinkStatus::computeFromLLInt):
+ (JSC::CallLinkStatus::computeFor):
+ * bytecode/CallLinkStatus.h:
+ (JSC::CallLinkStatus::CallLinkStatus):
+ (JSC::CallLinkStatus::isClosureCall):
+ (CallLinkStatus):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleCall):
+ * jit/JIT.cpp:
+ (JSC::JIT::linkFor):
+ (JSC::JIT::linkSlowCall):
+ * jit/JIT.h:
+ (JSC::JIT::compileClosureCall):
+ * jit/JITCall.cpp:
+ (JSC::JIT::privateCompileClosureCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::privateCompileClosureCall):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ * jit/ThunkGenerators.cpp:
+ (JSC::linkClosureCallGenerator):
+ * jit/ThunkGenerators.h:
+
+2013-01-01 Dan Bernstein <mitz@apple.com>
+
+ <rdar://problem/12942239> Update copyright strings
+
+ Reviewed by Sam Weinig.
+
+ * Info.plist:
+
+2012-12-31 Gavin Barraclough <barraclough@apple.com>
+
+ Objective-C API for JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=105889
+
+ Reviewed by Filip Pizlo.
+
+ For a detailed description of the API implemented here, see:
+ JSContext.h
+ APIJSValue.h
+ JSVirtualMachine.h
+ JSExport.h
+ Still to do -
+ (1) Shoud rename APIJSValue.h -> JSValue.h (but we'll have to rename JSValue.h first).
+ (2) Numerous FIXMEs, all with separate bugs filed.
+
+ * API/APIJSValue.h: Added.
+ - this Objective-C class is used to reference a JavaScript object.
+ * API/JSBase.h:
+ - added JS_OBJC_API_ENABLED macro to control ObjC API support.
+ * API/JSBlockAdaptor.h: Added.
+ - this Objective-C class is used in creating a special NSBlock proxying a JavaScript function.
+ * API/JSBlockAdaptor.mm: Added.
+ (BlockArgument):
+ (BlockArgument::~BlockArgument):
+ (BlockArgumentBoolean):
+ (BlockArgumentBoolean::get):
+ (BlockArgumentNumeric):
+ (BlockArgumentNumeric::get):
+ (BlockArgumentId):
+ (BlockArgumentId::get):
+ (BlockArgumentStruct):
+ (BlockArgumentStruct::BlockArgumentStruct):
+ (BlockArgumentStruct::~BlockArgumentStruct):
+ (BlockArgumentStruct::get):
+ - decoded arguent type information of a JSBlockAdaptor.
+ (BlockArgumentTypeDelegate):
+ (BlockArgumentTypeDelegate::typeInteger):
+ (BlockArgumentTypeDelegate::typeDouble):
+ (BlockArgumentTypeDelegate::typeBool):
+ (BlockArgumentTypeDelegate::typeVoid):
+ (BlockArgumentTypeDelegate::typeId):
+ (BlockArgumentTypeDelegate::typeOfClass):
+ (BlockArgumentTypeDelegate::typeBlock):
+ (BlockArgumentTypeDelegate::typeStruct):
+ - delegate for use in conjunction with parseObjCType.
+ (BlockResult):
+ (BlockResult::~BlockResult):
+ (BlockResultVoid):
+ (BlockResultVoid::set):
+ (BlockResultInteger):
+ (BlockResultInteger::set):
+ (BlockResultDouble):
+ (BlockResultDouble::set):
+ (BlockResultBoolean):
+ (BlockResultBoolean::set):
+ (BlockResultStruct):
+ (BlockResultStruct::BlockResultStruct):
+ (BlockResultStruct::~BlockResultStruct):
+ (BlockResultStruct::set):
+ - decoded result type information of a JSBlockAdaptor.
+ (buildBlockSignature):
+ - partial step in constructing a signature with stack offset information from one without.
+ (-[JSBlockAdaptor initWithBlockSignatureFromProtocol:]):
+ - constructor.
+ (-[JSBlockAdaptor blockMatchesSignature:]):
+ - check whether signature strings match, where only one contains stack frame offsets.
+ (-[JSBlockAdaptor blockFromValue:inContext:withException:]):
+ - use the adaptor to create a special forwarding block.
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::inherits):
+ - add missing braces to multiline for statement.
+ * API/JSContext.h: Added.
+ - this Objective-C class is used to reference a JavaScript context.
+ * API/JSContext.mm: Added.
+ (-[JSContext init]):
+ - constructor.
+ (-[JSContext initWithVirtualMachine:]):
+ - construct in a given VM (JSGlobalData).
+ (-[JSContext evaluateScript:]):
+ (-[JSContext globalObject]):
+ - evaluate a script, global object accessor.
+ (+[JSContext currentContext]):
+ (+[JSContext currentThis]):
+ (+[JSContext currentArguments]):
+ - These methods obtain context, this, arguments from within a callback.
+ (-[JSContext virtualMachine]):
+ - implementation for .virtualMachine property.
+ (-[JSContext objectForKeyedSubscript:]):
+ (-[JSContext setObject:forKeyedSubscript:]):
+ - support for subscript property access.
+ (contextInternalContext):
+ - internal accessor to m_context.
+ (-[JSContext dealloc]):
+ - desctructor.
+ (-[JSContext notifyException:]):
+ (-[JSContext valueFromNotifyException:]):
+ (-[JSContext boolFromNotifyException:]):
+ - internal method to record an exception was thrown.
+ (-[JSContext beginCallbackWithData:thisValue:argumentCount:arguments:]):
+ (-[JSContext endCallbackWithData:]):
+ - internal methods to push/pop a callback record.
+ (-[JSContext protect:]):
+ (-[JSContext unprotect:]):
+ - internal methods to add a value to a protect set (used to protect the internal property of JSValue).
+ (-[JSContext wrapperForObject:]):
+ - internal method to create a wrapper object.
+ (WeakContextRef::WeakContextRef):
+ (WeakContextRef::~WeakContextRef):
+ (WeakContextRef::get):
+ (WeakContextRef::set):
+ - Helper class to implement a weak reference to a JSContext.
+ * API/JSContextInternal.h: Added.
+ (CallbackData):
+ (WeakContextRef):
+ - see API/JSContext.mm for description of internal methods.
+ * API/JSExport.h: Added.
+ - Provides JSExport protocol & JSExportAs macro.
+ * API/JSValue.mm: Added.
+ (+[JSValue valueWithObject:inContext:]):
+ (+[JSValue valueWithBool:inContext:]):
+ (+[JSValue valueWithDouble:inContext:]):
+ (+[JSValue valueWithInt32:inContext:]):
+ (+[JSValue valueWithUInt32:inContext:]):
+ (+[JSValue valueWithNewObjectInContext:]):
+ (+[JSValue valueWithNewArrayInContext:]):
+ (+[JSValue valueWithNewRegularExpressionFromPattern:flags:inContext:]):
+ (+[JSValue valueWithNewErrorFromMessage:inContext:]):
+ (+[JSValue valueWithNullInContext:]):
+ (+[JSValue valueWithUndefinedInContext:]):
+ - Constructors.
+ (-[JSValue toObject]):
+ (-[JSValue toObjectOfClass:]):
+ (-[JSValue toBool]):
+ (-[JSValue toDouble]):
+ (-[JSValue toInt32]):
+ (-[JSValue toUInt32]):
+ (-[JSValue toNumber]):
+ (-[JSValue toString]):
+ (-[JSValue toDate]):
+ (-[JSValue toArray]):
+ (-[JSValue toDictionary]):
+ - Conversion to Objective-C types.
+ (-[JSValue valueForProperty:]):
+ (-[JSValue setValue:forProperty:]):
+ (-[JSValue deleteProperty:]):
+ (-[JSValue hasProperty:]):
+ (-[JSValue defineProperty:descriptor:]):
+ - Property access by property name.
+ (-[JSValue valueAtIndex:]):
+ (-[JSValue setValue:atIndex:]):
+ - Property access by index.
+ (-[JSValue isUndefined]):
+ (-[JSValue isNull]):
+ (-[JSValue isBoolean]):
+ (-[JSValue isNumber]):
+ (-[JSValue isString]):
+ (-[JSValue isObject]):
+ - Test JavaScript type.
+ (-[JSValue isEqualToObject:]):
+ (-[JSValue isEqualWithTypeCoercionToObject:]):
+ (-[JSValue isInstanceOf:]):
+ - ===, ==, instanceof operators.
+ (-[JSValue callWithArguments:]):
+ (-[JSValue constructWithArguments:]):
+ (-[JSValue invokeMethod:withArguments:]):
+ - Call & construct.
+ (-[JSValue context]):
+ - implementation for .context property.
+ (-[JSValue toPoint]):
+ (-[JSValue toRange]):
+ (-[JSValue toRect]):
+ (-[JSValue toSize]):
+ (+[JSValue valueWithPoint:inContext:]):
+ (+[JSValue valueWithRange:inContext:]):
+ (+[JSValue valueWithRect:inContext:]):
+ (+[JSValue valueWithSize:inContext:]):
+ - Support for NS struct types.
+ (-[JSValue objectForKeyedSubscript:]):
+ (-[JSValue objectAtIndexedSubscript:]):
+ (-[JSValue setObject:forKeyedSubscript:]):
+ (-[JSValue setObject:atIndexedSubscript:]):
+ - support for subscript property access.
+ (isDate):
+ (isArray):
+ - internal helper functions to check for instances of JS Date, Array types.
+ (JSContainerConvertor):
+ (Task):
+ (JSContainerConvertor::JSContainerConvertor):
+ (JSContainerConvertor::isWorkListEmpty):
+ (JSContainerConvertor::convert):
+ (JSContainerConvertor::add):
+ (JSContainerConvertor::take):
+ - helper class for tracking state while converting to Array/Dictionary objects.
+ (valueToObjectWithoutCopy):
+ (containerValueToObject):
+ (valueToObject):
+ (valueToNumber):
+ (valueToString):
+ (valueToDate):
+ (valueToArray):
+ (valueToDictionary):
+ - function for converting JavaScript values to Objective-C objects.
+ (ObjcContainerConvertor):
+ (ObjcContainerConvertor::ObjcContainerConvertor):
+ (ObjcContainerConvertor::isWorkListEmpty):
+ (ObjcContainerConvertor::convert):
+ (ObjcContainerConvertor::add):
+ (ObjcContainerConvertor::take):
+ - helper class for tracking state while converting to Array/Dictionary values.
+ (objectToValueWithoutCopy):
+ (objectToValue):
+ (valueInternalValue):
+ - function for converting Objective-C objects to JavaScript values.
+ (+[JSValue valueWithValue:inContext:]):
+ (-[JSValue initWithValue:inContext:]):
+ - internal constructors.
+ (StructTagHandler):
+ (getStructTagHandler):
+ (+[JSValue selectorForStructToValue:]):
+ (+[JSValue selectorForValueToStruct:]):
+ - methods to tracking struct types that support conversion to/from JSValue.
+ (-[JSValue dealloc]):
+ - destructor.
+ (-[JSValue description]):
+ - Objective-C to-NSString conversion.
+ (typeToValueInvocationFor):
+ (valueToTypeInvocationFor):
+ - create invocation objects for conversion to/from JSValue.
+ * API/JSValueInternal.h: Added.
+ - see API/JSValue.mm for description of internal methods.
+ * API/JSVirtualMachine.h: Added.
+ - this Objective-C class is used to reference a JavaScript virtual machine (JSGlobalData).
+ * API/JSVirtualMachine.mm: Added.
+ (-[JSVirtualMachine init]):
+ (-[JSVirtualMachine dealloc]):
+ - constructor & destructor.
+ (getGroupFromVirtualMachine):
+ - internal accessor for m_group property.
+ * API/JSVirtualMachineInternal.h: Added.
+ - see API/JSVirtualMachine.mm for description of internal methods.
+ * API/JSWrapperMap.h: Added.
+ * API/JSWrapperMap.mm: Added.
+ (wrapperClass):
+ - singleton root for detction (& unwrapping) of wrapper objects.
+ (selectorToPropertyName):
+ - default selector to property name conversion.
+ (createObjectWithCustomBrand):
+ - creates a JSObject with a custom NativeBrand (class name).
+ (createRenameMap):
+ - parse @optional properties of a JSExport protocol.
+ (putNonEnumerable):
+ - property put with enumerable=false.
+ (copyMethodsToObject):
+ - iterate methods in a protocol; add functions to a JSObject.
+ (parsePropertyAttributes):
+ - examine protocol property metadata.
+ (makeSetterName):
+ - "foo" -> "setFoo"
+ (copyPrototypeProperties):
+ - create properties on a Protocol object reflecting the instance methods & properties of a protocol.
+ (-[JSObjCClassInfo initWithContext:forClass:superClassInfo:]):
+ (-[JSObjCClassInfo dealloc]):
+ (-[JSObjCClassInfo wrapperForObject:]):
+ (-[JSObjCClassInfo constructor]):
+ - cache the Protocol/Constructor objects for an Objective-C type.
+ (-[JSWrapperMap initWithContext:]):
+ (-[JSWrapperMap dealloc]):
+ - constructor & desctructor.
+ (-[JSWrapperMap classInfoForClass:]):
+ - maps Class -> JSObjCClassInfo.
+ (-[JSWrapperMap wrapperForObject:]):
+ - cretae or retrieve a cached wrapper value for an object.
+ (tryUnwrapObjcObject):
+ - check whether a value is a wrapper object; unwrap if so.
+ * API/JavaScriptCore.h:
+ - Added includes for new API headers.
+ * API/ObjCCallbackFunction.h: Added.
+ - this class is used to wrap Objective-C instance methods, class methods & blocks as JSFunction objects.
+ * API/ObjCCallbackFunction.mm: Added.
+ (CallbackArgument):
+ (CallbackArgument::~CallbackArgument):
+ (CallbackArgumentBoolean):
+ (CallbackArgumentBoolean::set):
+ (CallbackArgumentInteger):
+ (CallbackArgumentInteger::set):
+ (CallbackArgumentDouble):
+ (CallbackArgumentDouble::set):
+ (CallbackArgumentJSValue):
+ (CallbackArgumentJSValue::set):
+ (CallbackArgumentId):
+ (CallbackArgumentId::set):
+ (CallbackArgumentOfClass):
+ (CallbackArgumentOfClass::CallbackArgumentOfClass):
+ (CallbackArgumentOfClass::~CallbackArgumentOfClass):
+ (CallbackArgumentOfClass::set):
+ (CallbackArgumentNSNumber):
+ (CallbackArgumentNSNumber::set):
+ (CallbackArgumentNSString):
+ (CallbackArgumentNSString::set):
+ (CallbackArgumentNSDate):
+ (CallbackArgumentNSDate::set):
+ (CallbackArgumentNSArray):
+ (CallbackArgumentNSArray::set):
+ (CallbackArgumentNSDictionary):
+ (CallbackArgumentNSDictionary::set):
+ (CallbackArgumentStruct):
+ (CallbackArgumentStruct::CallbackArgumentStruct):
+ (CallbackArgumentStruct::~CallbackArgumentStruct):
+ (CallbackArgumentStruct::set):
+ (CallbackArgumentBlockCallback):
+ (CallbackArgumentBlockCallback::CallbackArgumentBlockCallback):
+ (CallbackArgumentBlockCallback::~CallbackArgumentBlockCallback):
+ (CallbackArgumentBlockCallback::set):
+ - decoded arguent type information of a ObjCCallbackFunction.
+ (ArgumentTypeDelegate):
+ (ArgumentTypeDelegate::typeInteger):
+ (ArgumentTypeDelegate::typeDouble):
+ (ArgumentTypeDelegate::typeBool):
+ (ArgumentTypeDelegate::typeVoid):
+ (ArgumentTypeDelegate::typeId):
+ (ArgumentTypeDelegate::typeOfClass):
+ (ArgumentTypeDelegate::typeBlock):
+ (ArgumentTypeDelegate::typeStruct):
+ - delegate for use in conjunction with parseObjCType.
+ (CallbackResult):
+ (CallbackResult::~CallbackResult):
+ (CallbackResultVoid):
+ (CallbackResultVoid::get):
+ (CallbackResultId):
+ (CallbackResultId::get):
+ (CallbackResultNumeric):
+ (CallbackResultNumeric::get):
+ (CallbackResultBoolean):
+ (CallbackResultBoolean::get):
+ (CallbackResultStruct):
+ (CallbackResultStruct::CallbackResultStruct):
+ (CallbackResultStruct::~CallbackResultStruct):
+ (CallbackResultStruct::get):
+ - decoded result type information of a ObjCCallbackFunction.
+ (ResultTypeDelegate):
+ (ResultTypeDelegate::typeInteger):
+ (ResultTypeDelegate::typeDouble):
+ (ResultTypeDelegate::typeBool):
+ (ResultTypeDelegate::typeVoid):
+ (ResultTypeDelegate::typeId):
+ (ResultTypeDelegate::typeOfClass):
+ (ResultTypeDelegate::typeBlock):
+ (ResultTypeDelegate::typeStruct):
+ - delegate for use in conjunction with parseObjCType.
+ (ObjCCallbackFunction):
+ (ObjCCallbackFunction::ObjCCallbackFunction):
+ (ObjCCallbackFunction::~ObjCCallbackFunction):
+ - constructor & destructor.
+ (ObjCCallbackFunction::context):
+ - accessor.
+ (ObjCCallbackFunction::wrappedBlock):
+ - attemmpt to unwrap a block object.
+ (objCCallbackFunctionFinalize):
+ (objCCallbackFunctionCallAsFunction):
+ (objCCallbackFunctionClass):
+ - JSClassRef used to represent ObjCCallbackFunction objects.
+ (ObjCCallbackFunction::call):
+ (blockSignatureContainsClass):
+ - helper function to determine if we're running on a recent Clang.
+ (skipNumber):
+ - helper used in parsing signature strings.
+ (objCCallbackFunctionForInvocation):
+ (objCCallbackFunctionForMethod):
+ (objCCallbackFunctionForBlock):
+ - functions to try to create ObjCCallbackFunction instances for methods/blocks.
+ (tryUnwrapBlock):
+ - attemmpt to unwrap a block object.
+ * API/ObjcRuntimeExtras.h: Added.
+ (protocolImplementsProtocol):
+ (forEachProtocolImplementingProtocol):
+ (forEachMethodInClass):
+ (forEachMethodInProtocol):
+ (forEachPropertyInProtocol):
+ - functions used in reflecting on Objective-C types.
+ (skipPair):
+ - parsing helper used by parseObjCType, scans for matching parentheses.
+ (StringRange):
+ (StringRange::StringRange):
+ (StringRange::~StringRange):
+ (StringRange::operator const char*):
+ (StringRange::get):
+ - Helper class - create a c string copy of a range of an existing string.
+ (parseObjCType):
+ - function to parse Objective-C type strings, makes callbacks to a deleagte.
+ * API/tests/testapi.c:
+ (main):
+ - added call to testObjectiveCAPI (in testapi.m).
+ * API/tests/testapi.m: Added.
+ (+[ParentObject parentTest]):
+ (+[TestObject testObject]):
+ (+[TestObject classTest]):
+ (-[TestObject getString]):
+ (-[TestObject testArgumentTypesWithInt:double:boolean:string:number:array:dictionary:]):
+ (-[TestObject callback:]):
+ (-[TextXYZ test:]):
+ - test object, used in various test vases.
+ (checkResult):
+ - helper function.
+ (blockSignatureContainsClass):
+ - helper function to determine if we're running on a recent Clang.
+ (testObjectiveCAPI):
+ - new test cases.
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ - added new files.
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ - added m_apiData - provide convenient storage for use by the API.
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ - added m_apiData - provide convenient storage for use by the API.
+
+2012-12-27 Csaba Osztrogonác <ossy@webkit.org>
+
+ One more unreviwed holiday MIPS and SH4 buildfixes after r138516.
+
+ * jit/ThunkGenerators.cpp:
+
+2012-12-27 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviwed holiday ARM and SH4 buildfixes after r138516.
+
+ * jit/ThunkGenerators.cpp:
+ (JSC::nativeForGenerator):
+
+2012-12-26 Filip Pizlo <fpizlo@apple.com>
+
+ All JIT stubs should go through the getCTIStub API
+ https://bugs.webkit.org/show_bug.cgi?id=105750
+
+ Reviewed by Sam Weinig.
+
+ Previously JITThunks had two sets of thunks: one static set stored in a struct,
+ which was filled by JIT::privateCompileCTITrampolines, and another set stored in
+ a HashMap. Moreover, the code to generate the code for the CTI trampoline struct
+ had loads of copy-paste between JSVALUE32_64 and JSVALUE64, and was total
+ unmodular with respect to calls versus constructors, among other things.
+
+ This changeset removes this struct and rationalizes the code that generates those
+ thunks. All of thunks are now generated through the getCTIStub HashMap API. All
+ thunks for the baseline JIT now use the JSInterfaceJIT and have their codegen
+ located in ThunkGenerators.cpp. All thunks now share as much code as possible -
+ it turns out that they are almost 100% identical between 32_64 and 64, so that
+ works out great. A bunch of call vs. construct duplication was eliminated. And,
+ most of the call link versus virtual call duplication was also eliminated.
+
+ This does not change behavior but it does make it easier to add more thunks in
+ the future.
+
+ * bytecode/CallLinkInfo.cpp:
+ (JSC::CallLinkInfo::unlink):
+ * jit/JIT.cpp:
+ (JSC::JIT::linkFor):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlines.h:
+ (JSC):
+ * jit/JITOpcodes.cpp:
+ (JSC):
+ (JSC::JIT::privateCompileCTINativeCall):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC):
+ * jit/JITStubs.cpp:
+ (JSC::tryCacheGetByID):
+ * jit/JITThunks.cpp:
+ (JSC::JITThunks::JITThunks):
+ (JSC::JITThunks::ctiNativeCall):
+ (JSC::JITThunks::ctiNativeConstruct):
+ (JSC):
+ (JSC::JITThunks::hostFunctionStub):
+ * jit/JITThunks.h:
+ (JSC):
+ (JITThunks):
+ * jit/JSInterfaceJIT.h:
+ (JSInterfaceJIT):
+ (JSC::JSInterfaceJIT::emitJumpIfNotJSCell):
+ (JSC):
+ (JSC::JSInterfaceJIT::emitFastArithIntToImmNoCheck):
+ (JSC::JSInterfaceJIT::emitJumpIfNotType):
+ (JSC::JSInterfaceJIT::emitGetFromCallFrameHeaderPtr):
+ (JSC::JSInterfaceJIT::emitPutToCallFrameHeader):
+ (JSC::JSInterfaceJIT::emitPutImmediateToCallFrameHeader):
+ (JSC::JSInterfaceJIT::emitPutCellToCallFrameHeader):
+ (JSC::JSInterfaceJIT::preserveReturnAddressAfterCall):
+ (JSC::JSInterfaceJIT::restoreReturnAddressBeforeReturn):
+ (JSC::JSInterfaceJIT::restoreArgumentReference):
+ * jit/ThunkGenerators.cpp:
+ (JSC::generateSlowCaseFor):
+ (JSC):
+ (JSC::linkForGenerator):
+ (JSC::linkCallGenerator):
+ (JSC::linkConstructGenerator):
+ (JSC::virtualForGenerator):
+ (JSC::virtualCallGenerator):
+ (JSC::virtualConstructGenerator):
+ (JSC::stringLengthTrampolineGenerator):
+ (JSC::nativeForGenerator):
+ (JSC::nativeCallGenerator):
+ (JSC::nativeConstructGenerator):
+ (JSC::charCodeAtThunkGenerator):
+ (JSC::charAtThunkGenerator):
+ (JSC::fromCharCodeThunkGenerator):
+ (JSC::sqrtThunkGenerator):
+ (JSC::floorThunkGenerator):
+ (JSC::ceilThunkGenerator):
+ (JSC::roundThunkGenerator):
+ (JSC::expThunkGenerator):
+ (JSC::logThunkGenerator):
+ (JSC::absThunkGenerator):
+ (JSC::powThunkGenerator):
+ * jit/ThunkGenerators.h:
+ (JSC):
+ * runtime/Executable.h:
+ (NativeExecutable):
+ (JSC::NativeExecutable::nativeFunctionFor):
+ (JSC::NativeExecutable::offsetOfNativeFunctionFor):
+
+2012-12-25 Gyuyoung Kim <gyuyoung.kim@samsung.com>
+
+ [CMAKE] Remove header files in JavaScriptCore/CMakeLists.txt
+ https://bugs.webkit.org/show_bug.cgi?id=105753
+
+ Reviewed by Laszlo Gombos.
+
+ * CMakeLists.txt: Remove header files in source list.
+
+2012-12-25 Filip Pizlo <fpizlo@apple.com>
+
+ JITThunks should be in its own file
+ https://bugs.webkit.org/show_bug.cgi?id=105744
+
+ Rubber stamped by Sam Weinig.
+
+ Moved JITThunks into its own file and removed some static methods from it
+ that were not related to what JITThunks currently does. Performed various
+ pagan rituals to get it to build - apparently there is a circular dependency
+ between JSCell, Weak, and JITThunks, which magically resolves itself if you
+ make sure to first include Register.h. Making it so that fewer pagan rituals
+ need to be performed if this code changes in the future is covered by
+ https://bugs.webkit.org/show_bug.cgi?id=105696.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * jit/JITStubs.cpp:
+ (JSC::tryCachePutByID):
+ (JSC::tryCacheGetByID):
+ * jit/JITStubs.h:
+ (JSC::JITStackFrame::returnAddressSlot):
+ (JSC::returnAddressIsInCtiTrampoline):
+ * jit/JITThunks.cpp: Added.
+ (JSC::JITThunks::JITThunks):
+ (JSC::JITThunks::~JITThunks):
+ (JSC::JITThunks::ctiStub):
+ (JSC::JITThunks::hostFunctionStub):
+ (JSC::JITThunks::clearHostFunctionStubs):
+ * jit/JITThunks.h: Added.
+ (JSC::JITThunks::ctiStringLengthTrampoline):
+ (JSC::JITThunks::ctiVirtualCallLink):
+ (JSC::JITThunks::ctiVirtualConstructLink):
+ (JSC::JITThunks::ctiVirtualCall):
+ (JSC::JITThunks::ctiVirtualConstruct):
+ (JSC::JITThunks::ctiNativeCall):
+ (JSC::JITThunks::ctiNativeConstruct):
+ * jit/ThunkGenerator.h: Added.
+ * jit/ThunkGenerators.cpp:
+ * jit/ThunkGenerators.h:
+ * runtime/JSGlobalData.h:
+
+2012-12-25 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Unreviewed follow-up for r138455.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-12-24 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Unreviewed compilation fix for r138452.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-12-24 Laszlo Gombos <l.gombos@samsung.com>
+
+ Remove wtf/Platform.h includes from {c|cpp} files
+ https://bugs.webkit.org/show_bug.cgi?id=105678
+
+ Reviewed by Kentaro Hara.
+
+ Remove wtf/Platform.h from the include list as it is already
+ included in config.h.
+
+ * disassembler/udis86/udis86.c:
+ * disassembler/udis86/udis86_decode.c:
+ * disassembler/udis86/udis86_input.c:
+ * disassembler/udis86/udis86_itab_holder.c:
+ * disassembler/udis86/udis86_syn-att.c:
+ * disassembler/udis86/udis86_syn-intel.c:
+ * disassembler/udis86/udis86_syn.c:
+ * heap/VTableSpectrum.cpp:
+
+2012-12-21 Filip Pizlo <fpizlo@apple.com>
+
+ DFG Arrayify slow path should be out-of-line
+ https://bugs.webkit.org/show_bug.cgi?id=105400
+
+ Reviewed by Gavin Barraclough.
+
+ The interesting bit of this change is allowing out-of-line slow path generators
+ to emit speculation checks. This is accomplished by having a version of
+ speculationCheck() that returns a jump placeholder instead of taking a jump (or
+ jump list) as an argument. You can then fill in that jump placeholder at a
+ later time, so long as you do it before OSR exit linking. Slow path generators
+ run before linking, so that just naturally ends up working.
+
+ This isn't really a big win, but we know that out-of-lining slow paths is
+ generally a good thing to do, so it's fair to assume that this is a move in the
+ right direction.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * dfg/DFGArrayifySlowPathGenerator.h: Added.
+ (DFG):
+ (ArrayifySlowPathGenerator):
+ (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator):
+ (JSC::DFG::ArrayifySlowPathGenerator::generateInternal):
+ * dfg/DFGOSRExitJumpPlaceholder.cpp: Added.
+ (DFG):
+ (JSC::DFG::OSRExitJumpPlaceholder::fill):
+ * dfg/DFGOSRExitJumpPlaceholder.h: Added.
+ (DFG):
+ (OSRExitJumpPlaceholder):
+ (JSC::DFG::OSRExitJumpPlaceholder::OSRExitJumpPlaceholder):
+ (JSC::DFG::OSRExitJumpPlaceholder::operator!):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2012-12-20 Oliver Hunt <oliver@apple.com>
+
+ Finally found the problem. Using the wrong JSContextGroup.
+
+ * API/tests/testapi.c:
+ (main):
+
+2012-12-20 Oliver Hunt <oliver@apple.com>
+
+ Try to convince bots to be happy with testapi.
+
+ * API/JSScriptRefPrivate.h:
+
+2012-12-20 Michael Saboff <msaboff@apple.com>
+
+ JIT: Change uninitialized pointer value -1 to constant
+ https://bugs.webkit.org/show_bug.cgi?id=105576
+
+ Rubber stamped by Gavin Barraclough.
+
+ Changed the use of -1 as a pointer value in the JITs to be the constant unusedPointer defined in the
+ new file jit/UnusedPointer.h. Made it's value 0xd1e7beef, which is a bad pointer on most architectures
+ because it is odd, and to distinguish it from other common values.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::dfgResetGetByID):
+ (JSC::DFG::dfgResetPutByID):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::cachedGetById):
+ (JSC::DFG::SpeculativeJIT::cachedPutById):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::cachedGetById):
+ (JSC::DFG::SpeculativeJIT::cachedPutById):
+ * jit/JIT.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::resetPatchGetById):
+ (JSC::JIT::resetPatchPutById):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::resetPatchGetById):
+ (JSC::JIT::resetPatchPutById):
+ * jit/JITWriteBarrier.h:
+ (JSC::JITWriteBarrierBase::clearToUnusedPointer):
+ (JSC::JITWriteBarrierBase::get):
+ * jit/UnusedPointer.h: Added.
+
+2012-12-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG shouldn't emit CheckStructure on array accesses if exit profiling tells it not to
+ https://bugs.webkit.org/show_bug.cgi?id=105577
+
+ Reviewed by Mark Hahnenberg.
+
+ I don't know why this wasn't there from the beginning.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
+
+2012-12-19 Filip Pizlo <fpizlo@apple.com>
+
+ DFG speculation checks that take JumpList should consolidate OSRExits
+ https://bugs.webkit.org/show_bug.cgi?id=105401
+
+ Reviewed by Oliver Hunt.
+
+ Change OSRExitCompilationInfo to always contain a JumpList, and change JumpList
+ to be more compact. This way, a speculationCheck that takes a JumpList only has
+ to emit one OSRExit structure, and one OSRExit landing pad.
+
+ The downside is that we get less precise information about *where* we exited
+ from. So, this also includes changes to the profiler to be more relaxed about
+ what an ExitSite is.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JumpList):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::linkOSRExits):
+ (JSC::DFG::JITCompiler::link):
+ * dfg/DFGJITCompiler.h:
+ (DFG):
+ (JSC::DFG::JITCompiler::appendExitInfo):
+ (JITCompiler):
+ * dfg/DFGOSRExitCompilationInfo.h:
+ (OSRExitCompilationInfo):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ * profiler/ProfilerCompilation.cpp:
+ (JSC::Profiler::Compilation::addOSRExitSite):
+ * profiler/ProfilerCompilation.h:
+ (Compilation):
+ * profiler/ProfilerOSRExitSite.cpp:
+ (JSC::Profiler::OSRExitSite::toJS):
+ * profiler/ProfilerOSRExitSite.h:
+ (JSC::Profiler::OSRExitSite::OSRExitSite):
+ (JSC::Profiler::OSRExitSite::codeAddress):
+ (OSRExitSite):
+
+2012-12-19 Oliver Hunt <oliver@apple.com>
+
+ Fix some incorrect tests in testapi.c
+
+ Reviewed by Simon Fraser.
+
+ * API/tests/testapi.c:
+ (main):
+
+2012-12-19 Filip Pizlo <fpizlo@apple.com>
+
+ JSObject::ensure<IndexingType> should gracefully handle InterceptsGetOwn..., and should never be called when the 'this' is not an object
+ https://bugs.webkit.org/show_bug.cgi?id=105468
+
+ Reviewed by Mark Hahnenberg, Oliver Hunt, and Gavin Barraclough.
+
+ Changed JSObject::ensure<IndexingType> methods to gracefully handle
+ InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero. Most of them handle it by returning
+ null as a result of indexingShouldBeSparse() returning true, while ensureArrayStorage handles it
+ by entering dictionary indexing mode, which forces the object to behave correctly even if there
+ is proxying or weird prototype stuff going on.
+
+ Changed DFGOperations entrypoints to reject non-objects, so that JSObject doesn't have to deal
+ with pretending to be JSString. In particular, this would go wrong in the ArrayStorage case
+ since we'd try to resize a butterfly on a JSString, but JSString has something other than
+ m_butterfly at that offset.
+
+ Finally, removed all InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero from JIT code
+ since those are now redundant.
+
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::enterDictionaryIndexingMode):
+ (JSC::JSObject::ensureInt32Slow):
+ (JSC::JSObject::ensureDoubleSlow):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::ensureArrayStorageSlow):
+ (JSC):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ * runtime/JSObject.h:
+ (JSObject):
+
+2012-12-19 Oliver Hunt <oliver@apple.com>
+
+ Tidy up JSScriptRef API
+ https://bugs.webkit.org/show_bug.cgi?id=105470
+
+ Reviewed by Anders Carlsson.
+
+ People found the API's use of a context confusing, so we'll switch to a JSContextGroup based
+ API, and drop a number of the unnecessary uses of contexts.
+
+ * API/JSScriptRef.cpp:
+ (OpaqueJSScript::globalData):
+ (parseScript):
+ * API/JSScriptRefPrivate.h:
+ * API/tests/testapi.c:
+ (main):
+
+2012-12-19 Alexis Menard <alexis@webkit.org>
+
+ Implement CSS parsing for CSS transitions unprefixed.
+ https://bugs.webkit.org/show_bug.cgi?id=104804
+
+ Reviewed by Dean Jackson.
+
+ Add a new flag ENABLE_CSS_TRANSFORMS_ANIMATIONS_TRANSITIONS_UNPREFIXED
+ to cover the work of unprefixing Transforms, Animations and
+ Transitions. It will let the possibility of each ports to turn it off
+ in their release branches until we're confident that these CSS
+ properties are ready to be unprefixed.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-12-18 Filip Pizlo <fpizlo@apple.com>
+
+ Proxies should set InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero
+ https://bugs.webkit.org/show_bug.cgi?id=105379
+
+ Reviewed by Gavin Barraclough.
+
+ Forgetting to set this flag led to the DFG trying to ensure array storage on a proxy. I've
+ now hardened the code with a release assertion as well as fixing the bug. A release assertion
+ is appropriate here since this is slow-path code.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::enterDictionaryIndexingMode):
+ (JSC::JSObject::ensureInt32Slow):
+ (JSC::JSObject::ensureDoubleSlow):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::ensureArrayStorageSlowNoCheck):
+ (JSC::JSObject::ensureArrayStorageSlow):
+ (JSC):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ * runtime/JSObject.h:
+ (JSObject):
+ * runtime/JSProxy.h:
+ (JSProxy):
+
+2012-12-18 Oliver Hunt <oliver@apple.com>
+
+ Add a JSScriptRef API to JSC so that we can allow API users to avoid the full cost of reparsing everytime the execute a script.
+ https://bugs.webkit.org/show_bug.cgi?id=105340
+
+ Reviewed by Gavin Barraclough.
+
+ This patch adds a (currently private) API to allow users of the JSC API to create a JSScript object
+ that references a reusable version of the script that they wish to evaluate. This can help us avoid
+ numeorus copies that are otherwise induced by our existing API and gives us an opaque object that we
+ can hang various caches off. Currently this is simply a simple SourceProvider, but in future we may
+ be able to add more caching without requiring new/replacement APIs.
+
+ * API/JSScriptRef.cpp: Added.
+ * API/JSScriptRefPrivate.h: Added.
+ * API/tests/testapi.c:
+ Add tests for new APIs.
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2012-12-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode incorrectly checks for non-array array storage when it should be checking for array array storage
+ https://bugs.webkit.org/show_bug.cgi?id=105365
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+
+2012-12-18 Filip Pizlo <fpizlo@apple.com>
+
+ SunSpider/date-format-tofte shouldn't compile each of the tiny worthless eval's only to OSR exit in the prologue every time
+ https://bugs.webkit.org/show_bug.cgi?id=105335
+
+ Reviewed by Geoffrey Garen.
+
+ The first thing I did was restructure the logic of canInlineResolveOperations(),
+ because I didn't understand it. This was relevant because the OSR exits are
+ caused by a resolve that the DFG cannot handle.
+
+ I was then going to make it so that we didn't compile the resolve at all, but
+ realized that this would not be the best fix: it didn't seem sensible to me to
+ be optimizing these evals after only 60 invocations. Evals should have a higher
+ threshold, since they often contain code for which the baseline JIT does a
+ pretty good job already (if all you've got is a single heap access or a single
+ hard-to-inline call, then the baseline JIT has got you covered), and typically
+ if we see one eval code block we expect to see more (from the same eval site):
+ so our typical low threshold could lead to a *lot* of compilation. As such, the
+ main effect of this patch is to introduce an evalThresholdMultiplier, which is
+ now set to 10.
+
+ This is a ~5% speed-up on data-format-tofte. No regressions anywhere as far as
+ I can see.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::codeTypeThresholdMultiplier):
+ (JSC):
+ (JSC::CodeBlock::optimizationThresholdScalingFactor):
+ (JSC::CodeBlock::exitCountThresholdForReoptimization):
+ (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineResolveOperations):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * runtime/Options.h:
+ (JSC):
+
+2012-12-18 Filip Pizlo <fpizlo@apple.com>
+
+ Convert indexingTypeToString to IndexingTypeDump
+ https://bugs.webkit.org/show_bug.cgi?id=105351
+
+ Reviewed by Mark Hahnenberg.
+
+ This gets rid of another case of static char buffer[thingy].
+
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * runtime/IndexingType.cpp:
+ (JSC::dumpIndexingType):
+ * runtime/IndexingType.h:
+ (JSC):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::dump):
+
+2012-12-18 Beth Dakin <bdakin@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=102579
+ [mac] Enable scaled cursors
+
+ Reviewed by Dean Jackson.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-12-18 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Restrictions on oversize CopiedBlock allocations should be relaxed
+ https://bugs.webkit.org/show_bug.cgi?id=105339
+
+ Reviewed by Filip Pizlo.
+
+ Currently the DFG has a single branch in the inline allocation path for property/array storage where
+ it checks to see if the number of bytes requested will fit in the current block. This does not match
+ what the C++ allocation path does; it checks if the requested number of bytes is oversize, and then
+ if it's not, it tries to fit it in the current block. The garbage collector assumes that ALL allocations
+ that are greater than 16KB are in oversize blocks. Therefore, this mismatch can lead to crashes when
+ the collector tries to perform some operation on a CopiedBlock.
+
+ To avoid adding an extra branch to the inline allocation path in the JIT, we should make it so that
+ oversize blocks are allocated on the same alignment boundaries so that there is a single mask to find
+ the block header of any CopiedBlock (rather than two, one for normal and one for oversize blocks), and
+ we should figure out if a block is oversize by some other method than just whatever the JSObject says
+ it is. One way we could record this info Region of the block, since we allocate a one-off Region for
+ oversize blocks.
+
+ * heap/BlockAllocator.h:
+ (JSC::Region::isCustomSize):
+ (Region):
+ (JSC::Region::createCustomSize):
+ (JSC::Region::Region):
+ (JSC::BlockAllocator::deallocateCustomSize):
+ * heap/CopiedBlock.h:
+ (CopiedBlock):
+ (JSC::CopiedBlock::isOversize):
+ (JSC):
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::tryAllocateOversize):
+ (JSC::CopiedSpace::tryReallocate):
+ (JSC::CopiedSpace::tryReallocateOversize):
+ * heap/CopiedSpace.h:
+ (CopiedSpace):
+ * heap/CopiedSpaceInlines.h:
+ (JSC::CopiedSpace::contains):
+ (JSC::CopiedSpace::tryAllocate):
+ (JSC):
+ * heap/CopyVisitor.h:
+ (CopyVisitor):
+ * heap/CopyVisitorInlines.h:
+ (JSC::CopyVisitor::checkIfShouldCopy):
+ (JSC::CopyVisitor::didCopy):
+ * heap/SlotVisitorInlines.h:
+ (JSC::SlotVisitor::copyLater):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly):
+
+2012-12-18 Joseph Pecoraro <pecoraro@apple.com>
+
+ [Mac] Add Build Phase to Check Headers for Inappropriate Macros (Platform.h macros)
+ https://bugs.webkit.org/show_bug.cgi?id=104279
+
+ Reviewed by David Kilzer.
+
+ Add a build phase to check the public JavaScriptCore headers for
+ inappropriate macros.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2012-12-18 Michael Saboff <msaboff@apple.com>
+
+ [Qt] Fix the ARMv7 build after r137976
+ https://bugs.webkit.org/show_bug.cgi?id=105270
+
+ Reviewed by Csaba Osztrogonác.
+
+ Add default value for Jump parameter to fix build.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Jump::Jump):
+
+2012-12-17 Geoffrey Garen <ggaren@apple.com>
+
+ Constant fold !{number} in the parser
+ https://bugs.webkit.org/show_bug.cgi?id=105232
+
+ Reviewed by Filip Pizlo.
+
+ Typically, we wait for hot execution and constant fold in the DFG.
+ However, !0 and !1 are common enough in minifiers that it can be good
+ to get them out of the way early, for faster/smaller parsing and startup.
+
+ * parser/ASTBuilder.h:
+ (JSC::ASTBuilder::createLogicalNot): !{literal} is super simple, especially
+ since there's no literal form of NaN or Inf.
+
+2012-12-17 Filip Pizlo <fpizlo@apple.com>
+
+ DFG is too aggressive eliding overflow checks for additions involving large constants
+ https://bugs.webkit.org/show_bug.cgi?id=105239
+
+ Reviewed by Gavin Barraclough.
+
+ If we elide overflow checks on an addition (or subtraction) involving a larger-than-2^32 immediate,
+ then make sure that the non-constant child of the addition knows that he's got to do an overflow
+ check, by flowing the UsedAsNumber property at him.
+
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::addSpeculationMode):
+ (Graph):
+ (JSC::DFG::Graph::addShouldSpeculateInteger):
+ (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
+2012-12-17 Michael Saboff <msaboff@apple.com>
+
+ DFG: Refactor DFGCorrectableJumpPoint to reduce size of OSRExit data
+ https://bugs.webkit.org/show_bug.cgi?id=105237
+
+ Reviewed by Filip Pizlo.
+
+ Replaced DFGCorrectableJumpPoint with OSRExitCompilationInfo which is used and kept alive only while we are
+ compiling in the DFG. Moved the patchable branch offset directly into OSRExit.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/AbstractMacroAssembler.h:
+ * dfg/DFGCorrectableJumpPoint.cpp: Removed.
+ * dfg/DFGCorrectableJumpPoint.h: Removed.
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::linkOSRExits):
+ (JSC::DFG::JITCompiler::link):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::appendExitJump):
+ (JITCompiler):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ (JSC::DFG::OSRExit::setPatchableCodeOffset):
+ (JSC::DFG::OSRExit::getPatchableCodeOffsetAsJump):
+ (JSC::DFG::OSRExit::codeLocationForRepatch):
+ (JSC::DFG::OSRExit::correctJump):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ * dfg/DFGOSRExitCompilationInfo.h: Added.
+ (OSRExitCompilationInfo):
+ (JSC::DFG::OSRExitCompilationInfo::OSRExitCompilationInfo):
+ (JSC::DFG::OSRExitCompilationInfo::failureJump):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+
+2012-12-17 Filip Pizlo <fpizlo@apple.com>
+
+ DFG is too aggressive with eliding overflow checks in loops
+ https://bugs.webkit.org/show_bug.cgi?id=105226
+
+ Reviewed by Mark Hahnenberg and Oliver Hunt.
+
+ If we see a variable's live range cross basic block boundaries, conservatively assume that it may
+ be part of a data-flow back-edge, and as a result, we may have entirely integer operations that
+ could lead to the creation of an integer that is out of range of 2^52 (the significand of a double
+ float). This does not seem to regress any of the benchmarks we care about, and it fixes the bug.
+
+ In future we may want to actually look at whether or not there was a data-flow back-edge instead
+ of being super conservative about it. But we have no evidence, yet, that this would help us on
+ real code.
+
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
+2012-12-17 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Butterfly::growArrayRight shouldn't be called on null Butterfly objects
+ https://bugs.webkit.org/show_bug.cgi?id=105221
+
+ Reviewed by Filip Pizlo.
+
+ Currently we depend upon the fact that Butterfly::growArrayRight works with null Butterfly
+ objects purely by coincidence. We should add a new static function that null checks the old
+ Butterfly object and creates a new one if it's null, or calls growArrayRight if it isn't for
+ use in the couple of places in JSObject that expect such behavior to work.
+
+ * runtime/Butterfly.h:
+ (Butterfly):
+ * runtime/ButterflyInlines.h:
+ (JSC::Butterfly::createOrGrowArrayRight):
+ (JSC):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::createInitialIndexedStorage):
+ (JSC::JSObject::createArrayStorage):
+
+2012-12-17 Filip Pizlo <fpizlo@apple.com>
+
+ javascript integer overflow
+ https://bugs.webkit.org/show_bug.cgi?id=104967
+
+ Reviewed by Mark Hahnenberg.
+
+ Fix PutScopedVar backward flow.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
+2012-12-16 Filip Pizlo <fpizlo@apple.com>
+
+ Rationalize array profiling for out-of-bounds and hole cases
+ https://bugs.webkit.org/show_bug.cgi?id=105139
+
+ Reviewed by Geoffrey Garen.
+
+ This makes ArrayProfile track whether or not we had out-of-bounds, which allows
+ for more precise decision-making in the DFG.
+
+ Also cleaned up ExitKinds for out-of-bounds and hole cases to make it easier to
+ look at them in the profiler.
+
+ Slight speed-up (5-8%) on SunSpider/crypto-md5.
+
+ * bytecode/ArrayProfile.cpp:
+ (JSC::ArrayProfile::computeUpdatedPrediction):
+ (JSC::ArrayProfile::briefDescription):
+ * bytecode/ArrayProfile.h:
+ (JSC::ArrayProfile::ArrayProfile):
+ (JSC::ArrayProfile::addressOfOutOfBounds):
+ (JSC::ArrayProfile::expectedStructure):
+ (JSC::ArrayProfile::structureIsPolymorphic):
+ (JSC::ArrayProfile::outOfBounds):
+ (JSC::ArrayProfile::polymorphicStructure):
+ * bytecode/CodeBlock.cpp:
+ (JSC::dumpChain):
+ * bytecode/ExitKind.cpp:
+ (JSC::exitKindToString):
+ (JSC::exitKindIsCountable):
+ * bytecode/ExitKind.h:
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JIT.h:
+ * jit/JITInlines.h:
+ (JSC::JIT::emitArrayProfileOutOfBoundsSpecialCase):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emitSlow_op_put_by_val):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emitSlow_op_put_by_val):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2012-12-17 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ Implement add64 for MIPS assembler after r136601
+ https://bugs.webkit.org/show_bug.cgi?id=104106
+
+ Reviewed by Zoltan Herczeg.
+
+ Added add64 function to MacroAssebler of MIPS.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::add32):
+ (JSC::MacroAssemblerMIPS::add64):
+ (MacroAssemblerMIPS):
+
+2012-12-17 Jonathan Liu <net147@gmail.com>
+
+ Fix Math.pow implementation with MinGW-w64
+ https://bugs.webkit.org/show_bug.cgi?id=105087
+
+ Reviewed by Simon Hausmann.
+
+ The MinGW-w64 runtime has different behaviour for pow()
+ compared to other C runtimes. This results in the following
+ test262 tests failing with the latest MinGW-w64 runtime:
+ - S15.8.2.13_A14
+ - S15.8.2.13_A16
+ - S15.8.2.13_A20
+ - S15.8.2.13_A22
+
+ Handle the special cases that are different with MinGW-w64.
+
+ * runtime/MathObject.cpp:
+ (JSC::mathPow):
+
+2012-12-16 Filip Pizlo <fpizlo@apple.com>
+
+ Bytecode dumping should show rare case profiles
+ https://bugs.webkit.org/show_bug.cgi?id=105133
+
+ Reviewed by Geoffrey Garen.
+
+ Refactored the dumper to call dumpBytecodeCommandAndNewLine in just one place,
+ rather than in all of the places. Changed the rare case profile getters to use
+ tryBinarySearch rather than binarySearch, so that they can be used speculatively
+ even if you don't know that the bytecode has rare case profiles. This actually
+ increases our assertion level, since it means that in release builds we will get
+ null and crash rather than getting some random adjacent profile. And then this
+ adds some printing of the rare case profiles.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printUnaryOp):
+ (JSC::CodeBlock::printBinaryOp):
+ (JSC::CodeBlock::printConditionalJump):
+ (JSC::CodeBlock::printCallOp):
+ (JSC::CodeBlock::printPutByIdOp):
+ (JSC::CodeBlock::beginDumpProfiling):
+ (JSC):
+ (JSC::CodeBlock::dumpValueProfiling):
+ (JSC::CodeBlock::dumpArrayProfiling):
+ (JSC::CodeBlock::dumpRareCaseProfile):
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::rareCaseProfileForBytecodeOffset):
+ (JSC::CodeBlock::specialFastCaseProfileForBytecodeOffset):
+
+2012-12-13 Filip Pizlo <fpizlo@apple.com>
+
+ Attempt to rationalize and simplify WTF::binarySearch
+ https://bugs.webkit.org/show_bug.cgi?id=104890
+
+ Reviewed by Maciej Stachowiak.
+
+ Switch to using the new binarySearch() API. No change in behavior.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::bytecodeOffset):
+ (JSC::CodeBlock::codeOriginForReturn):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::getStubInfo):
+ (JSC::CodeBlock::getByValInfo):
+ (JSC::CodeBlock::getCallLinkInfo):
+ (JSC::CodeBlock::dfgOSREntryDataForBytecodeIndex):
+ (JSC::CodeBlock::valueProfileForBytecodeOffset):
+ (JSC::CodeBlock::rareCaseProfileForBytecodeOffset):
+ (JSC::CodeBlock::specialFastCaseProfileForBytecodeOffset):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::blockIndexForBytecodeOffset):
+ * dfg/DFGMinifiedGraph.h:
+ (JSC::DFG::MinifiedGraph::at):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * profiler/ProfilerBytecodeSequence.cpp:
+ (JSC::Profiler::BytecodeSequence::indexForBytecodeIndex):
+
+2012-12-13 Filip Pizlo <fpizlo@apple.com>
+
+ Don't assert that flags <= 0x3ff in JSTypeInfo
+ https://bugs.webkit.org/show_bug.cgi?id=104988
+
+ Reviewed by Sam Weinig.
+
+ This assertion doesn't accomplish anything other than crashes.
+
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::TypeInfo):
+
+2012-12-13 Filip Pizlo <fpizlo@apple.com>
+
+ Named lookups on HTML documents produce inconsistent results in JavaScriptCore bindings
+ https://bugs.webkit.org/show_bug.cgi?id=104623
+
+ Reviewed by Geoffrey Garen.
+
+ Add the notion of objects that HasImpureGetOwnPropertySlot, and use that to inhibit prototype chain caching
+ in some cases. This appears to be perf-neutral on benchmarks that we track.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDProtoList):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSTypeInfo.h:
+ (JSC):
+ (JSC::TypeInfo::hasImpureGetOwnPropertySlot):
+ * runtime/Operations.h:
+ (JSC::normalizePrototypeChainForChainAccess):
+
+2012-12-13 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, roll out http://trac.webkit.org/changeset/137683.
+ It broke gmail.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/Operations.cpp:
+ (JSC::jsTypeStringForValue):
+ (JSC):
+ * runtime/Operations.h:
+ (JSC):
+
+2012-13-11 Oliver Hunt <oliver@apple.com>
+
+ Support op_typeof in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=98898
+
+ Reviewed by Filip Pizlo.
+
+ Adds a TypeOf node to the DFG to support op_typeof.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ We try to determine the result early here, and substitute in a constant.
+ Otherwise we leave the node intact, and set the result type to SpecString.
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ Parse op_typeof
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ TypeOf nodes can be subjected to pure CSE
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ We can handle typeof.
+ * dfg/DFGNodeType.h:
+ (DFG):
+ Define the node.
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ Add operationTypeOf to support the non-trivial cases.
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ Actual codegen
+ * runtime/Operations.cpp:
+ (JSC::jsTypeStringForValue):
+ (JSC):
+ * runtime/Operations.h:
+ (JSC):
+ Some refactoring to allow us to get the type string for an
+ object without needing a callframe.
+
+2012-12-12 Filip Pizlo <fpizlo@apple.com>
+
+ OSR exit compiler should emit code for resetting the execution counter that matches the logic of ExecutionCounter.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=104791
+
+ Reviewed by Oliver Hunt.
+
+ The OSR exit compiler wants to make it so that every OSR exit does the equivalent
+ of:
+
+ codeBlock->m_jitExecuteCounter.setNewThreshold(
+ codeBlock->counterValueForOptimizeAfterLongWarmUp());
+
+ This logically involves:
+
+ - Resetting the counter to zero.
+ - Setting m_activeThreshold to counterValueForOptimizeAfterLongWarmUp().
+ - Figuring out the scaled threshold, subtracting the count so far (which is zero,
+ so this part is a no-op), and clipping (ExecuteCounter::clippedThreshold()).
+ - Setting m_counter to the negated clipped threshold.
+ - Setting m_totalCount to the previous count so far (which is zero) plus the
+ clipped threshold.
+
+ Because of the reset, which sets the count-so-far to zero, this amounts to:
+
+ - Setting m_activeThreshold to counterValueForOptimizeAfterLongWarmUp().
+ - Figuring out the clipped scaled threshold.
+ - Setting m_counter to the negated clipped scaled threshold.
+ - Setting m_totalCount to the (positive) clipped scaled threshold.
+
+ The code was previously not doing this, but now is. This is performance neutral.
+ The only change in behavior over what the code was previously doing (setting the
+ m_counter to the negated scaled threshold, without clipping, and then setting
+ the m_totalCount to the clipped scaled threshold) is that this will respond more
+ gracefully under memory pressure and will ensure that we get more value profile
+ LUBing before triggering recompilation. More LUBing is almost always a good
+ thing.
+
+ * dfg/DFGOSRExitCompiler.cpp:
+ (JSC::DFG::OSRExitCompiler::handleExitCounts):
+
+2012-12-12 Ilya Tikhonovsky <loislo@chromium.org>
+
+ Web Inspector: Native Memory Instrumentation: remove fake root MemoryObjectInfo.
+ https://bugs.webkit.org/show_bug.cgi?id=104796
+
+ Reviewed by Yury Semikhatsky.
+
+ It was not a good idea to introduce a fake root MemoryObjectInfo.
+ It makes a problem when we visit an object without its own MemoryObjectType.
+
+ Example: RenderBox has a global pointer to a hash map.
+ HashMap doesn't have its own object type because it is a generic container.
+ It will inherit object type from the fake root memory object info.
+ The same could happen for another container in another class with other MemoryObjectType.
+
+ This fact forces me to create custom process method for root objects
+ because they need to have their own MemoryObjectInfo with customisable memory object type.
+
+ Drive by fix: InstrumentedPointer* was replaced with Wrapper* because actually it is using
+ for instrumented and not instrumented object classes.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-12-11 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ Implement add64 for ARM traditional assembler after r136601
+ https://bugs.webkit.org/show_bug.cgi?id=104103
+
+ Reviewed by Zoltan Herczeg.
+
+ Implement add64 function for ARM traditional macroassembler.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::add64):
+ (MacroAssemblerARM):
+
+2012-12-11 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed. Fix build with DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE).
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::tallyFrequentExitSites):
+
+2012-12-11 Filip Pizlo <fpizlo@apple.com>
+
+ Profiler should show bytecode dumps as they would have been visible to the JITs, including the profiling data that the JITs would see
+ https://bugs.webkit.org/show_bug.cgi?id=104647
+
+ Reviewed by Oliver Hunt.
+
+ Adds more profiling data to bytecode dumps, and adds the ability to do a secondary
+ bytecode dump for each JIT compilation of a code block. This is relevant because both
+ the bytecodes, and the profiling data, may change after some number of executions.
+
+ Also fixes some random dumping code to use PrintStream& rather than
+ static const char[thingy].
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/ArrayProfile.cpp:
+ (JSC::dumpArrayModes):
+ (JSC::ArrayProfile::briefDescription):
+ * bytecode/ArrayProfile.h:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::CodeBlock::printGetByIdCacheStatus):
+ (JSC::CodeBlock::printCallOp):
+ (JSC::CodeBlock::dumpValueProfiling):
+ (JSC::CodeBlock::dumpArrayProfiling):
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/CodeBlock.h:
+ * bytecode/ValueProfile.h:
+ (JSC::ValueProfileBase::briefDescription):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::dump):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * profiler/ProfilerBytecodeSequence.cpp: Added.
+ (JSC::Profiler::BytecodeSequence::BytecodeSequence):
+ (JSC::Profiler::BytecodeSequence::~BytecodeSequence):
+ (JSC::Profiler::BytecodeSequence::indexForBytecodeIndex):
+ (JSC::Profiler::BytecodeSequence::forBytecodeIndex):
+ (JSC::Profiler::BytecodeSequence::addSequenceProperties):
+ * profiler/ProfilerBytecodeSequence.h: Added.
+ (JSC::Profiler::BytecodeSequence::size):
+ (JSC::Profiler::BytecodeSequence::at):
+ * profiler/ProfilerBytecodes.cpp:
+ (JSC::Profiler::Bytecodes::Bytecodes):
+ (JSC::Profiler::Bytecodes::toJS):
+ * profiler/ProfilerBytecodes.h:
+ (JSC::Profiler::Bytecodes::instructionCount):
+ * profiler/ProfilerCompilation.cpp:
+ (JSC::Profiler::Compilation::addProfiledBytecodes):
+ (JSC::Profiler::Compilation::toJS):
+ * profiler/ProfilerCompilation.h:
+ (JSC::Profiler::Compilation::profiledBytecodesSize):
+ (JSC::Profiler::Compilation::profiledBytecodesAt):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ * profiler/ProfilerDatabase.h:
+ * profiler/ProfilerProfiledBytecodes.cpp: Added.
+ (JSC::Profiler::ProfiledBytecodes::ProfiledBytecodes):
+ (JSC::Profiler::ProfiledBytecodes::~ProfiledBytecodes):
+ (JSC::Profiler::ProfiledBytecodes::toJS):
+ * profiler/ProfilerProfiledBytecodes.h: Added.
+ (JSC::Profiler::ProfiledBytecodes::bytecodes):
+ * runtime/CommonIdentifiers.h:
+
+2012-12-11 Oswald Buddenhagen <oswald.buddenhagen@digia.com>
+
+ [Qt] delete dead include paths
+
+ Reviewed by Simon Hausmann.
+
+ followup to https://bugs.webkit.org/show_bug.cgi?id=93446
+
+ * JavaScriptCore.pri:
+
+2012-12-11 Julien BRIANCEAU <jbrianceau@nds.com>
+
+ Implement add64 for SH4 assembler to fix build after r136601
+ https://bugs.webkit.org/show_bug.cgi?id=104377
+
+ Reviewed by Zoltan Herczeg.
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::add64):
+ (MacroAssemblerSH4):
+
+2012-12-10 Yury Semikhatsky <yurys@chromium.org>
+
+ Memory instrumentation: make sure each edge is reported only once
+ https://bugs.webkit.org/show_bug.cgi?id=104630
+
+ Reviewed by Pavel Feldman.
+
+ Changed exported symbols for MemoryInstrumentation.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-12-10 Filip Pizlo <fpizlo@apple.com>
+
+ Don't OSR exit just because a string is a rope
+ https://bugs.webkit.org/show_bug.cgi?id=104621
+
+ Reviewed by Michael Saboff.
+
+ Slight SunSpider speed-up at around the 0.7% level. This patch does the obvious
+ thing of calling a slow path to resolve ropes rather than OSR exiting if the
+ string is a rope.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::getIndexedPropertyStorageMayTriggerGC):
+ (ArrayMode):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+
+2012-12-10 Gustavo Noronha Silva <gns@gnome.org>
+
+ Unreviewed distcheck fix.
+
+ * GNUmakefile.list.am:
+
+2012-12-10 Filip Pizlo <fpizlo@apple.com>
+
+ JSC profiling and debug dump code should use inferred names when possible
+ https://bugs.webkit.org/show_bug.cgi?id=104519
+
+ Reviewed by Oliver Hunt.
+
+ This does as advertised: the profiler now knows the inferred name of all code blocks,
+ and all uses of CodeBlock::dump() dump it along with the hash.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::inferredName):
+ (JSC::CodeBlock::dumpAssumingJITType):
+ * bytecode/CodeBlock.h:
+ * profiler/ProfilerBytecodes.cpp:
+ (JSC::Profiler::Bytecodes::Bytecodes):
+ (JSC::Profiler::Bytecodes::toJS):
+ * profiler/ProfilerBytecodes.h:
+ (JSC::Profiler::Bytecodes::inferredName):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::addBytecodes):
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ * profiler/ProfilerDatabase.h:
+ * runtime/CommonIdentifiers.h:
+
+2012-12-09 Filip Pizlo <fpizlo@apple.com>
+
+ Profiler should say things about OSR exits
+ https://bugs.webkit.org/show_bug.cgi?id=104497
+
+ Reviewed by Oliver Hunt.
+
+ This adds support for profiling OSR exits. For each exit that is taken, the profiler
+ records the machine code address that the exit occurred on, the exit kind, the origin
+ stack, and the number of times that it happened.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/AbstractMacroAssembler.h:
+ (Jump):
+ (JSC::AbstractMacroAssembler::Jump::label):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::saveCompilation):
+ (CodeBlock):
+ (JSC::CodeBlock::compilation):
+ (DFGData):
+ * bytecode/DFGExitProfile.h:
+ (DFG):
+ * bytecode/ExitKind.cpp: Added.
+ (JSC):
+ (JSC::exitKindToString):
+ (JSC::exitKindIsCountable):
+ (WTF):
+ (WTF::printInternal):
+ * bytecode/ExitKind.h: Added.
+ (JSC):
+ (WTF):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::linkOSRExits):
+ (JSC::DFG::JITCompiler::link):
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ (JITCompiler):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JumpReplacementWatchpoint.h:
+ (JSC::JumpReplacementWatchpoint::sourceLabel):
+ (JumpReplacementWatchpoint):
+ * profiler/ProfilerCompilation.cpp:
+ (JSC::Profiler::Compilation::addOSRExitSite):
+ (Profiler):
+ (JSC::Profiler::Compilation::addOSRExit):
+ (JSC::Profiler::Compilation::toJS):
+ * profiler/ProfilerCompilation.h:
+ (Compilation):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::newCompilation):
+ * profiler/ProfilerDatabase.h:
+ (Database):
+ * profiler/ProfilerOSRExit.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::OSRExit::OSRExit):
+ (JSC::Profiler::OSRExit::~OSRExit):
+ (JSC::Profiler::OSRExit::toJS):
+ * profiler/ProfilerOSRExit.h: Added.
+ (Profiler):
+ (OSRExit):
+ (JSC::Profiler::OSRExit::id):
+ (JSC::Profiler::OSRExit::origin):
+ (JSC::Profiler::OSRExit::exitKind):
+ (JSC::Profiler::OSRExit::isWatchpoint):
+ (JSC::Profiler::OSRExit::counterAddress):
+ (JSC::Profiler::OSRExit::count):
+ * profiler/ProfilerOSRExitSite.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::OSRExitSite::toJS):
+ * profiler/ProfilerOSRExitSite.h: Added.
+ (Profiler):
+ (OSRExitSite):
+ (JSC::Profiler::OSRExitSite::OSRExitSite):
+ (JSC::Profiler::OSRExitSite::codeAddress):
+ * runtime/CommonIdentifiers.h:
+
+2012-12-10 Alexis Menard <alexis@webkit.org>
+
+ [CSS3 Backgrounds and Borders] Remove CSS3_BACKGROUND feature flag.
+ https://bugs.webkit.org/show_bug.cgi?id=104539
+
+ Reviewed by Antonio Gomes.
+
+ As discussed on webkit-dev it is not needed to keep this feature flag
+ as support for <position> type is a small feature that is already
+ implemented by three other UAs. It was useful while landing this
+ feature as partial bits were landed one after one.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-12-09 Filip Pizlo <fpizlo@apple.com>
+
+ DFG ArrayPush/Pop should not pass their second child as the index for blessArrayOperation()
+ https://bugs.webkit.org/show_bug.cgi?id=104500
+
+ Reviewed by Oliver Hunt.
+
+ Slight across-the-board speed-up.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+
+2012-12-08 Filip Pizlo <fpizlo@apple.com>
+
+ JSC should scale the optimization threshold for a code block according to the cost of compiling it
+ https://bugs.webkit.org/show_bug.cgi?id=104406
+
+ Reviewed by Oliver Hunt.
+
+ We've long known that we want to scale the execution count threshold needed for the DFG
+ to kick in to scale according to some estimate of the cost of compiling that code block.
+ This institutes a relationship like this:
+
+ threshold = thresholdSetting * (a * sqrt(instructionCount + b) + abs(c * instructionCount) + d
+
+ Where a, b, c, d are coefficients derived from fitting the above expression to various
+ data points, which I chose based on looking at one benchmark (3d-cube) and from my
+ own intuitions.
+
+ Making this work well also required changing the thresholdForOptimizeAfterLongWarmUp
+ from 5000 to 1000.
+
+ This is a >1% speed-up on SunSpider, a >3% speed-up on V8Spider, ~1% speed-up on V8v7,
+ neutral on Octane, and neutral on Kraken.
+
+ I also out-of-lined a bunch of methods related to these heuristics, because I couldn't
+ stand having them defined in the header anymore. I also made improvements to debugging
+ code because I needed it for tuning this change.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::sourceCodeForTools):
+ (JSC::CodeBlock::sourceCodeOnOneLine):
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::reoptimizationRetryCounter):
+ (JSC::CodeBlock::countReoptimization):
+ (JSC::CodeBlock::optimizationThresholdScalingFactor):
+ (JSC::clipThreshold):
+ (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp):
+ (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp):
+ (JSC::CodeBlock::counterValueForOptimizeSoon):
+ (JSC::CodeBlock::checkIfOptimizationThresholdReached):
+ (JSC::CodeBlock::optimizeNextInvocation):
+ (JSC::CodeBlock::dontOptimizeAnytimeSoon):
+ (JSC::CodeBlock::optimizeAfterWarmUp):
+ (JSC::CodeBlock::optimizeAfterLongWarmUp):
+ (JSC::CodeBlock::optimizeSoon):
+ (JSC::CodeBlock::adjustedExitCountThreshold):
+ (JSC::CodeBlock::exitCountThresholdForReoptimization):
+ (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop):
+ (JSC::CodeBlock::shouldReoptimizeNow):
+ (JSC::CodeBlock::shouldReoptimizeFromLoopNow):
+ * bytecode/CodeBlock.h:
+ * bytecode/ExecutionCounter.cpp:
+ (JSC::ExecutionCounter::hasCrossedThreshold):
+ * bytecode/ReduceWhitespace.cpp: Added.
+ (JSC::reduceWhitespace):
+ * bytecode/ReduceWhitespace.h: Added.
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::mightCompileEval):
+ (JSC::DFG::mightCompileProgram):
+ (JSC::DFG::mightCompileFunctionForCall):
+ (JSC::DFG::mightCompileFunctionForConstruct):
+ (JSC::DFG::mightInlineFunctionForCall):
+ (JSC::DFG::mightInlineFunctionForConstruct):
+ * dfg/DFGCapabilities.h:
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dumpHeader):
+ * dfg/DFGOSREntry.cpp:
+ (JSC::DFG::prepareOSREntry):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dumpHeader):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::entryOSR):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ * runtime/Options.h:
+
+2012-12-07 Jonathan Liu <net147@gmail.com>
+
+ Add missing forward declaration for JSC::ArrayAllocationProfile
+ https://bugs.webkit.org/show_bug.cgi?id=104425
+
+ Reviewed by Kentaro Hara.
+
+ The header for the JSC::ArrayConstructor class is missing a forward
+ declaration for the JSC::ArrayAllocationProfile class which causes
+ compilation to fail when compiling with MinGW-w64.
+
+ * runtime/ArrayConstructor.h:
+ (JSC):
+
+2012-12-07 Jonathan Liu <net147@gmail.com>
+
+ Add missing const qualifier to JSC::CodeBlock::getJITType()
+ https://bugs.webkit.org/show_bug.cgi?id=104424
+
+ Reviewed by Laszlo Gombos.
+
+ JSC::CodeBlock::getJITType() has the const qualifier when JIT is
+ enabled but is missing the const qualifier when JIT is disabled.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::getJITType):
+
+2012-12-07 Oliver Hunt <oliver@apple.com>
+
+ Make function code cache proportional to main codeblock cache
+ https://bugs.webkit.org/show_bug.cgi?id=104420
+
+ Reviewed by Geoffrey Garen.
+
+ Makes the constants determining the recently used function cache proportional
+ to the number of root codeblocks in the cache. Also renames the constants to
+ make them more clear.
+
+ * runtime/CodeCache.h:
+
+2012-12-06 Filip Pizlo <fpizlo@apple.com>
+
+ Strange results calculating a square root in a loop
+ https://bugs.webkit.org/show_bug.cgi?id=104247
+ <rdar://problem/12826880>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed the CFG simplification phase to ignore dead GetLocals in the first of the blocks
+ under the merge. This fixes the assertion, and is also cleaner: our general rule is
+ to not "revive" things that we've already proved to be dead.
+
+ Also fixed some rotted debug code.
+
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2012-12-07 Geoffrey Garen <ggaren@apple.com>
+
+ Crash in JSC::Bindings::RootObject::globalObject() sync'ing notes in Evernote
+ https://bugs.webkit.org/show_bug.cgi?id=104321
+ <rdar://problem/12770497>
+
+ Reviewed by Sam Weinig.
+
+ Work around a JSValueUnprotect(NULL) in Evernote.
+
+ * API/JSValueRef.cpp:
+ (evernoteHackNeeded):
+ (JSValueUnprotect):
+
+2012-12-06 Filip Pizlo <fpizlo@apple.com>
+
+ Incorrect inequality for checking whether a statement is within bounds of a handler
+ https://bugs.webkit.org/show_bug.cgi?id=104313
+ <rdar://problem/12808934>
+
+ Reviewed by Geoffrey Garen.
+
+ The most relevant change is in handlerForBytecodeOffset(), which fixes the inequality
+ used for checking whether a handler is pertinent to the current instruction. '<' is
+ correct, but '<=' isn't, since the 'end' is not inclusive.
+
+ Also found, and addressed, a benign goof in how the finally inliner works: sometimes
+ we will have end > start. This falls out naturally from how the inliner works and how
+ we pop scopes in the bytecompiler, but it's sufficiently surprising that, to avoid any
+ future confusion, I added a comment and some code to prune those handlers out. Because
+ of how the handler resolution works, these handlers would have been skipped anyway.
+
+ Also made various fixes to debugging code, which was necessary for tracking this down.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::handlerForBytecodeOffset):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ * bytecompiler/Label.h:
+ (JSC::Label::bind):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+ * llint/LLIntExceptions.cpp:
+ (JSC::LLInt::interpreterThrowInCaller):
+ (JSC::LLInt::returnToThrow):
+ (JSC::LLInt::callToThrow):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::handleHostCall):
+
+2012-12-06 Rick Byers <rbyers@chromium.org>
+
+ CSS cursor property should support webkit-image-set
+ https://bugs.webkit.org/show_bug.cgi?id=99493
+
+ Reviewed by Beth Dakin.
+
+ Add ENABLE_MOUSE_CURSOR_SCALE (disabled by default)
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-12-06 Laszlo Gombos <l.gombos@samsung.com>
+
+ [CMake] Consolidate list of files to build for JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=104287
+
+ Reviewed by Gyuyoung Kim.
+
+ Add MemoryStatistics.cpp and ExecutableAllocator.cpp to the common
+ list of files and remove them from the port specific lists.
+
+ * CMakeLists.txt:
+ * PlatformBlackBerry.cmake:
+ * PlatformEfl.cmake:
+ * PlatformWinCE.cmake:
+
+2012-12-06 Oliver Hunt <oliver@apple.com>
+
+ Tell heap that we've released all the compiled code.
+
+ Reviewed by Geoff Garen.
+
+ When we discard compiled code, inform the heap that we've
+ released an entire object graph. This informs the heap that
+ it might want to perform a GC soon.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::discardAllCode):
+
+2012-12-06 Laszlo Gombos <l.gombos@samsung.com>
+
+ [EFL] Remove ENABLE_GLIB_SUPPORT CMake variable
+ https://bugs.webkit.org/show_bug.cgi?id=104278
+
+ Reviewed by Brent Fulgham.
+
+ The conditional is not required as it is always set for EFL.
+
+ * PlatformEfl.cmake:
+
+2012-12-06 Oliver Hunt <oliver@apple.com>
+
+ Build fix, last patch rolled out logic that is now needed on ToT.
+
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ (JSC::ASTBuilder::setFunctionStart):
+ * parser/Nodes.h:
+ (JSC::FunctionBodyNode::setFunctionStart):
+ (JSC::FunctionBodyNode::functionStart):
+ (FunctionBodyNode):
+ * parser/Parser.cpp:
+ (JSC::::parseFunctionInfo):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::setFunctionStart):
+
+2012-12-05 Oliver Hunt <oliver@apple.com>
+
+ Remove harmful string->function cache
+ https://bugs.webkit.org/show_bug.cgi?id=104193
+
+ Reviewed by Alexey Proskuryakov.
+
+ Remove the string->function code cache that turned out to actually
+ be quite harmful.
+
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getFunctionCodeBlock):
+ * runtime/CodeCache.h:
+ (JSC::CodeCache::clear):
+
+2012-12-05 Halton Huo <halton.huo@intel.com>
+
+ [CMake] Unify coding style for CMake files
+ https://bugs.webkit.org/show_bug.cgi?id=103605
+
+ Reviewed by Laszlo Gombos.
+
+ Update cmake files(.cmake, CMakeLists.txt) with following style rules:
+ 1. Indentation
+ 1.1 Use spaces, not tabs.
+ 1.2 Four spaces as indent.
+ 2. Spacing
+ 2.1 Place one space between control statements and their parentheses.
+ For eg, if (), else (), elseif (), endif (), foreach (),
+ endforeach (), while (), endwhile (), break ().
+ 2.2 Do not place spaces between function and macro statements and
+ their parentheses. For eg, macro(), endmacro(), function(),
+ endfunction().
+ 2.3 Do not place spaces between a command or function or macro and its
+ parentheses, or between a parenthesis and its content. For eg,
+ message("testing") not message( "testing") or message ("testing" )
+ 2.4 No space at line ending.
+ 3. Lowercase when call commands macros and functions. For eg,
+ add_executable() not ADD_EXECUTABLE(), set() not SET().
+
+ * CMakeLists.txt:
+ * PlatformBlackBerry.cmake:
+ * PlatformEfl.cmake:
+ * PlatformWinCE.cmake:
+ * shell/CMakeLists.txt:
+ * shell/PlatformBlackBerry.cmake:
+ * shell/PlatformEfl.cmake:
+ * shell/PlatformWinCE.cmake:
+
+2012-12-05 Oliver Hunt <oliver@apple.com>
+
+ Empty parse cache when receiving a low memory warning
+ https://bugs.webkit.org/show_bug.cgi?id=104161
+
+ Reviewed by Filip Pizlo.
+
+ This adds a function to the globaldata to empty all code related data
+ structures (code in the heap and the code cache).
+ It also adds a function to allow the CodeCache to actually be cleared
+ at all.
+
+ * runtime/CodeCache.h:
+ (CacheMap):
+ (JSC::CacheMap::clear):
+ (JSC::CodeCache::clear):
+ (CodeCache):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::discardAllCode):
+ (JSC):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+
+2012-12-05 Filip Pizlo <fpizlo@apple.com>
+
+ JSC profiler should not count executions of op_call_put_result because doing so changes DFG codegen
+ https://bugs.webkit.org/show_bug.cgi?id=104102
+
+ Reviewed by Oliver Hunt.
+
+ This removes op_call_put_result from profiling, since profiling it has an effect on
+ codegen. This fix enables all of SunSpider, V8, and Kraken to be profiled with the
+ new profiler.
+
+ To make this all fit together, the profiler now also reports in its output the exact
+ bytecode opcode name for each instruction (in addition to the stringified dump of that
+ bytecode), so that tools that grok the output can take note of op_call_put_result and
+ work around the fact that it has no counts.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * profiler/ProfilerBytecode.cpp:
+ (JSC::Profiler::Bytecode::toJS):
+ * profiler/ProfilerBytecode.h:
+ (JSC::Profiler::Bytecode::Bytecode):
+ (JSC::Profiler::Bytecode::opcodeID):
+ (Bytecode):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ * runtime/CommonIdentifiers.h:
+
+2012-12-04 Filip Pizlo <fpizlo@apple.com>
+
+ display-profiler-output should be able to show source code
+ https://bugs.webkit.org/show_bug.cgi?id=104073
+
+ Reviewed by Oliver Hunt.
+
+ Modify the profiler database to store source code. For functions, we store the
+ function including the function signature.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::unlinkedCodeBlock):
+ (CodeBlock):
+ * profiler/ProfilerBytecodes.cpp:
+ (JSC::Profiler::Bytecodes::Bytecodes):
+ (JSC::Profiler::Bytecodes::toJS):
+ * profiler/ProfilerBytecodes.h:
+ (Bytecodes):
+ (JSC::Profiler::Bytecodes::sourceCode):
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::addBytecodes):
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ * profiler/ProfilerDatabase.h:
+ (Database):
+ * runtime/CommonIdentifiers.h:
+ * runtime/Executable.h:
+ (FunctionExecutable):
+ (JSC::FunctionExecutable::unlinkedExecutable):
+
+2012-12-02 Filip Pizlo <fpizlo@apple.com>
+
+ JSC should be able to report profiling data associated with the IR dumps and disassembly
+ https://bugs.webkit.org/show_bug.cgi?id=102999
+
+ Reviewed by Gavin Barraclough.
+
+ Added a new profiler to JSC. It's simply called "Profiler" in anticipation of it
+ ultimately replacing the previous profiling infrastructure. This profiler counts the
+ number of times that a bytecode executes in various engines, and will record both the
+ counts and all disassembly and bytecode dumps, into a database that can be at any
+ time turned into either a JS object using any global object or global data of your
+ choice, or can be turned into a JSON string, or saved to a file.
+
+ Currently the only use of this is the new '-p <file>' flag to the jsc command-line.
+
+ The profiler is always compiled in and normally incurs no execution time cost, but is
+ only activated when you create a Profiler::Database and install it in
+ JSGlobalData::m_perBytecodeProfiler. From that point on, all code blocks will be
+ compiled along with disassembly and bytecode dumps stored into the Profiler::Database,
+ and all code blocks will have execution counts, which are also stored in the database.
+ The database will continue to keep information about code blocks alive even after they
+ are otherwise GC'd.
+
+ This currently still has some glitches, like the fact that it only counts executions
+ in the JITs. Doing execution counting in the LLInt might require a bit of a rethink
+ about how the counting is expressed - currently it is implicit in bytecode, so there
+ is no easy way to "turn it on" in the LLInt. Also, right now there is no information
+ recorded about OSR exits or out-of-line stubs. But, even so, it's quite cool, and
+ gives you a peek into what JSC is doing that would otherwise not be possible.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::~CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::baselineVersion):
+ * bytecode/CodeOrigin.cpp:
+ (JSC::InlineCallFrame::baselineCodeBlock):
+ (JSC):
+ * bytecode/CodeOrigin.h:
+ (InlineCallFrame):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dump):
+ (DFG):
+ (JSC::DFG::Disassembler::reportToProfiler):
+ (JSC::DFG::Disassembler::dumpHeader):
+ (JSC::DFG::Disassembler::append):
+ (JSC::DFG::Disassembler::createDumpList):
+ * dfg/DFGDisassembler.h:
+ (Disassembler):
+ (JSC::DFG::Disassembler::DumpedOp::DumpedOp):
+ (DumpedOp):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::Graph):
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::JITCompiler):
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGNode.h:
+ (Node):
+ (JSC::DFG::Node::hasExecutionCounter):
+ (JSC::DFG::Node::executionCounter):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dump):
+ (JSC::JITDisassembler::reportToProfiler):
+ (JSC):
+ (JSC::JITDisassembler::dumpHeader):
+ (JSC::JITDisassembler::firstSlowLabel):
+ (JSC::JITDisassembler::dumpVectorForInstructions):
+ (JSC::JITDisassembler::dumpForInstructions):
+ (JSC::JITDisassembler::reportInstructions):
+ * jit/JITDisassembler.h:
+ (JITDisassembler):
+ (DumpedOp):
+ * jsc.cpp:
+ (CommandLine::CommandLine):
+ (CommandLine):
+ (printUsageStatement):
+ (CommandLine::parseArguments):
+ (jscmain):
+ * profiler/ProfilerBytecode.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::Bytecode::toJS):
+ * profiler/ProfilerBytecode.h: Added.
+ (Profiler):
+ (Bytecode):
+ (JSC::Profiler::Bytecode::Bytecode):
+ (JSC::Profiler::Bytecode::bytecodeIndex):
+ (JSC::Profiler::Bytecode::description):
+ (JSC::Profiler::getBytecodeIndexForBytecode):
+ * profiler/ProfilerBytecodes.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::Bytecodes::Bytecodes):
+ (JSC::Profiler::Bytecodes::~Bytecodes):
+ (JSC::Profiler::Bytecodes::indexForBytecodeIndex):
+ (JSC::Profiler::Bytecodes::forBytecodeIndex):
+ (JSC::Profiler::Bytecodes::dump):
+ (JSC::Profiler::Bytecodes::toJS):
+ * profiler/ProfilerBytecodes.h: Added.
+ (Profiler):
+ (Bytecodes):
+ (JSC::Profiler::Bytecodes::append):
+ (JSC::Profiler::Bytecodes::id):
+ (JSC::Profiler::Bytecodes::hash):
+ (JSC::Profiler::Bytecodes::size):
+ (JSC::Profiler::Bytecodes::at):
+ * profiler/ProfilerCompilation.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::Compilation::Compilation):
+ (JSC::Profiler::Compilation::~Compilation):
+ (JSC::Profiler::Compilation::addDescription):
+ (JSC::Profiler::Compilation::executionCounterFor):
+ (JSC::Profiler::Compilation::toJS):
+ * profiler/ProfilerCompilation.h: Added.
+ (Profiler):
+ (Compilation):
+ (JSC::Profiler::Compilation::bytecodes):
+ (JSC::Profiler::Compilation::kind):
+ * profiler/ProfilerCompilationKind.cpp: Added.
+ (WTF):
+ (WTF::printInternal):
+ * profiler/ProfilerCompilationKind.h: Added.
+ (Profiler):
+ (WTF):
+ * profiler/ProfilerCompiledBytecode.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::CompiledBytecode::CompiledBytecode):
+ (JSC::Profiler::CompiledBytecode::~CompiledBytecode):
+ (JSC::Profiler::CompiledBytecode::toJS):
+ * profiler/ProfilerCompiledBytecode.h: Added.
+ (Profiler):
+ (CompiledBytecode):
+ (JSC::Profiler::CompiledBytecode::originStack):
+ (JSC::Profiler::CompiledBytecode::description):
+ * profiler/ProfilerDatabase.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::Database::Database):
+ (JSC::Profiler::Database::~Database):
+ (JSC::Profiler::Database::addBytecodes):
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ (JSC::Profiler::Database::notifyDestruction):
+ (JSC::Profiler::Database::newCompilation):
+ (JSC::Profiler::Database::toJS):
+ (JSC::Profiler::Database::toJSON):
+ (JSC::Profiler::Database::save):
+ * profiler/ProfilerDatabase.h: Added.
+ (Profiler):
+ (Database):
+ * profiler/ProfilerExecutionCounter.h: Added.
+ (Profiler):
+ (ExecutionCounter):
+ (JSC::Profiler::ExecutionCounter::ExecutionCounter):
+ (JSC::Profiler::ExecutionCounter::address):
+ (JSC::Profiler::ExecutionCounter::count):
+ * profiler/ProfilerOrigin.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::Origin::Origin):
+ (JSC::Profiler::Origin::dump):
+ (JSC::Profiler::Origin::toJS):
+ * profiler/ProfilerOrigin.h: Added.
+ (JSC):
+ (Profiler):
+ (Origin):
+ (JSC::Profiler::Origin::Origin):
+ (JSC::Profiler::Origin::operator!):
+ (JSC::Profiler::Origin::bytecodes):
+ (JSC::Profiler::Origin::bytecodeIndex):
+ (JSC::Profiler::Origin::operator!=):
+ (JSC::Profiler::Origin::operator==):
+ (JSC::Profiler::Origin::hash):
+ (JSC::Profiler::Origin::isHashTableDeletedValue):
+ (JSC::Profiler::OriginHash::hash):
+ (JSC::Profiler::OriginHash::equal):
+ (OriginHash):
+ (WTF):
+ * profiler/ProfilerOriginStack.cpp: Added.
+ (Profiler):
+ (JSC::Profiler::OriginStack::OriginStack):
+ (JSC::Profiler::OriginStack::~OriginStack):
+ (JSC::Profiler::OriginStack::append):
+ (JSC::Profiler::OriginStack::operator==):
+ (JSC::Profiler::OriginStack::hash):
+ (JSC::Profiler::OriginStack::dump):
+ (JSC::Profiler::OriginStack::toJS):
+ * profiler/ProfilerOriginStack.h: Added.
+ (JSC):
+ (Profiler):
+ (OriginStack):
+ (JSC::Profiler::OriginStack::OriginStack):
+ (JSC::Profiler::OriginStack::operator!):
+ (JSC::Profiler::OriginStack::size):
+ (JSC::Profiler::OriginStack::fromBottom):
+ (JSC::Profiler::OriginStack::fromTop):
+ (JSC::Profiler::OriginStack::isHashTableDeletedValue):
+ (JSC::Profiler::OriginStackHash::hash):
+ (JSC::Profiler::OriginStackHash::equal):
+ (OriginStackHash):
+ (WTF):
+ * runtime/CommonIdentifiers.h:
+ * runtime/ExecutionHarness.h:
+ (JSC::prepareForExecution):
+ (JSC::prepareFunctionForExecution):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ * runtime/Options.h:
+ (JSC):
+
+2012-12-04 Filip Pizlo <fpizlo@apple.com>
+
+ Rename Profiler to LegacyProfiler
+ https://bugs.webkit.org/show_bug.cgi?id=104031
+
+ Rubber stamped by Mark Hahnenberg
+
+ Make room in the namespace for https://bugs.webkit.org/show_bug.cgi?id=102999.
+
+ * API/JSProfilerPrivate.cpp:
+ (JSStartProfiling):
+ (JSEndProfiling):
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ * jit/JIT.h:
+ * jit/JITCode.h:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ (JSC):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * profiler/LegacyProfiler.cpp: Added.
+ (JSC):
+ (JSC::LegacyProfiler::profiler):
+ (JSC::LegacyProfiler::startProfiling):
+ (JSC::LegacyProfiler::stopProfiling):
+ (JSC::dispatchFunctionToProfiles):
+ (JSC::LegacyProfiler::willExecute):
+ (JSC::LegacyProfiler::didExecute):
+ (JSC::LegacyProfiler::exceptionUnwind):
+ (JSC::LegacyProfiler::createCallIdentifier):
+ (JSC::createCallIdentifierFromFunctionImp):
+ * profiler/LegacyProfiler.h: Added.
+ (JSC):
+ (LegacyProfiler):
+ (JSC::LegacyProfiler::currentProfiles):
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::addParentForConsoleStart):
+ * profiler/ProfileNode.cpp:
+ * profiler/Profiler.cpp: Removed.
+ * profiler/Profiler.h: Removed.
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSC::JSGlobalData::enabledProfiler):
+ (JSGlobalData):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::~JSGlobalObject):
+
+2012-12-03 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should inline code blocks that use scoped variable access
+ https://bugs.webkit.org/show_bug.cgi?id=103974
+
+ Reviewed by Oliver Hunt.
+
+ This mostly just turns on something we could have done all along, but also adds a few key
+ necessities to make this right:
+
+ 1) Constant folding of SkipScope, since if we inline with a known JSFunction* then the
+ scope is constant.
+
+ 2) Interference analysis for GetLocal<->PutScopedVar and SetLocal<->GetScopedVar.
+
+ This is not meant to be a speed-up on major benchmarks since we don't yet inline most
+ closure calls for entirely unrelated reasons. But on toy programs it can be >2x faster.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getScope):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (JSC::DFG::CSEPhase::scopedVarStoreElimination):
+ (JSC::DFG::CSEPhase::getLocalLoadElimination):
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineResolveOperations):
+
+2012-12-03 Filip Pizlo <fpizlo@apple.com>
+
+ Replace JSValue::description() with JSValue::dump(PrintStream&)
+ https://bugs.webkit.org/show_bug.cgi?id=103866
+
+ Reviewed by Darin Adler.
+
+ JSValue now has a dump() method. Anywhere that you would have wanted to use
+ description(), you can either do toCString(value).data(), or if the callee
+ is a print()/dataLog() method then you just pass the value directly.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * bytecode/CodeBlock.cpp:
+ (JSC::valueToSourceString):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ * bytecode/ValueProfile.h:
+ (JSC::ValueProfileBase::dump):
+ * bytecode/ValueRecovery.h:
+ (JSC::ValueRecovery::dump):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::dump):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpRegisters):
+ * jsc.cpp:
+ (functionDescribe):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::llint_trace_value):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::dump):
+ * runtime/JSValue.h:
+
+2012-12-04 Filip Pizlo <fpizlo@apple.com>
+
+ jsc command line tool's support for typed arrays should be robust against array buffer allocation errors
+ https://bugs.webkit.org/show_bug.cgi?id=104020
+ <rdar://problem/12802478>
+
+ Reviewed by Mark Hahnenberg.
+
+ Check for null buffers, since that's what typed array allocators are supposed to do. WebCore does it,
+ and that is indeed the contract of ArrayBuffer and TypedArrayBase.
+
+ * JSCTypedArrayStubs.h:
+ (JSC):
+
+2012-12-03 Peter Rybin <prybin@chromium.org>
+
+ Web Inspector: make ASSERTION FAILED: foundPropertiesCount == object->size() more useful
+ https://bugs.webkit.org/show_bug.cgi?id=103254
+
+ Reviewed by Pavel Feldman.
+
+ Missing symbol WTFReportFatalError is added to the linker list.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-12-03 Alexis Menard <alexis@webkit.org>
+
+ [Mac] Enable CSS3 background-position offset by default.
+ https://bugs.webkit.org/show_bug.cgi?id=103905
+
+ Reviewed by Simon Fraser.
+
+ Turn the flag on by default.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-12-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should trigger rage conversion from double to contiguous if it sees a GetByVal on Double being used in an integer context
+ https://bugs.webkit.org/show_bug.cgi?id=103858
+
+ Reviewed by Gavin Barraclough.
+
+ A rage conversion from double to contiguous is one where you try to convert each
+ double to an int32.
+
+ This is probably not the last we'll hear of rage conversion from double to contiguous.
+ It may be better to do this right during parsing, which will result in fewer cases of
+ Arrayification. But even so, this looks like a straight win already - 1% speed-up on
+ Kraken, no major regression anywhere else.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::refine):
+ (JSC::DFG::arrayConversionToString):
+ (JSC::DFG::ArrayMode::dump):
+ (WTF):
+ (WTF::printInternal):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::withConversion):
+ (ArrayMode):
+ (JSC::DFG::ArrayMode::doesConversion):
+ (WTF):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupBlock):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ (FixupPhase):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * runtime/JSObject.cpp:
+ (JSC):
+ (JSC::JSObject::genericConvertDoubleToContiguous):
+ (JSC::JSObject::convertDoubleToContiguous):
+ (JSC::JSObject::rageConvertDoubleToContiguous):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::rageEnsureContiguousSlow):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC::JSObject::rageEnsureContiguous):
+
+2012-12-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CSE should not keep alive things that aren't relevant to OSR
+ https://bugs.webkit.org/show_bug.cgi?id=103849
+
+ Reviewed by Oliver Hunt.
+
+ Most Phantom nodes are inserted by CSE, and by default have the same children as the
+ node that CSE had eliminated. This change makes CSE inspect all Phantom nodes (both
+ those it creates and those that were created by other phases) to see if they have
+ children that are redundant - i.e. children that are not interesting to OSR, which
+ is the only reason why Phantoms exist in the first place. Being relevant to OSR is
+ defined as one of: (1) you're a Phi, (2) you're a SetLocal, (3) somewhere between
+ your definition and the Phantom there was a SetLocal that referred to you.
+
+ This is a slight speed-up in a few places.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::CSEPhase):
+ (JSC::DFG::CSEPhase::run):
+ (JSC::DFG::CSEPhase::performSubstitution):
+ (CSEPhase):
+ (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::eliminate):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ (JSC::DFG::CSEPhase::performBlockCSE):
+
+2012-12-02 Filip Pizlo <fpizlo@apple.com>
+
+ It should be possible to build and run with DFG_ENABLE(PROPAGATION_VERBOSE)
+ https://bugs.webkit.org/show_bug.cgi?id=103848
+
+ Reviewed by Sam Weinig.
+
+ Fix random dataLog() and print() statements.
+
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dumpBlockHeader):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2012-12-01 Filip Pizlo <fpizlo@apple.com>
+
+ CodeBlock should be able to dump bytecode to something other than WTF::dataFile()
+ https://bugs.webkit.org/show_bug.cgi?id=103832
+
+ Reviewed by Oliver Hunt.
+
+ Add a PrintStream& argument to all of the CodeBlock bytecode dumping methods.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecodeCommentAndNewLine):
+ (JSC::CodeBlock::printUnaryOp):
+ (JSC::CodeBlock::printBinaryOp):
+ (JSC::CodeBlock::printConditionalJump):
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::dumpStructure):
+ (JSC::dumpChain):
+ (JSC::CodeBlock::printGetByIdCacheStatus):
+ (JSC::CodeBlock::printCallOp):
+ (JSC::CodeBlock::printPutByIdOp):
+ (JSC::CodeBlock::printStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dumpBytecode):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dumpForInstructions):
+
+2012-11-30 Pierre Rossi <pierre.rossi@gmail.com>
+
+ [Qt] Unreviewed speculative Mac build fix after r136232
+
+ Update the include path so that LLIntAssembly.h is picked up.
+ The bot didn't break until later when a clean build was triggered.
+
+ * JavaScriptCore.pri:
+
+2012-11-30 Oliver Hunt <oliver@apple.com>
+
+ Optimise more cases of op_typeof
+ https://bugs.webkit.org/show_bug.cgi?id=103783
+
+ Reviewed by Mark Hahnenberg.
+
+ Increase our coverage of typeof based typechecks by
+ making sure that the codegenerators always uses
+ consistent operand ordering when feeding typeof operations
+ into equality operations.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::EqualNode::emitBytecode):
+ (JSC::StrictEqualNode::emitBytecode):
+
+2012-11-30 Filip Pizlo <fpizlo@apple.com>
+
+ Rationalize and clean up DFG handling of scoped accesses
+ https://bugs.webkit.org/show_bug.cgi?id=103715
+
+ Reviewed by Oliver Hunt.
+
+ Previously, we had a GetScope node that specified the depth to which you wanted
+ to travel to get a JSScope, and the backend implementation of the node would
+ perform all of the necessary footwork, including potentially skipping the top
+ scope if necessary, and doing however many loads were needed. But there were
+ strange things. First, if you had accesses at different scope depths, then the
+ loads to get to the common depth could not be CSE'd - CSE would match only
+ GetScope's that had identical depth. Second, GetScope would be emitted even if
+ we already had the scope, for example in put_to_base. And finally, even though
+ the ResolveOperations could tell us whether or not we had to skip the top scope,
+ the backend would recompute this information itself, often pessimistically.
+
+ This eliminates GetScope and replaces it with the following:
+
+ GetMyScope: just get the JSScope from the call frame header. This will forever
+ mean getting the JSScope associated with the machine call frame; it will not
+ mean getting the scope of an inlined function. Or at least that's the intent.
+
+ SkipTopScope: check if there is an activation, and if so, skip a scope. This
+ takes a scope as a child and returns a scope.
+
+ SkipScope: skip one scope level.
+
+ The bytecode parser now emits the right combination of the above, and
+ potentially emits multiple SkipScope's, based on the ResolveOperations.
+
+ This change also includes some fixups to debug logging. We now always print
+ the ExecutableBase* in addition to the CodeBlock* in the CodeBlock's dump,
+ and we are now more verbose when dumping CodeOrigins and InlineCallFrames.
+
+ This is performance-neutral. It's just meant to be a clean-up.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpAssumingJITType):
+ * bytecode/CodeOrigin.cpp:
+ (JSC::CodeOrigin::inlineStack):
+ (JSC::CodeOrigin::dump):
+ (JSC):
+ (JSC::InlineCallFrame::dump):
+ * bytecode/CodeOrigin.h:
+ (CodeOrigin):
+ (InlineCallFrame):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::getScope):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (JSC::DFG::CSEPhase::scopedVarStoreElimination):
+ (JSC::DFG::CSEPhase::getMyScopeLoadElimination):
+ (JSC::DFG::CSEPhase::setLocalStoreElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dump):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ (JSC::DFG::Graph::dumpBlockHeader):
+ * dfg/DFGNode.h:
+ (Node):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dump):
+
+2012-11-30 Oliver Hunt <oliver@apple.com>
+
+ Add direct string->function code cache
+ https://bugs.webkit.org/show_bug.cgi?id=103764
+
+ Reviewed by Michael Saboff.
+
+ A fairly logically simple patch. We now track the start of the
+ unique portion of a functions body, and use that as our key for
+ unlinked function code. This allows us to cache identical code
+ in different contexts, leading to a small but consistent improvement
+ on the benchmarks we track.
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedFunctionExecutable::functionStartOffset):
+ (UnlinkedFunctionExecutable):
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ (JSC::ASTBuilder::setFunctionStart):
+ * parser/Nodes.cpp:
+ * parser/Nodes.h:
+ (JSC::FunctionBodyNode::setFunctionStart):
+ (JSC::FunctionBodyNode::functionStart):
+ (FunctionBodyNode):
+ * parser/Parser.cpp:
+ (JSC::::parseFunctionInfo):
+ * parser/Parser.h:
+ (JSC::Parser::findCachedFunctionInfo):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::setFunctionStart):
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::generateFunctionCodeBlock):
+ (JSC::CodeCache::getFunctionCodeBlock):
+ (JSC::CodeCache::usedFunctionCode):
+ * runtime/CodeCache.h:
+
+2012-11-30 Allan Sandfeld Jensen <allan.jensen@digia.com>
+
+ Crash in conversion of empty OpaqueJSString to Identifier
+ https://bugs.webkit.org/show_bug.cgi?id=101867
+
+ Reviewed by Michael Saboff.
+
+ The constructor call used for both null and empty OpaqueJSStrings results
+ in an assertion voilation and crash. This patch instead uses the Identifier
+ constructors which are specifically for null and empty Identifier.
+
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::identifier):
+
+2012-11-30 Tor Arne Vestbø <tor.arne.vestbo@digia.com>
+
+ [Qt] Place the LLIntOffsetsExtractor binaries in debug/release subdirs on Mac
+
+ Otherwise we'll end up using the same LLIntAssembly.h for both build
+ configs of JavaScriptCore -- one of them which will be for the wrong
+ config.
+
+ Reviewed by Simon Hausmann.
+
+ * LLIntOffsetsExtractor.pro:
+
+2012-11-30 Julien BRIANCEAU <jbrianceau@nds.com>
+
+ [sh4] Fix compilation warnings in JavaScriptCore JIT for sh4 arch
+ https://bugs.webkit.org/show_bug.cgi?id=103378
+
+ Reviewed by Filip Pizlo.
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::branchTest32):
+ (JSC::MacroAssemblerSH4::branchAdd32):
+ (JSC::MacroAssemblerSH4::branchMul32):
+ (JSC::MacroAssemblerSH4::branchSub32):
+ (JSC::MacroAssemblerSH4::branchOr32):
+
+2012-11-29 Rafael Weinstein <rafaelw@chromium.org>
+
+ [HTMLTemplateElement] Add feature flag
+ https://bugs.webkit.org/show_bug.cgi?id=103694
+
+ Reviewed by Adam Barth.
+
+ This flag will guard the implementation of the HTMLTemplateElement.
+ http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-11-29 Filip Pizlo <fpizlo@apple.com>
+
+ It should be easy to find code blocks in debug dumps
+ https://bugs.webkit.org/show_bug.cgi?id=103623
+
+ Reviewed by Goeffrey Garen.
+
+ This gives CodeBlock a relatively strong, but also relatively compact, hash. We compute
+ it lazily so that it only impacts run-time when debug support is enabled. We stringify
+ it smartly so that it's short and easy to type. We base it on the source code so that
+ the optimization level is irrelevant. And, we use SHA1 since it's already in our code
+ base. Now, when a piece of code wants to print some debugging to say that it's operating
+ on some code block, it can use this CodeBlockHash instead of memory addresses.
+
+ This also takes CodeBlock debugging into the new world of print() and dataLog(). In
+ particular, CodeBlock::dump() corresponds to the thing you want printed if you do:
+
+ dataLog("I heart ", *myCodeBlock);
+
+ Probably, you want to just print some identifying information at this point rather than
+ the full bytecode dump. So, the existing CodeBlock::dump() has been renamed to
+ CodeBlock::dumpBytecode(), and CodeBlock::dump() now prints the CodeBlockHash plus just
+ a few little tidbits.
+
+ Here's an example of CodeBlock::dump() output:
+
+ EkILzr:[0x103883a00, BaselineFunctionCall]
+
+ EkILzr is the CodeBlockHash. 0x103883a00 is the CodeBlock's address in memory. The other
+ part is self-explanatory.
+
+ Finally, this new notion of CodeBlockHash is available for other purposes like bisecting
+ breakage. As such CodeBlockHash has all of the comparison operator overloads. When
+ bisecting in DFGDriver.cpp, you can now say things like:
+
+ if (codeBlock->hash() < CodeBlockHash("CAAAAA"))
+ return false;
+
+ And yes, CAAAAA is near the median hash, and the largest one is smaller than E99999. Such
+ is life when you use base 62 to encode a 32-bit number.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CallLinkInfo.h:
+ (CallLinkInfo):
+ (JSC::CallLinkInfo::specializationKind):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::hash):
+ (JSC):
+ (JSC::CodeBlock::dumpAssumingJITType):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::dumpBytecode):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::resetStubInternal):
+ (JSC::CodeBlock::reoptimize):
+ (JSC::ProgramCodeBlock::jettison):
+ (JSC::EvalCodeBlock::jettison):
+ (JSC::FunctionCodeBlock::jettison):
+ (JSC::CodeBlock::shouldOptimizeNow):
+ (JSC::CodeBlock::tallyFrequentExitSites):
+ (JSC::CodeBlock::dumpValueProfiles):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::specializationKind):
+ (CodeBlock):
+ (JSC::CodeBlock::getJITType):
+ * bytecode/CodeBlockHash.cpp: Added.
+ (JSC):
+ (JSC::CodeBlockHash::CodeBlockHash):
+ (JSC::CodeBlockHash::dump):
+ * bytecode/CodeBlockHash.h: Added.
+ (JSC):
+ (CodeBlockHash):
+ (JSC::CodeBlockHash::CodeBlockHash):
+ (JSC::CodeBlockHash::hash):
+ (JSC::CodeBlockHash::operator==):
+ (JSC::CodeBlockHash::operator!=):
+ (JSC::CodeBlockHash::operator<):
+ (JSC::CodeBlockHash::operator>):
+ (JSC::CodeBlockHash::operator<=):
+ (JSC::CodeBlockHash::operator>=):
+ * bytecode/CodeBlockWithJITType.h: Added.
+ (JSC):
+ (CodeBlockWithJITType):
+ (JSC::CodeBlockWithJITType::CodeBlockWithJITType):
+ (JSC::CodeBlockWithJITType::dump):
+ * bytecode/CodeOrigin.cpp: Added.
+ (JSC):
+ (JSC::CodeOrigin::inlineDepthForCallFrame):
+ (JSC::CodeOrigin::inlineDepth):
+ (JSC::CodeOrigin::inlineStack):
+ (JSC::InlineCallFrame::hash):
+ * bytecode/CodeOrigin.h:
+ (InlineCallFrame):
+ (JSC::InlineCallFrame::specializationKind):
+ (JSC):
+ * bytecode/CodeType.cpp: Added.
+ (WTF):
+ (WTF::printInternal):
+ * bytecode/CodeType.h:
+ (WTF):
+ * bytecode/ExecutionCounter.cpp:
+ (JSC::ExecutionCounter::dump):
+ * bytecode/ExecutionCounter.h:
+ (ExecutionCounter):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dump):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::generateProtoChainAccessStub):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDList):
+ (JSC::DFG::emitPutReplaceStub):
+ (JSC::DFG::emitPutTransitionStub):
+ (JSC::DFG::dfgLinkClosureCall):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpCallFrame):
+ * jit/JITCode.cpp: Added.
+ (WTF):
+ (WTF::printInternal):
+ * jit/JITCode.h:
+ (JSC::JITCode::jitType):
+ (WTF):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dump):
+ (JSC::JITDisassembler::dumpForInstructions):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompileGetByVal):
+ (JSC::JIT::privateCompilePutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/CodeSpecializationKind.cpp: Added.
+ (WTF):
+ (WTF::printInternal):
+ * runtime/CodeSpecializationKind.h:
+ (JSC::specializationFromIsCall):
+ (JSC):
+ (JSC::specializationFromIsConstruct):
+ (WTF):
+ * runtime/Executable.cpp:
+ (JSC::ExecutableBase::hashFor):
+ (JSC):
+ (JSC::NativeExecutable::hashFor):
+ (JSC::ScriptExecutable::hashFor):
+ * runtime/Executable.h:
+ (ExecutableBase):
+ (NativeExecutable):
+ (ScriptExecutable):
+ (JSC::ScriptExecutable::source):
+
+2012-11-29 Michael Saboff <msaboff@apple.com>
+
+ Speculative Windows build fix after r136086.
+
+ Unreviewed build fix.
+
+ Suspect that ?setDumpsGeneratedCode@BytecodeGenerator@JSC@@SAX_N@Z needs to be removed from Windows
+ export list since the symbol was removed in r136086.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-11-28 Filip Pizlo <fpizlo@apple.com>
+
+ SpeculatedType dumping should not use the static char buffer[thingy] idiom
+ https://bugs.webkit.org/show_bug.cgi?id=103584
+
+ Reviewed by Michael Saboff.
+
+ Changed SpeculatedType to be "dumpable" by saying things like:
+
+ dataLog("thingy = ", SpeculationDump(thingy))
+
+ Removed the old stringification functions, and changed all code that referred to them
+ to use the new dataLog()/print() style.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/SpeculatedType.cpp:
+ (JSC::dumpSpeculation):
+ (JSC::speculationToAbbreviatedString):
+ (JSC::dumpSpeculationAbbreviated):
+ * bytecode/SpeculatedType.h:
+ * bytecode/ValueProfile.h:
+ (JSC::ValueProfileBase::dump):
+ * bytecode/VirtualRegister.h:
+ (WTF::printInternal):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::dump):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
+ (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ (JSC::DFG::Graph::predictArgumentTypes):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * dfg/DFGStructureAbstractValue.h:
+ * dfg/DFGVariableAccessDataDump.cpp: Added.
+ (JSC::DFG::VariableAccessDataDump::VariableAccessDataDump):
+ (JSC::DFG::VariableAccessDataDump::dump):
+ * dfg/DFGVariableAccessDataDump.h: Added.
+ (VariableAccessDataDump):
+
+2012-11-28 Michael Saboff <msaboff@apple.com>
+
+ Change Bytecompiler s_dumpsGeneratedCode to an Options value
+ https://bugs.webkit.org/show_bug.cgi?id=103588
+
+ Reviewed by Filip Pizlo.
+
+ Moved the control of dumping bytecodes to Options::dumpGeneratedBytecodes.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecompiler/BytecodeGenerator.cpp:
+ * bytecompiler/BytecodeGenerator.h:
+ * jsc.cpp:
+ (runWithScripts):
+ * runtime/Options.h:
+
+2012-11-28 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Copying phase should use work lists
+ https://bugs.webkit.org/show_bug.cgi?id=101390
+
+ Reviewed by Filip Pizlo.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::BlockAllocator):
+ * heap/BlockAllocator.h: New RegionSet for CopyWorkListSegments.
+ (BlockAllocator):
+ (JSC::CopyWorkListSegment):
+ * heap/CopiedBlock.h: Added a per-block CopyWorkList to keep track of the JSCells that need to be revisited during the copying
+ phase to copy their backing stores.
+ (CopiedBlock):
+ (JSC::CopiedBlock::CopiedBlock):
+ (JSC::CopiedBlock::didSurviveGC):
+ (JSC::CopiedBlock::didEvacuateBytes): There is now a one-to-one relationship between GCThreads and the CopiedBlocks they're
+ responsible for evacuating, we no longer need any of that fancy compare and swap stuff.
+ (JSC::CopiedBlock::pin):
+ (JSC::CopiedBlock::hasWorkList):
+ (JSC::CopiedBlock::workList):
+ * heap/CopiedBlockInlines.h: Added.
+ (JSC::CopiedBlock::reportLiveBytes): Since we now have to grab a SpinLock to perform operations on the CopyWorkList during marking,
+ we don't need to do any of that fancy compare and swap stuff we were doing for tracking live bytes.
+ * heap/CopiedSpace.h:
+ (CopiedSpace):
+ * heap/CopiedSpaceInlines.h:
+ (JSC::CopiedSpace::pin):
+ * heap/CopyVisitor.cpp:
+ (JSC::CopyVisitor::copyFromShared): We now iterate over a range of CopiedBlocks rather than MarkedBlocks and revisit the cells in those
+ blocks' CopyWorkLists.
+ * heap/CopyVisitor.h:
+ (CopyVisitor):
+ * heap/CopyVisitorInlines.h:
+ (JSC::CopyVisitor::visitCell): The function responsible for calling the correct copyBackingStore() function for each JSCell from
+ a CopiedBlock's CopyWorkList.
+ (JSC::CopyVisitor::didCopy): We no longer need to check if the block is empty here because we know exactly when we're done
+ evacuating a CopiedBlock, which is when we've gone through all of the CopiedBlock's CopyWorkList.
+ * heap/CopyWorkList.h: Added.
+ (CopyWorkListSegment): Individual chunk of a CopyWorkList that is allocated from the BlockAllocator.
+ (JSC::CopyWorkListSegment::create):
+ (JSC::CopyWorkListSegment::size):
+ (JSC::CopyWorkListSegment::isFull):
+ (JSC::CopyWorkListSegment::get):
+ (JSC::CopyWorkListSegment::append):
+ (JSC::CopyWorkListSegment::CopyWorkListSegment):
+ (JSC::CopyWorkListSegment::data):
+ (JSC::CopyWorkListSegment::endOfBlock):
+ (CopyWorkListIterator): Responsible for giving CopyVisitors a contiguous notion of access across the separate CopyWorkListSegments
+ that make up each CopyWorkList.
+ (JSC::CopyWorkListIterator::get):
+ (JSC::CopyWorkListIterator::operator*):
+ (JSC::CopyWorkListIterator::operator->):
+ (JSC::CopyWorkListIterator::operator++):
+ (JSC::CopyWorkListIterator::operator==):
+ (JSC::CopyWorkListIterator::operator!=):
+ (JSC::CopyWorkListIterator::CopyWorkListIterator):
+ (CopyWorkList): Data structure that keeps track of the JSCells that need copying in a particular CopiedBlock.
+ (JSC::CopyWorkList::CopyWorkList):
+ (JSC::CopyWorkList::~CopyWorkList):
+ (JSC::CopyWorkList::append):
+ (JSC::CopyWorkList::begin):
+ (JSC::CopyWorkList::end):
+ * heap/GCThreadSharedData.cpp:
+ (JSC::GCThreadSharedData::GCThreadSharedData): We no longer use the m_blockSnapshot from the Heap during the copying phase.
+ (JSC::GCThreadSharedData::didStartCopying): We now copy the set of all blocks in the CopiedSpace to a separate vector for
+ iterating over during the copying phase since the set stored in the CopiedSpace will change as blocks are evacuated and
+ recycled throughout the copying phase.
+ * heap/GCThreadSharedData.h:
+ (GCThreadSharedData):
+ * heap/Heap.h:
+ (Heap):
+ * heap/SlotVisitor.h: We now need to know the object who is being marked that has a backing store so that we can store it
+ in a CopyWorkList to revisit later during the copying phase.
+ * heap/SlotVisitorInlines.h:
+ (JSC::SlotVisitor::copyLater):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::visitButterfly):
+
+2012-11-28 Filip Pizlo <fpizlo@apple.com>
+
+ Disassembly methods should be able to disassemble to any PrintStream& rather than always using WTF::dataFile()
+ https://bugs.webkit.org/show_bug.cgi?id=103492
+
+ Reviewed by Mark Hahnenberg.
+
+ Switched disassembly code to use PrintStream&, and to use print() rather than printf().
+
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dump):
+ (DFG):
+ (JSC::DFG::Disassembler::dumpDisassembly):
+ * dfg/DFGDisassembler.h:
+ (Disassembler):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::printWhiteSpace):
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ (JSC::DFG::Graph::printNodeWhiteSpace):
+ (JSC::DFG::Graph::dump):
+ (DFG):
+ (JSC::DFG::Graph::dumpBlockHeader):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dump):
+ (JSC::JITDisassembler::dumpForInstructions):
+ (JSC::JITDisassembler::dumpDisassembly):
+ * jit/JITDisassembler.h:
+ (JITDisassembler):
+
+2012-11-28 Filip Pizlo <fpizlo@apple.com>
+
+ It should be possible to say dataLog("count = ", count, "\n") instead of dataLogF("count = %d\n", count)
+ https://bugs.webkit.org/show_bug.cgi?id=103009
+
+ Reviewed by Michael Saboff.
+
+ Instead of converting all of JSC to use the new dataLog()/print() methods, I just changed
+ one place: dumping of abstract values. This is mainly just to ensure that the code I
+ added to WTF is actually doing things.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::dump):
+ (WTF):
+ (WTF::printInternal):
+ * dfg/DFGStructureAbstractValue.h:
+ (JSC::DFG::StructureAbstractValue::dump):
+ (WTF):
+ (WTF::printInternal):
+
+2012-11-28 Oliver Hunt <oliver@apple.com>
+
+ Make source cache include more information about the function extent.
+ https://bugs.webkit.org/show_bug.cgi?id=103552
+
+ Reviewed by Gavin Barraclough.
+
+ Add a bit more information to the source cache.
+
+ * parser/Parser.cpp:
+ (JSC::::parseFunctionInfo):
+ Store the function start offset
+ * parser/SourceProviderCacheItem.h:
+ (JSC::SourceProviderCacheItem::SourceProviderCacheItem):
+ (SourceProviderCacheItem):
+ Add additional field for the start of the real function string, and re-arrange
+ fields to avoid growing the struct.
+
+2012-11-27 Filip Pizlo <fpizlo@apple.com>
+
+ Convert some remaining uses of FILE* to PrintStream&.
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * bytecode/ValueProfile.h:
+ (JSC::ValueProfileBase::dump):
+ * bytecode/ValueRecovery.h:
+ (JSC::ValueRecovery::dump):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::dumpChildren):
+
+2012-11-27 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation in JSValue.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/JSValue.h:
+
+2012-11-26 Filip Pizlo <fpizlo@apple.com>
+
+ DFG SetLocal should use forwardSpeculationCheck instead of its own half-baked version of same
+ https://bugs.webkit.org/show_bug.cgi?id=103353
+
+ Reviewed by Oliver Hunt and Gavin Barraclough.
+
+ Made it possible to use forward speculations for most of the operand classes. Changed the conditional
+ direction parameter from being 'bool isForward' to an enum (SpeculationDirection). Changed SetLocal
+ to use forward speculations and got rid of its half-baked version of same.
+
+ Also added the ability to force the DFG's disassembler to dump all nodes, even ones that are dead.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dump):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+ (JSC::DFG::SpeculativeJIT::fillStorage):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateIntegerOperand::gpr):
+ (SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateDoubleOperand::fpr):
+ (SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::gpr):
+ (SpeculateCellOperand):
+ (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
+ (JSC::DFG::SpeculateBooleanOperand::gpr):
+ (SpeculateBooleanOperand):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/Options.h:
+ (JSC):
+
+2012-11-26 Daniel Bates <dbates@webkit.org>
+
+ Substitute "allSeparators8Bit" for "allSeperators8Bit" in JSC::jsSpliceSubstringsWithSeparators()
+ <https://bugs.webkit.org/show_bug.cgi?id=103303>
+
+ Reviewed by Simon Fraser.
+
+ Fix misspelled word, "Seperators" [sic], in a local variable name in JSC::jsSpliceSubstringsWithSeparators().
+
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstringsWithSeparators):
+
+2012-11-26 Daniel Bates <dbates@webkit.org>
+
+ JavaScript fails to handle String.replace() with large replacement string
+ https://bugs.webkit.org/show_bug.cgi?id=102956
+ <rdar://problem/12738012>
+
+ Reviewed by Oliver Hunt.
+
+ Fix an issue where we didn't check for overflow when computing the length
+ of the result of String.replace() with a large replacement string.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstringsWithSeparators):
+
+2012-11-26 Zeno Albisser <zeno@webkit.org>
+
+ [Qt] Fix the LLInt build on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=97587
+
+ Reviewed by Simon Hausmann.
+
+ * DerivedSources.pri:
+ * JavaScriptCore.pro:
+
+2012-11-26 Oliver Hunt <oliver@apple.com>
+
+ 32-bit build fix. Move the method decalration outside of the X86_64 only section.
+
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::shouldConsiderBlinding):
+
+2012-11-26 Oliver Hunt <oliver@apple.com>
+
+ Don't blind all the things.
+ https://bugs.webkit.org/show_bug.cgi?id=102572
+
+ Reviewed by Gavin Barraclough.
+
+ No longer blind all the constants in the instruction stream. We use a
+ simple non-deterministic filter to avoid blinding everything. Also modified
+ the basic integer blinding logic to avoid blinding small negative values.
+
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::shouldConsiderBlinding):
+ (JSC::MacroAssembler::shouldBlind):
+
+2012-11-26 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ JSObject::copyButterfly doesn't handle undecided indexing types correctly
+ https://bugs.webkit.org/show_bug.cgi?id=102573
+
+ Reviewed by Filip Pizlo.
+
+ We don't do any copying into the newly allocated vector and we don't zero-initialize CopiedBlocks
+ during the copying phase, so we end up with uninitialized memory in arrays which have undecided indexing
+ types. We should just do the actual memcpy from the old block to the new one.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly): Just do the same thing that we do for other contiguous indexing types.
+
+2012-11-26 Julien BRIANCEAU <jbrianceau@nds.com>
+
+ [sh4] JavaScriptCore JIT build is broken since r135330
+ Add missing implementation for sh4 arch.
+ https://bugs.webkit.org/show_bug.cgi?id=103145
+
+ Reviewed by Oliver Hunt.
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::canJumpReplacePatchableBranchPtrWithPatch):
+ (MacroAssemblerSH4):
+ (JSC::MacroAssemblerSH4::startOfBranchPtrWithPatchOnRegister):
+ (JSC::MacroAssemblerSH4::revertJumpReplacementToBranchPtrWithPatch):
+ (JSC::MacroAssemblerSH4::startOfPatchableBranchPtrWithPatchOnAddress):
+ (JSC::MacroAssemblerSH4::revertJumpReplacementToPatchableBranchPtrWithPatch):
+ * assembler/SH4Assembler.h:
+ (JSC::SH4Assembler::revertJump):
+ (SH4Assembler):
+ (JSC::SH4Assembler::printInstr):
+
+2012-11-26 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Use load64 instead of loadPtr to load a JSValue on JSVALUE64 platforms
+ https://bugs.webkit.org/show_bug.cgi?id=100909
+
+ Reviewed by Brent Fulgham.
+
+ This is a (trivial) fix after r132701.
+
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+
+2012-11-26 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ [Qt][ARM] REGRESSION(r130826): It made 33 JSC test and 466 layout tests crash
+ https://bugs.webkit.org/show_bug.cgi?id=98857
+
+ Reviewed by Zoltan Herczeg.
+
+ Implement a new version of patchableBranch32 to fix crashing JSC
+ tests.
+
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::patchableBranch32):
+ (MacroAssemblerARM):
+
+2012-11-21 Filip Pizlo <fpizlo@apple.com>
+
+ Any function that can log things should be able to easily log them to a memory buffer as well
+ https://bugs.webkit.org/show_bug.cgi?id=103000
+
+ Reviewed by Sam Weinig.
+
+ Change all users of WTF::dataFile() to expect a PrintStream& rather than a FILE*.
+
+ * bytecode/Operands.h:
+ (JSC::OperandValueTraits::dump):
+ (JSC::dumpOperands):
+ (JSC):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::dump):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::dump):
+ * dfg/DFGCommon.h:
+ (JSC::DFG::NodeIndexTraits::dump):
+ * dfg/DFGStructureAbstractValue.h:
+ (JSC::DFG::StructureAbstractValue::dump):
+ * dfg/DFGVariableEvent.cpp:
+ (JSC::DFG::VariableEvent::dump):
+ (JSC::DFG::VariableEvent::dumpFillInfo):
+ (JSC::DFG::VariableEvent::dumpSpillInfo):
+ * dfg/DFGVariableEvent.h:
+ (VariableEvent):
+ * disassembler/Disassembler.h:
+ (JSC):
+ (JSC::tryToDisassemble):
+ * disassembler/UDis86Disassembler.cpp:
+ (JSC::tryToDisassemble):
+
+2012-11-23 Alexis Menard <alexis@webkit.org>
+
+ [CSS3 Backgrounds and Borders] Implement new CSS3 background-position parsing.
+ https://bugs.webkit.org/show_bug.cgi?id=102104
+
+ Reviewed by Julien Chaffraix.
+
+ Protect the new feature behind a feature flag.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-11-23 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ Fix the ARM traditional build after r135330
+ https://bugs.webkit.org/show_bug.cgi?id=102871
+
+ Reviewed by Zoltan Herczeg.
+
+ Added missing functionality to traditional ARM architecture.
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::revertJump):
+ (ARMAssembler):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::startOfPatchableBranchPtrWithPatchOnAddress):
+ (JSC::MacroAssemblerARM::startOfBranchPtrWithPatchOnRegister):
+ (MacroAssemblerARM):
+ (JSC::MacroAssemblerARM::revertJumpReplacementToBranchPtrWithPatch):
+
+2012-11-16 Yury Semikhatsky <yurys@chromium.org>
+
+ Memory instrumentation: extract MemoryObjectInfo declaration into a separate file
+ https://bugs.webkit.org/show_bug.cgi?id=102510
+
+ Reviewed by Pavel Feldman.
+
+ Added new symbols for the methods that have moved into .../wtf/MemoryInstrumentation.cpp
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-11-23 Julien BRIANCEAU <jbrianceau@nds.com>
+
+ [sh4] JavaScriptCore JIT build is broken since r130839
+ Add missing implementation for sh4 arch.
+ https://bugs.webkit.org/show_bug.cgi?id=101479
+
+ Reviewed by Filip Pizlo.
+
+ * assembler/MacroAssemblerSH4.h:
+ (JSC::MacroAssemblerSH4::load8Signed):
+ (MacroAssemblerSH4):
+ (JSC::MacroAssemblerSH4::load16Signed):
+ (JSC::MacroAssemblerSH4::store8):
+ (JSC::MacroAssemblerSH4::store16):
+ (JSC::MacroAssemblerSH4::moveDoubleToInts):
+ (JSC::MacroAssemblerSH4::moveIntsToDouble):
+ (JSC::MacroAssemblerSH4::loadFloat):
+ (JSC::MacroAssemblerSH4::loadDouble):
+ (JSC::MacroAssemblerSH4::storeFloat):
+ (JSC::MacroAssemblerSH4::storeDouble):
+ (JSC::MacroAssemblerSH4::addDouble):
+ (JSC::MacroAssemblerSH4::convertFloatToDouble):
+ (JSC::MacroAssemblerSH4::convertDoubleToFloat):
+ (JSC::MacroAssemblerSH4::urshift32):
+ * assembler/SH4Assembler.h:
+ (JSC::SH4Assembler::sublRegReg):
+ (JSC::SH4Assembler::subvlRegReg):
+ (JSC::SH4Assembler::floatfpulfrn):
+ (JSC::SH4Assembler::fldsfpul):
+ (JSC::SH4Assembler::fstsfpul):
+ (JSC::SH4Assembler::dcnvsd):
+ (SH4Assembler):
+ (JSC::SH4Assembler::movbRegMem):
+ (JSC::SH4Assembler::sizeOfConstantPool):
+ (JSC::SH4Assembler::linkJump):
+ (JSC::SH4Assembler::printInstr):
+ (JSC::SH4Assembler::printBlockInstr):
+
+2012-11-22 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ Fix the MIPS build after r135330
+ https://bugs.webkit.org/show_bug.cgi?id=102872
+
+ Reviewed by Gavin Barraclough.
+
+ Revert/replace functions added to MIPS port.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::revertJumpToMove):
+ (MIPSAssembler):
+ (JSC::MIPSAssembler::replaceWithJump):
+ * assembler/MacroAssemblerMIPS.h:
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::startOfBranchPtrWithPatchOnRegister):
+ (JSC::MacroAssemblerMIPS::revertJumpReplacementToBranchPtrWithPatch):
+ (JSC::MacroAssemblerMIPS::startOfPatchableBranchPtrWithPatchOnAddress):
+
+2012-11-21 Filip Pizlo <fpizlo@apple.com>
+
+ Rename dataLog() and dataLogV() to dataLogF() and dataLogFV()
+ https://bugs.webkit.org/show_bug.cgi?id=103001
+
+ Rubber stamped by Dan Bernstein.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * assembler/LinkBuffer.cpp:
+ (JSC::LinkBuffer::finalizeCodeWithDisassembly):
+ (JSC::LinkBuffer::dumpLinkStatistics):
+ (JSC::LinkBuffer::dumpCode):
+ * assembler/LinkBuffer.h:
+ (JSC):
+ * assembler/SH4Assembler.h:
+ (JSC::SH4Assembler::vprintfStdoutInstr):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecodeCommentAndNewLine):
+ (JSC::CodeBlock::printUnaryOp):
+ (JSC::CodeBlock::printBinaryOp):
+ (JSC::CodeBlock::printConditionalJump):
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::dumpStructure):
+ (JSC::dumpChain):
+ (JSC::CodeBlock::printGetByIdCacheStatus):
+ (JSC::CodeBlock::printCallOp):
+ (JSC::CodeBlock::printPutByIdOp):
+ (JSC::CodeBlock::printStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::dumpStatistics):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::resetStubInternal):
+ (JSC::CodeBlock::reoptimize):
+ (JSC::ProgramCodeBlock::jettison):
+ (JSC::EvalCodeBlock::jettison):
+ (JSC::FunctionCodeBlock::jettison):
+ (JSC::CodeBlock::shouldOptimizeNow):
+ (JSC::CodeBlock::tallyFrequentExitSites):
+ (JSC::CodeBlock::dumpValueProfiles):
+ * bytecode/Opcode.cpp:
+ (JSC::OpcodeStats::~OpcodeStats):
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingFlags::stop):
+ (JSC::SamplingRegion::dumpInternal):
+ (JSC::SamplingTool::dump):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ (JSC::DFG::AbstractState::endBasicBlock):
+ (JSC::DFG::AbstractState::mergeStateAtTail):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::dump):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
+ (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
+ (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
+ (JSC::DFG::ByteCodeParser::makeSafe):
+ (JSC::DFG::ByteCodeParser::makeDivSafe):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::processPhiStack):
+ (JSC::DFG::ByteCodeParser::linkBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::parseCodeBlock):
+ (JSC::DFG::ByteCodeParser::parse):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ (JSC::DFG::CFAPhase::performForwardCFA):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal):
+ (JSC::DFG::CFGSimplificationPhase::fixPhis):
+ (JSC::DFG::CFGSimplificationPhase::fixJettisonedPredecessors):
+ (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::endIndexForPureCSE):
+ (JSC::DFG::CSEPhase::setReplacement):
+ (JSC::DFG::CSEPhase::eliminate):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::debugFail):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dump):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::fixDoubleEdge):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::printWhiteSpace):
+ (JSC::DFG::Graph::dumpCodeOrigin):
+ (JSC::DFG::Graph::dump):
+ (JSC::DFG::Graph::dumpBlockHeader):
+ (JSC::DFG::Graph::predictArgumentTypes):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ * dfg/DFGOSREntry.cpp:
+ (JSC::DFG::prepareOSREntry):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGPhase.cpp:
+ (JSC::DFG::Phase::beginPhase):
+ * dfg/DFGPhase.h:
+ (JSC::DFG::runAndLog):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::propagateForward):
+ (JSC::DFG::PredictionPropagationPhase::propagateBackward):
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGRegisterBank.h:
+ (JSC::DFG::RegisterBank::dump):
+ * dfg/DFGScoreBoard.h:
+ (JSC::DFG::ScoreBoard::use):
+ (JSC::DFG::ScoreBoard::dump):
+ * dfg/DFGSlowPathGenerator.h:
+ (JSC::DFG::SlowPathGenerator::generate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection):
+ (JSC::DFG::SpeculativeJIT::runSlowPathGenerators):
+ (JSC::DFG::SpeculativeJIT::dump):
+ (JSC::DFG::SpeculativeJIT::checkConsistency):
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * dfg/DFGValidate.cpp:
+ (Validate):
+ (JSC::DFG::Validate::reportValidationContext):
+ (JSC::DFG::Validate::dumpData):
+ (JSC::DFG::Validate::dumpGraphIfAppropriate):
+ * dfg/DFGVariableEventStream.cpp:
+ (JSC::DFG::VariableEventStream::logEvent):
+ (JSC::DFG::VariableEventStream::reconstruct):
+ * dfg/DFGVirtualRegisterAllocationPhase.cpp:
+ (JSC::DFG::VirtualRegisterAllocationPhase::run):
+ * heap/Heap.cpp:
+ * heap/HeapStatistics.cpp:
+ (JSC::HeapStatistics::logStatistics):
+ (JSC::HeapStatistics::showObjectStatistics):
+ * heap/MarkStack.h:
+ * heap/MarkedBlock.h:
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::validate):
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::dumpCaller):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpRegisters):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dump):
+ (JSC::JITDisassembler::dumpForInstructions):
+ * jit/JITStubRoutine.h:
+ (JSC):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JumpReplacementWatchpoint.cpp:
+ (JSC::JumpReplacementWatchpoint::fireInternal):
+ * llint/LLIntExceptions.cpp:
+ (JSC::LLInt::interpreterThrowInCaller):
+ (JSC::LLInt::returnToThrow):
+ (JSC::LLInt::callToThrow):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::llint_trace_operand):
+ (JSC::LLInt::llint_trace_value):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::traceFunctionPrologue):
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ (JSC::LLInt::entryOSR):
+ (JSC::LLInt::handleHostCall):
+ (JSC::LLInt::setUpCall):
+ * profiler/Profile.cpp:
+ (JSC::Profile::debugPrintData):
+ (JSC::Profile::debugPrintDataSampleStyle):
+ * profiler/ProfileNode.cpp:
+ (JSC::ProfileNode::debugPrintData):
+ (JSC::ProfileNode::debugPrintDataSampleStyle):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::dumpRegExpTrace):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::matchCompareWithInterpreter):
+ * runtime/SamplingCounter.cpp:
+ (JSC::AbstractSamplingCounter::dump):
+ * runtime/Structure.cpp:
+ (JSC::Structure::dumpStatistics):
+ (JSC::PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger):
+ * tools/CodeProfile.cpp:
+ (JSC::CodeProfile::report):
+ * tools/ProfileTreeNode.h:
+ (JSC::ProfileTreeNode::dumpInternal):
+ * yarr/YarrInterpreter.cpp:
+ (JSC::Yarr::ByteCompiler::dumpDisjunction):
+
+2012-11-21 Filip Pizlo <fpizlo@apple.com>
+
+ It should be possible to say disassemble(stuff) instead of having to say if (!tryToDisassemble(stuff)) dataLog("I failed")
+ https://bugs.webkit.org/show_bug.cgi?id=103010
+
+ Reviewed by Anders Carlsson.
+
+ You can still say tryToDisassemble(), which will tell you if it failed; you can then
+ decide what to do instead. But it's better to say disassemble(), which will just print
+ the instruction ranges if tryToDisassemble() failed. This is particularly appropriate
+ since that's what all previous users of tryToDisassemble() would have done in some
+ form or another.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/LinkBuffer.cpp:
+ (JSC::LinkBuffer::finalizeCodeWithDisassembly):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dumpDisassembly):
+ * disassembler/Disassembler.cpp: Added.
+ (JSC):
+ (JSC::disassemble):
+ * disassembler/Disassembler.h:
+ (JSC):
+ * jit/JITDisassembler.cpp:
+ (JSC::JITDisassembler::dumpDisassembly):
+
+2012-11-21 Filip Pizlo <fpizlo@apple.com>
+
+ dumpOperands() claims that it needs a non-const Operands& when that is completely false
+ https://bugs.webkit.org/show_bug.cgi?id=103005
+
+ Reviewed by Eric Carlson.
+
+ * bytecode/Operands.h:
+ (JSC::dumpOperands):
+ (JSC):
+
+2012-11-20 Filip Pizlo <fpizlo@apple.com>
+
+ Baseline JIT's disassembly should be just as pretty as the DFG's
+ https://bugs.webkit.org/show_bug.cgi?id=102873
+
+ Reviewed by Sam Weinig.
+
+ Integrated the CodeBlock's bytecode dumper with the JIT's disassembler. Also fixed
+ some type goof-ups (instructions are not in a Vector<Instruction> so using a Vector
+ iterator makes no sense) and stream-lined some things (you don't actually need a
+ full-fledged ExecState* to dump bytecode).
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printUnaryOp):
+ (JSC::CodeBlock::printBinaryOp):
+ (JSC::CodeBlock::printConditionalJump):
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::CodeBlock::printCallOp):
+ (JSC::CodeBlock::printPutByIdOp):
+ (JSC::CodeBlock::dump):
+ (JSC):
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpCallFrame):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITDisassembler.cpp: Added.
+ (JSC):
+ (JSC::JITDisassembler::JITDisassembler):
+ (JSC::JITDisassembler::~JITDisassembler):
+ (JSC::JITDisassembler::dump):
+ (JSC::JITDisassembler::dumpForInstructions):
+ (JSC::JITDisassembler::dumpDisassembly):
+ * jit/JITDisassembler.h: Added.
+ (JSC):
+ (JITDisassembler):
+ (JSC::JITDisassembler::setStartOfCode):
+ (JSC::JITDisassembler::setForBytecodeMainPath):
+ (JSC::JITDisassembler::setForBytecodeSlowPath):
+ (JSC::JITDisassembler::setEndOfSlowPath):
+ (JSC::JITDisassembler::setEndOfCode):
+
+2012-11-21 Daniel Bates <dbates@webkit.org>
+
+ JavaScript fails to concatenate large strings
+ <https://bugs.webkit.org/show_bug.cgi?id=102963>
+
+ Reviewed by Michael Saboff.
+
+ Fixes an issue where we inadvertently didn't check the length of
+ a JavaScript string for overflow.
+
+ * runtime/Operations.h:
+ (JSC::jsString):
+ (JSC::jsStringFromArguments):
+
+2012-11-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should be able to cache closure calls (part 2/2)
+ https://bugs.webkit.org/show_bug.cgi?id=102662
+
+ Reviewed by Gavin Barraclough.
+
+ Added caching of calls where the JSFunction* varies, but the Structure* and ExecutableBase*
+ stay the same. This is accomplished by replacing the branch that compares against a constant
+ JSFunction* with a jump to a closure call stub. The closure call stub contains a fast path,
+ and jumps slow directly to the virtual call thunk.
+
+ Looks like a 1% win on V8v7.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CallLinkInfo.cpp:
+ (JSC::CallLinkInfo::unlink):
+ * bytecode/CallLinkInfo.h:
+ (CallLinkInfo):
+ (JSC::CallLinkInfo::isLinked):
+ (JSC::getCallLinkInfoBytecodeIndex):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC):
+ (JSC::CodeBlock::findClosureCallForReturnPC):
+ (JSC::CodeBlock::bytecodeOffset):
+ (JSC::CodeBlock::codeOriginForReturn):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::getCallLinkInfo):
+ (CodeBlock):
+ (JSC::CodeBlock::isIncomingCallAlreadyLinked):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::link):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::addJSCall):
+ (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
+ (JSCallRecord):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::linkSlowFor):
+ (DFG):
+ (JSC::DFG::dfgLinkFor):
+ (JSC::DFG::dfgLinkSlowFor):
+ (JSC::DFG::dfgLinkClosureCall):
+ * dfg/DFGRepatch.h:
+ (DFG):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ * dfg/DFGThunks.cpp:
+ (DFG):
+ (JSC::DFG::linkClosureCallThunkGenerator):
+ * dfg/DFGThunks.h:
+ (DFG):
+ * heap/Heap.h:
+ (Heap):
+ (JSC::Heap::jitStubRoutines):
+ * heap/JITStubRoutineSet.h:
+ (JSC::JITStubRoutineSet::size):
+ (JSC::JITStubRoutineSet::at):
+ (JITStubRoutineSet):
+ * jit/ClosureCallStubRoutine.cpp: Added.
+ (JSC):
+ (JSC::ClosureCallStubRoutine::ClosureCallStubRoutine):
+ (JSC::ClosureCallStubRoutine::~ClosureCallStubRoutine):
+ (JSC::ClosureCallStubRoutine::markRequiredObjectsInternal):
+ * jit/ClosureCallStubRoutine.h: Added.
+ (JSC):
+ (ClosureCallStubRoutine):
+ (JSC::ClosureCallStubRoutine::structure):
+ (JSC::ClosureCallStubRoutine::executable):
+ (JSC::ClosureCallStubRoutine::codeOrigin):
+ * jit/GCAwareJITStubRoutine.cpp:
+ (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine):
+ * jit/GCAwareJITStubRoutine.h:
+ (GCAwareJITStubRoutine):
+ (JSC::GCAwareJITStubRoutine::isClosureCall):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+
+2012-11-20 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should be able to cache closure calls (part 1/2)
+ https://bugs.webkit.org/show_bug.cgi?id=102662
+
+ Reviewed by Gavin Barraclough.
+
+ Add ability to revert a jump replacement back to
+ branchPtrWithPatch(Condition, RegisterID, TrustedImmPtr). This is meant to be
+ a mandatory piece of functionality for all assemblers. I also renamed some of
+ the functions for reverting jump replacements back to
+ patchableBranchPtrWithPatch(Condition, Address, TrustedImmPtr), so as to avoid
+ confusion.
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::BadReg):
+ (ARMv7Assembler):
+ (JSC::ARMv7Assembler::revertJumpTo_movT3):
+ * assembler/LinkBuffer.h:
+ (JSC):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::startOfBranchPtrWithPatchOnRegister):
+ (MacroAssemblerARMv7):
+ (JSC::MacroAssemblerARMv7::revertJumpReplacementToBranchPtrWithPatch):
+ (JSC::MacroAssemblerARMv7::startOfPatchableBranchPtrWithPatchOnAddress):
+ * assembler/MacroAssemblerX86.h:
+ (JSC::MacroAssemblerX86::startOfBranchPtrWithPatchOnRegister):
+ (MacroAssemblerX86):
+ (JSC::MacroAssemblerX86::startOfPatchableBranchPtrWithPatchOnAddress):
+ (JSC::MacroAssemblerX86::revertJumpReplacementToBranchPtrWithPatch):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::startOfBranchPtrWithPatchOnRegister):
+ (JSC::MacroAssemblerX86_64::startOfPatchableBranchPtrWithPatchOnAddress):
+ (MacroAssemblerX86_64):
+ (JSC::MacroAssemblerX86_64::revertJumpReplacementToBranchPtrWithPatch):
+ * assembler/RepatchBuffer.h:
+ (JSC::RepatchBuffer::startOfBranchPtrWithPatchOnRegister):
+ (RepatchBuffer):
+ (JSC::RepatchBuffer::startOfPatchableBranchPtrWithPatchOnAddress):
+ (JSC::RepatchBuffer::revertJumpReplacementToBranchPtrWithPatch):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::revertJumpTo_cmpl_ir_force32):
+ (X86Assembler):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::replaceWithJump):
+ (JSC::DFG::dfgResetGetByID):
+ (JSC::DFG::dfgResetPutByID):
+
+2012-11-20 Yong Li <yoli@rim.com>
+
+ [ARMv7] Neither linkCall() nor linkPointer() should flush code.
+ https://bugs.webkit.org/show_bug.cgi?id=99213
+
+ Reviewed by George Staikos.
+
+ LinkBuffer doesn't need to flush code during linking. It will
+ eventually flush the whole executable. Fixing this gives >%5
+ sunspider boost (on QNX).
+
+ Also make replaceWithLoad() and replaceWithAddressComputation() flush
+ only when necessary.
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::linkCall):
+ (JSC::ARMv7Assembler::linkPointer):
+ (JSC::ARMv7Assembler::relinkCall):
+ (JSC::ARMv7Assembler::repatchInt32):
+ (JSC::ARMv7Assembler::repatchPointer):
+ (JSC::ARMv7Assembler::replaceWithLoad): Flush only after it did write.
+ (JSC::ARMv7Assembler::replaceWithAddressComputation): Flush only after it did write.
+ (JSC::ARMv7Assembler::setInt32):
+ (JSC::ARMv7Assembler::setPointer):
+
+2012-11-19 Filip Pizlo <fpizlo@apple.com>
+
+ Remove support for ARMv7 errata from the jump code
+ https://bugs.webkit.org/show_bug.cgi?id=102759
+
+ Reviewed by Oliver Hunt.
+
+ The jump replacement code was wrong to begin with since it wasn't doing
+ a cache flush on the inserted padding. And, to my knowledge, we don't need
+ this anymore, so this patch removes all errata code from the ARMv7 port.
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::computeJumpType):
+ (JSC::ARMv7Assembler::replaceWithJump):
+ (JSC::ARMv7Assembler::maxJumpReplacementSize):
+ (JSC::ARMv7Assembler::canBeJumpT3):
+ (JSC::ARMv7Assembler::canBeJumpT4):
+
+2012-11-19 Patrick Gansterer <paroga@webkit.org>
+
+ [CMake] Create JavaScriptCore ForwardingHeaders
+ https://bugs.webkit.org/show_bug.cgi?id=92665
+
+ Reviewed by Brent Fulgham.
+
+ When using CMake to build the Windows port, we need
+ to generate the forwarding headers with it too.
+
+ * CMakeLists.txt:
+
+2012-11-19 Kihong Kwon <kihong.kwon@samsung.com>
+
+ Add PROXIMITY_EVENTS feature
+ https://bugs.webkit.org/show_bug.cgi?id=102658
+
+ Reviewed by Kentaro Hara.
+
+ Add PROXIMITY_EVENTS feature to xcode project for JavaScriptCore.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-11-18 Dan Bernstein <mitz@apple.com>
+
+ Try to fix the DFG build after r135099.
+
+ * dfg/DFGCommon.h:
+ (JSC::DFG::shouldShowDisassembly):
+
+2012-11-18 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, build fix for !ENABLE(DFG_JIT).
+
+ * dfg/DFGCommon.h:
+ (JSC::DFG::shouldShowDisassembly):
+ (DFG):
+
+2012-11-18 Filip Pizlo <fpizlo@apple.com>
+
+ JSC should have more logging in structure-related code
+ https://bugs.webkit.org/show_bug.cgi?id=102630
+
+ Reviewed by Simon Fraser.
+
+ - JSValue::description() now tells you if something is a structure, and if so,
+ what kind of structure it is.
+
+ - Jettisoning logic now tells you why things are being jettisoned.
+
+ - It's now possible to turn off GC-triggered jettisoning entirely.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::reoptimize):
+ (JSC::ProgramCodeBlock::jettison):
+ (JSC::EvalCodeBlock::jettison):
+ (JSC::FunctionCodeBlock::jettison):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::shouldImmediatelyAssumeLivenessDuringScan):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::description):
+ * runtime/Options.h:
+ (JSC):
+
+2012-11-18 Filip Pizlo <fpizlo@apple.com>
+
+ DFG constant folding phase should say 'changed = true' whenever it changes the graph
+ https://bugs.webkit.org/show_bug.cgi?id=102550
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2012-11-17 Elliott Sprehn <esprehn@chromium.org>
+
+ Expose JSObject removeDirect and PrivateName to WebCore
+ https://bugs.webkit.org/show_bug.cgi?id=102546
+
+ Reviewed by Geoffrey Garen.
+
+ Export removeDirect for use in WebCore so JSDependentRetained works.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-11-16 Filip Pizlo <fpizlo@apple.com>
+
+ Given a PutById or GetById with a proven structure, the DFG should be able to emit a PutByOffset or GetByOffset instead
+ https://bugs.webkit.org/show_bug.cgi?id=102327
+
+ Reviewed by Mark Hahnenberg.
+
+ If the profiler tells us that a GetById or PutById may be polymorphic but our
+ control flow analysis proves that it isn't, we should trust the control flow
+ analysis over the profiler. This arises in cases where GetById or PutById were
+ inlined: the inlined function may have been called from other places that led
+ to polymorphism, but in the current inlined context, there is no polymorphism.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/GetByIdStatus.cpp:
+ (JSC::GetByIdStatus::computeFor):
+ (JSC):
+ * bytecode/GetByIdStatus.h:
+ (JSC::GetByIdStatus::GetByIdStatus):
+ (GetByIdStatus):
+ * bytecode/PutByIdStatus.cpp:
+ (JSC::PutByIdStatus::computeFor):
+ (JSC):
+ * bytecode/PutByIdStatus.h:
+ (JSC):
+ (JSC::PutByIdStatus::PutByIdStatus):
+ (PutByIdStatus):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::bestProvenStructure):
+ (AbstractValue):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+ (ConstantFoldingPhase):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::convertToGetByOffset):
+ (Node):
+ (JSC::DFG::Node::convertToPutByOffset):
+ (JSC::DFG::Node::hasStorageResult):
+ * runtime/JSGlobalObject.h:
+ (JSC::Structure::prototypeChain):
+ (JSC):
+ (JSC::Structure::isValid):
+ * runtime/Operations.h:
+ (JSC::isPrototypeChainNormalized):
+ (JSC):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::transitionDidInvolveSpecificValue):
+
+2012-11-16 Tony Chang <tony@chromium.org>
+
+ Remove ENABLE_CSS_HIERARCHIES since it's no longer in use
+ https://bugs.webkit.org/show_bug.cgi?id=102554
+
+ Reviewed by Andreas Kling.
+
+ As mentioned in https://bugs.webkit.org/show_bug.cgi?id=79939#c41 ,
+ we're going to revist this feature once additional vendor support is
+ achieved.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-11-16 Patrick Gansterer <paroga@webkit.org>
+
+ Build fix for WinCE after r133688.
+
+ Use numeric_limits<uint32_t>::max() instead of UINT32_MAX.
+
+ * runtime/CodeCache.h:
+ (JSC::CacheMap::CacheMap):
+
+2012-11-15 Filip Pizlo <fpizlo@apple.com>
+
+ ClassInfo.h should have correct indentation.
+
+ Rubber stamped by Mark Hahnenberg.
+
+ ClassInfo.h had some true creativity in its use of whitespace. Some things within
+ the namespace were indented four spaces and others where not. One #define had its
+ contents indented four spaces, while another didn't. I applied the following rule:
+
+ - Non-macro things in the namespace should not be indented (that's our current
+ accepted practice).
+
+ - Macros should never be indented but if they are multi-line then their subsequent
+ bodies should be indented four spaces. I believe that is consistent with what we
+ do elsewhere.
+
+ * runtime/ClassInfo.h:
+ (JSC):
+ (MethodTable):
+ (ClassInfo):
+ (JSC::ClassInfo::propHashTable):
+ (JSC::ClassInfo::isSubClassOf):
+ (JSC::ClassInfo::hasStaticProperties):
+
+2012-11-15 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should copy propagate trivially no-op ConvertThis
+ https://bugs.webkit.org/show_bug.cgi?id=102445
+
+ Reviewed by Oliver Hunt.
+
+ Copy propagation is always a good thing, since it reveals must-alias relationships
+ to the CFA and CSE. This accomplishes copy propagation for ConvertThis by first
+ converting it to an Identity node (which is done by the constant folder since it
+ has access to CFA results) and then performing substitution of references to
+ Identity with references to Identity's child in the CSE.
+
+ I'm not aiming for a big speed-up here; I just think that this will be useful for
+ the work on https://bugs.webkit.org/show_bug.cgi?id=102327.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-11-15 Filip Pizlo <fpizlo@apple.com>
+
+ CallData.h should have correct indentation.
+
+ Rubber stamped by Mark Hahneberg.
+
+ * runtime/CallData.h:
+ (JSC):
+
+2012-11-15 Filip Pizlo <fpizlo@apple.com>
+
+ Remove methodCallDummy since it is not used anymore.
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+
+2012-11-14 Filip Pizlo <fpizlo@apple.com>
+
+ Structure should be able to easily tell if the prototype chain might intercept a store
+ https://bugs.webkit.org/show_bug.cgi?id=102326
+
+ Reviewed by Geoffrey Garen.
+
+ This improves our ability to reason about the correctness of the more optimized
+ prototype chain walk in JSObject::put(), while also making it straight forward to
+ check if the prototype chain will do strange things to a property store by just
+ looking at the structure.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::put):
+ * runtime/Structure.cpp:
+ (JSC::Structure::prototypeChainMayInterceptStoreTo):
+ (JSC):
+ * runtime/Structure.h:
+ (Structure):
+
+2012-11-15 Thiago Marcos P. Santos <thiago.santos@intel.com>
+
+ [CMake] Do not regenerate LLIntAssembly.h on every incremental build
+ https://bugs.webkit.org/show_bug.cgi?id=102248
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Update LLIntAssembly.h's mtime after running asm.rb to make the build
+ system dependency tracking consistent.
+
+ * CMakeLists.txt:
+
+2012-11-15 Thiago Marcos P. Santos <thiago.santos@intel.com>
+
+ Fix compiler warnings about signed/unsigned comparison on i386
+ https://bugs.webkit.org/show_bug.cgi?id=102249
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Add casting to unsigned to shut up gcc warnings. Build was broken on
+ JSVALUE32_64 ports compiling with -Werror.
+
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+
+2012-11-14 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows, WinCairo] Unreviewed build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ Missed one of the exports that was part of the WebKit2.def.
+
+2012-11-14 Brent Fulgham <bfulgham@webkit.org>
+
+ [Windows, WinCairo] Correct build failure.
+ https://bugs.webkit.org/show_bug.cgi?id=102302
+
+ WebCore symbols were mistakenly added to the JavaScriptCore
+ library definition file.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Remove
+ WebCore symbols that were incorrectly added to the export file.
+
+2012-11-14 Mark Lam <mark.lam@apple.com>
+
+ Change JSEventListener::m_jsFunction to be a weak ref.
+ https://bugs.webkit.org/show_bug.cgi?id=101989.
+
+ Reviewed by Geoffrey Garen.
+
+ Added infrastructure for scanning weak ref slots.
+
+ * heap/SlotVisitor.cpp: Added #include "SlotVisitorInlines.h".
+ * heap/SlotVisitor.h:
+ (SlotVisitor): Added SlotVisitor::appendUnbarrieredWeak().
+ * heap/SlotVisitorInlines.h: Added #include "Weak.h".
+ (JSC::SlotVisitor::appendUnbarrieredWeak): Added.
+ * heap/Weak.h:
+ (JSC::operator==): Added operator==() for Weak.
+ * runtime/JSCell.h: Removed #include "SlotVisitorInlines.h".
+ * runtime/JSObject.h: Added #include "SlotVisitorInlines.h".
+
+2012-11-14 Filip Pizlo <fpizlo@apple.com>
+
+ Read-only properties created with putDirect() should tell the structure that there are read-only properties
+ https://bugs.webkit.org/show_bug.cgi?id=102292
+
+ Reviewed by Gavin Barraclough.
+
+ This mostly affects things like function.length.
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::putDirectInternal):
+
+2012-11-13 Filip Pizlo <fpizlo@apple.com>
+
+ Don't access Node& after adding nodes to the graph.
+ https://bugs.webkit.org/show_bug.cgi?id=102005
+
+ Reviewed by Oliver Hunt.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+
+2012-11-14 Valery Ignatyev <valery.ignatyev@ispras.ru>
+
+ Replace (typeof(x) != <"object", "undefined", ...>) with
+ !(typeof(x) == <"object",..>). Later is_object, is_<...> bytecode operation
+ will be used.
+
+ https://bugs.webkit.org/show_bug.cgi?id=98893
+
+ Reviewed by Filip Pizlo.
+
+ This eliminates expensive typeof implementation and
+ allows to use DFG optimizations, which doesn't support 'typeof'.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BinaryOpNode::emitBytecode):
+
+2012-11-14 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ [Qt][ARM]REGRESSION(r133985): It broke the build
+ https://bugs.webkit.org/show_bug.cgi?id=101740
+
+ Reviewed by Csaba Osztrogonác.
+
+ Changed the emitGenericContiguousPutByVal to accept the additional IndexingType argument.
+ This information was passed as a template parameter.
+
+ * jit/JIT.h:
+ (JSC::JIT::emitInt32PutByVal):
+ (JSC::JIT::emitDoublePutByVal):
+ (JSC::JIT::emitContiguousPutByVal):
+ (JIT):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitGenericContiguousPutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emitGenericContiguousPutByVal):
+
+2012-11-14 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Fix the MIPS build after r134332
+ https://bugs.webkit.org/show_bug.cgi?id=102227
+
+ Reviewed by Csaba Osztrogonác.
+
+ Added missing methods for the MacroAssemblerMIPS, based on the MacroAssemblerARMv7.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::canJumpReplacePatchableBranchPtrWithPatch):
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::startOfPatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerMIPS::revertJumpReplacementToPatchableBranchPtrWithPatch):
+
+2012-11-14 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Fix the [-Wreturn-type] warning in JavaScriptCore/assembler/MacroAssemblerARM.h
+ https://bugs.webkit.org/show_bug.cgi?id=102206
+
+ Reviewed by Csaba Osztrogonác.
+
+ Add a return value for the function to suppress the warning.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::startOfPatchableBranchPtrWithPatch):
+
+2012-11-14 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r134599.
+ http://trac.webkit.org/changeset/134599
+ https://bugs.webkit.org/show_bug.cgi?id=102225
+
+ It broke the 32 bit EFL build (Requested by Ossy on #webkit).
+
+ * jit/JITPropertyAccess.cpp:
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC):
+ (JSC::JIT::emitGenericContiguousPutByVal):
+
+2012-11-14 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ [Qt][ARM]REGRESSION(r133985): It broke the build
+ https://bugs.webkit.org/show_bug.cgi?id=101740
+
+ Reviewed by Csaba Osztrogonác.
+
+ Template function body moved to fix VALUE_PROFILER disabled case.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC):
+ (JSC::JIT::emitGenericContiguousPutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+
+2012-11-13 Filip Pizlo <fpizlo@apple.com>
+
+ DFG CreateThis should be able to statically account for the structure of the object it creates, if profiling indicates that this structure is always the same
+ https://bugs.webkit.org/show_bug.cgi?id=102017
+
+ Reviewed by Geoffrey Garen.
+
+ This adds a watchpoint in JSFunction on the cached inheritor ID. It also changes
+ NewObject to take a structure as an operand (previously it implicitly used the owning
+ global object's empty object structure). Any GetCallee where the callee is predictable
+ is turned into a CheckFunction + WeakJSConstant, and any CreateThis on a WeakJSConstant
+ where the inheritor ID watchpoint is still valid is turned into an InheritorIDWatchpoint
+ followed by a NewObject. NewObject already accounts for the structure it uses for object
+ creation in the CFA.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::checkFunctionElimination):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasFunction):
+ (JSC::DFG::Node::function):
+ (JSC::DFG::Node::hasStructure):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/Executable.h:
+ (JSC::JSFunction::JSFunction):
+ * runtime/JSBoundFunction.cpp:
+ (JSC):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::put):
+ (JSC::JSFunction::defineOwnProperty):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::tryGetKnownInheritorID):
+ (JSFunction):
+ (JSC::JSFunction::addInheritorIDWatchpoint):
+
+2012-11-13 Filip Pizlo <fpizlo@apple.com>
+
+ JSFunction and its descendants should be destructible
+ https://bugs.webkit.org/show_bug.cgi?id=102062
+
+ Reviewed by Mark Hahnenberg.
+
+ This will make it easy to place an InlineWatchpointSet inside JSFunction. In the
+ future, we could make JSFunction non-destructible again by making a version of
+ WatchpointSet that is entirely GC'd, but this seems like overkill for now.
+
+ This is performance-neutral.
+
+ * runtime/JSBoundFunction.cpp:
+ (JSC::JSBoundFunction::destroy):
+ (JSC):
+ * runtime/JSBoundFunction.h:
+ (JSBoundFunction):
+ * runtime/JSFunction.cpp:
+ (JSC):
+ (JSC::JSFunction::destroy):
+ * runtime/JSFunction.h:
+ (JSFunction):
+
+2012-11-13 Cosmin Truta <ctruta@rim.com>
+
+ Uninitialized fields in class JSLock
+ https://bugs.webkit.org/show_bug.cgi?id=101695
+
+ Reviewed by Mark Hahnenberg.
+
+ Initialize JSLock::m_ownerThread and JSLock::m_lockDropDepth.
+
+ * runtime/JSLock.cpp:
+ (JSC::JSLock::JSLock):
+
+2012-11-13 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Fix the ARM traditional build after r134332
+ https://bugs.webkit.org/show_bug.cgi?id=102044
+
+ Reviewed by Zoltan Herczeg.
+
+ Added missing methods for the MacroAssemblerARM, based on the MacroAssemblerARMv7.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::canJumpReplacePatchableBranchPtrWithPatch):
+ (MacroAssemblerARM):
+ (JSC::MacroAssemblerARM::startOfPatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerARM::revertJumpReplacementToPatchableBranchPtrWithPatch):
+
+2012-11-12 Filip Pizlo <fpizlo@apple.com>
+
+ op_get_callee should have value profiling
+ https://bugs.webkit.org/show_bug.cgi?id=102047
+
+ Reviewed by Sam Weinig.
+
+ This will allow us to detect if the callee is always the same, which is probably
+ the common case for a lot of constructors.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_get_callee):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_get_callee):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2012-11-12 Filip Pizlo <fpizlo@apple.com>
+
+ The act of getting the callee during 'this' construction should be explicit in bytecode
+ https://bugs.webkit.org/show_bug.cgi?id=102016
+
+ Reviewed by Michael Saboff.
+
+ This is mostly a rollout of http://trac.webkit.org/changeset/116673, but also includes
+ changes to have create_this use the result of get_callee.
+
+ No performance or behavioral impact. This is just meant to allow us to profile
+ get_callee in the future.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_get_callee):
+ (JSC):
+ (JSC::JIT::emit_op_create_this):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_get_callee):
+ (JSC):
+ (JSC::JIT::emit_op_create_this):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2012-11-12 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix ARMv7 build.
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::startOfPatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerARMv7::revertJumpReplacementToPatchableBranchPtrWithPatch):
+
+2012-11-12 Filip Pizlo <fpizlo@apple.com>
+
+ Patching of jumps to stubs should use jump replacement rather than branch destination overwrite
+ https://bugs.webkit.org/show_bug.cgi?id=101909
+
+ Reviewed by Geoffrey Garen.
+
+ This saves a few instructions in inline cases, on those architectures where it is
+ easy to figure out where to put the jump replacement. Sub-1% speed-up across the
+ board.
+
+ * assembler/MacroAssemblerARMv7.h:
+ (MacroAssemblerARMv7):
+ (JSC::MacroAssemblerARMv7::canJumpReplacePatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerARMv7::startOfPatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerARMv7::revertJumpReplacementToPatchableBranchPtrWithPatch):
+ * assembler/MacroAssemblerX86.h:
+ (JSC::MacroAssemblerX86::canJumpReplacePatchableBranchPtrWithPatch):
+ (MacroAssemblerX86):
+ (JSC::MacroAssemblerX86::startOfPatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerX86::revertJumpReplacementToPatchableBranchPtrWithPatch):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::canJumpReplacePatchableBranchPtrWithPatch):
+ (MacroAssemblerX86_64):
+ (JSC::MacroAssemblerX86_64::startOfPatchableBranchPtrWithPatch):
+ (JSC::MacroAssemblerX86_64::revertJumpReplacementToPatchableBranchPtrWithPatch):
+ * assembler/RepatchBuffer.h:
+ (JSC::RepatchBuffer::startOfPatchableBranchPtrWithPatch):
+ (RepatchBuffer):
+ (JSC::RepatchBuffer::replaceWithJump):
+ (JSC::RepatchBuffer::revertJumpReplacementToPatchableBranchPtrWithPatch):
+ * assembler/X86Assembler.h:
+ (X86Assembler):
+ (JSC::X86Assembler::revertJumpTo_movq_i64r):
+ (JSC::X86Assembler::revertJumpTo_cmpl_im_force32):
+ (X86InstructionFormatter):
+ * bytecode/StructureStubInfo.h:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::replaceWithJump):
+ (DFG):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDList):
+ (JSC::DFG::tryBuildGetByIDProtoList):
+ (JSC::DFG::tryCachePutByID):
+ (JSC::DFG::dfgResetGetByID):
+ (JSC::DFG::dfgResetPutByID):
+
+2012-11-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG ArithMul overflow check elimination is too aggressive
+ https://bugs.webkit.org/show_bug.cgi?id=101871
+
+ Reviewed by Oliver Hunt.
+
+ The code was ignoring the fact that ((a * b) | 0) == (((a | 0) * (b | 0)) | 0)
+ only holds if a * b < 2^53. So, I changed it to only enable the optimization
+ when a < 2^22 and b is an int32 (and vice versa), using a super trivial peephole
+ analysis to prove the inequality. I considered writing an epic forward flow
+ formulation that tracks the ranges of integer values but then I thought better
+ of it.
+
+ This also rewires the ArithMul integer speculation logic. Previously, we would
+ assume that an ArithMul was only UsedAsNumber if it escaped, and separately we
+ would decide whether to speculate integer based on a proof of the <2^22
+ inequality. Now, we treat the double rounding behavior of ArithMul as if the
+ result was UsedAsNumber even if it did not escape. Then we try to prove that
+ double rounding cannot happen by attemping to prove that a < 2^22. This then
+ feeds back into the decision of whether or not to speculate integer (if we fail
+ to prove a < 2^22 then we're UsedAsNumber, and if we're also MayOverflow then
+ that forces double speculation).
+
+ No performance impact. It just fixes a bug.
+
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::mulShouldSpeculateInteger):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoForConstant):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoNonRecursive):
+ (JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwo):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
+2012-11-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not emit function checks if we've already proved that the operand is that exact function
+ https://bugs.webkit.org/show_bug.cgi?id=101885
+
+ Reviewed by Oliver Hunt.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::filterByValue):
+ (AbstractValue):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2012-11-12 Kentaro Hara <haraken@chromium.org>
+
+ [V8][JSC] ScriptProfileNode::callUID needs not to be [Custom]
+ https://bugs.webkit.org/show_bug.cgi?id=101892
+
+ Reviewed by Adam Barth.
+
+ Added callUID(), which enables us to kill custom bindings for ScriptProfileNode::callUID.
+
+ * profiler/ProfileNode.h:
+ (JSC::ProfileNode::callUID):
+
+2012-11-12 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add missing header.
+
+2012-11-11 Michael Pruett <michael@68k.org>
+
+ Fix assertion failure in JSObject::tryGetIndexQuickly()
+ https://bugs.webkit.org/show_bug.cgi?id=101869
+
+ Reviewed by Filip Pizlo.
+
+ Currently JSObject::tryGetIndexQuickly() triggers an assertion
+ failure when the object has an undecided indexing type. This
+ case should be treated the same as a blank indexing type.
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::tryGetIndexQuickly):
+
+2012-11-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG register allocation should be greedy rather than round-robin
+ https://bugs.webkit.org/show_bug.cgi?id=101870
+
+ Reviewed by Geoffrey Garen.
+
+ This simplifies the code, reduces some code duplication, and shows some slight
+ performance improvements in a few places, likely due to the fact that lower-numered
+ registers also typically have smaller encodings.
+
+ * dfg/DFGRegisterBank.h:
+ (JSC::DFG::RegisterBank::RegisterBank):
+ (JSC::DFG::RegisterBank::tryAllocate):
+ (JSC::DFG::RegisterBank::allocate):
+ (JSC::DFG::RegisterBank::allocateInternal):
+ (RegisterBank):
+
+2012-11-11 Kenichi Ishibashi <bashi@chromium.org>
+
+ WTFString::utf8() should have a mode of conversion to use replacement character
+ https://bugs.webkit.org/show_bug.cgi?id=101678
+
+ Reviewed by Alexey Proskuryakov.
+
+ Follow the change on String::utf8()
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode): Pass String::StrictConversion instead of true to String::utf8().
+
+2012-11-10 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should optimize out the NaN check on loads from double arrays if the array prototype chain is having a great time
+ https://bugs.webkit.org/show_bug.cgi?id=101718
+
+ Reviewed by Geoffrey Garen.
+
+ If we're reading from a JSArray in double mode, where the array's structure is
+ primordial (all aspects of the structure are unchanged except for indexing type),
+ and the result of the load is used in arithmetic that is known to not distinguish
+ between NaN and undefined, then we should not emit a NaN check. Looks like a 5%
+ win on navier-stokes.
+
+ Also fixed an OpInfo initialization goof for String ops that was revealed by this
+ change.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::arraySpeculationToString):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::isSaneChain):
+ (ArrayMode):
+ (JSC::DFG::ArrayMode::isInBounds):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNodeFlags.cpp:
+ (JSC::DFG::nodeFlagsAsString):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
+ (JSC):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+
+2012-11-10 Filip Pizlo <fpizlo@apple.com>
+
+ DFG constant folding and CFG simplification should be smart enough to know that if a logical op's operand is proven to have a non-masquerading structure then it always evaluates to true
+ https://bugs.webkit.org/show_bug.cgi?id=101511
+
+ Reviewed by Geoffrey Garen.
+
+ This is the second attempt at this patch, which fixes the !"" case.
+
+ To make life easier, this moves BranchDirection into BasicBlock so that after
+ running the CFA, we always know, for each block, what direction the CFA
+ proved. CFG simplification now both uses and preserves cfaBranchDirection in
+ its transformations.
+
+ Also made both LogicalNot and Branch check whether the operand is a known cell
+ with a known structure, and if so, made them do the appropriate folding.
+
+ 5% speed-up on V8/raytrace because it makes raytrace's own null checks
+ evaporate (i.e. idioms like 'if (!x) throw "unhappiness"') thanks to the fact
+ that we were already doing structure check hoisting.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::endBasicBlock):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::BasicBlock):
+ (BasicBlock):
+ * dfg/DFGBranchDirection.h: Added.
+ (DFG):
+ (JSC::DFG::branchDirectionToString):
+ (JSC::DFG::isKnownDirection):
+ (JSC::DFG::branchCondition):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+
+2012-11-10 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r133971.
+ http://trac.webkit.org/changeset/133971
+ https://bugs.webkit.org/show_bug.cgi?id=101839
+
+ Causes WebProcess to hang at 100% on www.apple.com (Requested
+ by kling on #webkit).
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::endBasicBlock):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ * dfg/DFGAbstractState.h:
+ (JSC::DFG::AbstractState::branchDirectionToString):
+ (AbstractState):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::BasicBlock):
+ (BasicBlock):
+ * dfg/DFGBranchDirection.h: Removed.
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+
+2012-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ If the DFG ArrayMode says that an access is on an OriginalArray, then the checks should always enforce this
+ https://bugs.webkit.org/show_bug.cgi?id=101720
+
+ Reviewed by Mark Hahnenberg.
+
+ Previously, "original" arrays was just a hint that we could find the structure
+ of the array if we needed to even if the array profile didn't have it due to
+ polymorphism. Now, "original" arrays are a property that is actually checked:
+ if an array access has ArrayMode::arrayClass() == Array::OriginalArray, then we
+ can be sure that the code performing the access is dealing with not just a
+ JSArray, but a JSArray that has no named properties, no indexed accessors, and
+ the ArrayPrototype as its prototype. This will be useful for optimizations that
+ are being done as part of https://bugs.webkit.org/show_bug.cgi?id=101720.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::originalArrayStructure):
+ (DFG):
+ (JSC::DFG::ArrayMode::alreadyChecked):
+ * dfg/DFGArrayMode.h:
+ (JSC):
+ (DFG):
+ (JSC::DFG::ArrayMode::withProfile):
+ (ArrayMode):
+ (JSC::DFG::ArrayMode::benefitsFromOriginalArray):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::checkArray):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
+ (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
+
+2012-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of BooleanPrototype.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/BooleanPrototype.h:
+
+2012-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of BooleanObject.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/BooleanObject.h:
+
+2012-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of BooleanConstructor.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/BooleanConstructor.h:
+
+2012-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ Fix indentation of BatchedTransitionOptimizer.h
+
+ Rubber stamped by Mark Hahnenberg.
+
+ * runtime/BatchedTransitionOptimizer.h:
+
+2012-11-09 Oliver Hunt <oliver@apple.com>
+
+ So Thingy probably isn't the best name for a class, so
+ renamed to CacheMap.
+
+ RS=Geoff
+
+ * runtime/CodeCache.h:
+ (JSC::CacheMap::CacheMap):
+
+2012-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ ArrayPrototype should start out with a blank indexing type
+ https://bugs.webkit.org/show_bug.cgi?id=101719
+
+ Reviewed by Mark Hahnenberg.
+
+ This allows us to track if the array prototype ever ends up with indexed
+ properties.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::create):
+ (JSC::ArrayPrototype::ArrayPrototype):
+ * runtime/ArrayPrototype.h:
+ (ArrayPrototype):
+ (JSC::ArrayPrototype::createStructure):
+
+2012-11-08 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ MarkStackArray should use the BlockAllocator instead of the MarkStackSegmentAllocator
+ https://bugs.webkit.org/show_bug.cgi?id=101642
+
+ Reviewed by Filip Pizlo.
+
+ MarkStackSegmentAllocator is like a miniature version of the BlockAllocator. Now that the BlockAllocator has support
+ for a variety of block sizes, we should get rid of the MarkStackSegmentAllocator in favor of the BlockAllocator.
+
+ * heap/BlockAllocator.h: Add new specializations of regionSetFor for the new MarkStackSegments.
+ (JSC):
+ (JSC::MarkStackSegment):
+ * heap/GCThreadSharedData.cpp:
+ (JSC::GCThreadSharedData::GCThreadSharedData):
+ (JSC::GCThreadSharedData::reset):
+ * heap/GCThreadSharedData.h:
+ (GCThreadSharedData):
+ * heap/MarkStack.cpp:
+ (JSC::MarkStackArray::MarkStackArray): We now have a doubly linked list of MarkStackSegments, so we need to refactor
+ all the places that used the old custom tail/previous logic.
+ (JSC::MarkStackArray::~MarkStackArray):
+ (JSC::MarkStackArray::expand):
+ (JSC::MarkStackArray::refill):
+ (JSC::MarkStackArray::donateSomeCellsTo): Refactor to use the new linked list.
+ (JSC::MarkStackArray::stealSomeCellsFrom): Ditto.
+ * heap/MarkStack.h:
+ (JSC):
+ (MarkStackSegment):
+ (JSC::MarkStackSegment::MarkStackSegment):
+ (JSC::MarkStackSegment::sizeFromCapacity):
+ (MarkStackArray):
+ * heap/MarkStackInlines.h:
+ (JSC::MarkStackSegment::create):
+ (JSC):
+ (JSC::MarkStackArray::postIncTop):
+ (JSC::MarkStackArray::preDecTop):
+ (JSC::MarkStackArray::setTopForFullSegment):
+ (JSC::MarkStackArray::setTopForEmptySegment):
+ (JSC::MarkStackArray::top):
+ (JSC::MarkStackArray::validatePrevious):
+ (JSC::MarkStackArray::append):
+ (JSC::MarkStackArray::removeLast):
+ (JSC::MarkStackArray::isEmpty):
+ (JSC::MarkStackArray::size):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::SlotVisitor):
+
+2012-11-09 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ [Qt] r133953 broke the ARM_TRADITIONAL build
+ https://bugs.webkit.org/show_bug.cgi?id=101706
+
+ Reviewed by Csaba Osztrogonác.
+
+ Fix for both hardfp and softfp.
+
+ * dfg/DFGCCallHelpers.h:
+ (CCallHelpers):
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+
+2012-11-09 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r134051.
+ http://trac.webkit.org/changeset/134051
+ https://bugs.webkit.org/show_bug.cgi?id=101757
+
+ It didn't fix the build (Requested by Ossy on #webkit).
+
+ * dfg/DFGCCallHelpers.h:
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+
+2012-11-09 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ [Qt] r133953 broke the ARM_TRADITIONAL build
+ https://bugs.webkit.org/show_bug.cgi?id=101706
+
+ Reviewed by Csaba Osztrogonác.
+
+ Fix the ARM_TRADITIONAL build after r133953
+
+ * dfg/DFGCCallHelpers.h:
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+ (CCallHelpers):
+
+2012-11-09 Csaba Osztrogonác <ossy@webkit.org>
+
+ [Qt] Fix the LLINT build from ARMv7 platform
+ https://bugs.webkit.org/show_bug.cgi?id=101712
+
+ Reviewed by Simon Hausmann.
+
+ Enable generating of LLIntAssembly.h on ARM platforms.
+
+ * DerivedSources.pri:
+ * JavaScriptCore.pro:
+
+2012-11-08 Filip Pizlo <fpizlo@apple.com>
+
+ ArrayPrototype.h should have correct indentation
+
+ Rubber stamped by Sam Weinig.
+
+ * runtime/ArrayPrototype.h:
+
+2012-11-08 Mark Lam <mark.lam@apple.com>
+
+ Renamed ...InlineMethods.h files to ...Inlines.h.
+ https://bugs.webkit.org/show_bug.cgi?id=101145.
+
+ Reviewed by Geoffrey Garen.
+
+ This is only a refactoring effort to rename the files. There are no
+ functionality changes.
+
+ * API/JSObjectRef.cpp:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ * dfg/DFGOperations.cpp:
+ * heap/ConservativeRoots.cpp:
+ * heap/CopiedBlock.h:
+ * heap/CopiedSpace.cpp:
+ * heap/CopiedSpaceInlineMethods.h: Removed.
+ * heap/CopiedSpaceInlines.h: Copied from Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h.
+ * heap/CopyVisitor.cpp:
+ * heap/CopyVisitorInlineMethods.h: Removed.
+ * heap/CopyVisitorInlines.h: Copied from Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h.
+ * heap/GCThread.cpp:
+ * heap/GCThreadSharedData.cpp:
+ * heap/HandleStack.cpp:
+ * heap/Heap.cpp:
+ * heap/HeapRootVisitor.h:
+ * heap/MarkStack.cpp:
+ * heap/MarkStackInlineMethods.h: Removed.
+ * heap/MarkStackInlines.h: Copied from Source/JavaScriptCore/heap/MarkStackInlineMethods.h.
+ * heap/SlotVisitor.cpp:
+ * heap/SlotVisitor.h:
+ * heap/SlotVisitorInlineMethods.h: Removed.
+ * heap/SlotVisitorInlines.h: Copied from Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h.
+ * jit/HostCallReturnValue.cpp:
+ * jit/JIT.cpp:
+ * jit/JITArithmetic.cpp:
+ * jit/JITArithmetic32_64.cpp:
+ * jit/JITCall.cpp:
+ * jit/JITCall32_64.cpp:
+ * jit/JITInlineMethods.h: Removed.
+ * jit/JITInlines.h: Copied from Source/JavaScriptCore/jit/JITInlineMethods.h.
+ * jit/JITOpcodes.cpp:
+ * jit/JITOpcodes32_64.cpp:
+ * jit/JITPropertyAccess.cpp:
+ * jit/JITPropertyAccess32_64.cpp:
+ * jsc.cpp:
+ * runtime/ArrayConstructor.cpp:
+ * runtime/ArrayPrototype.cpp:
+ * runtime/ButterflyInlineMethods.h: Removed.
+ * runtime/ButterflyInlines.h: Copied from Source/JavaScriptCore/runtime/ButterflyInlineMethods.h.
+ * runtime/IndexingHeaderInlineMethods.h: Removed.
+ * runtime/IndexingHeaderInlines.h: Copied from Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h.
+ * runtime/JSActivation.h:
+ * runtime/JSArray.cpp:
+ * runtime/JSArray.h:
+ * runtime/JSCell.h:
+ * runtime/JSObject.cpp:
+ * runtime/JSValueInlineMethods.h: Removed.
+ * runtime/JSValueInlines.h: Copied from Source/JavaScriptCore/runtime/JSValueInlineMethods.h.
+ * runtime/LiteralParser.cpp:
+ * runtime/ObjectConstructor.cpp:
+ * runtime/Operations.h:
+ * runtime/RegExpMatchesArray.cpp:
+ * runtime/RegExpObject.cpp:
+ * runtime/StringPrototype.cpp:
+
+2012-11-08 Filip Pizlo <fpizlo@apple.com>
+
+ ArrayConstructor.h should have correct indentation
+
+ Rubber stamped by Sam Weinig.
+
+ * runtime/ArrayConstructor.h:
+
+2012-11-08 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should know that int == null is always false
+ https://bugs.webkit.org/show_bug.cgi?id=101665
+
+ Reviewed by Oliver Hunt.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+
+2012-11-08 Filip Pizlo <fpizlo@apple.com>
+
+ Arguments.h should have correct indentation
+
+ Rubber stamped by Sam Weinig.
+
+ * runtime/Arguments.h:
+
+2012-11-08 Filip Pizlo <fpizlo@apple.com>
+
+ It should be possible to JIT compile get_by_vals and put_by_vals even if the DFG is disabled.
+
+ Reviewed by Oliver Hunt.
+
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::chooseArrayMode):
+
+2012-11-08 Filip Pizlo <fpizlo@apple.com>
+
+ op_call should have LLInt call link info even if the DFG is disabled
+ https://bugs.webkit.org/show_bug.cgi?id=101672
+
+ Reviewed by Oliver Hunt.
+
+ Get rid of the evil uses of fall-through.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2012-11-08 Oliver Hunt <oliver@apple.com>
+
+ Improve effectiveness of function-level caching
+ https://bugs.webkit.org/show_bug.cgi?id=101667
+
+ Reviewed by Filip Pizlo.
+
+ Added a random-eviction based cache for unlinked functions, and switch
+ UnlinkedFunctionExecutable's code references to Weak<>, thereby letting
+ us remove the explicit UnlinkedFunctionExecutable::clearCode() calls that
+ were being triggered by GC.
+
+ Refactored the random eviction part of the CodeCache into a separate data
+ structure so that I didn't have to duplicate the code again, and then used
+ that for the new function cache.
+
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedFunctionExecutable::visitChildren):
+ (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedFunctionExecutable::clearCodeForRecompilation):
+ (UnlinkedFunctionExecutable):
+ * debugger/Debugger.cpp:
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getCodeBlock):
+ (JSC::CodeCache::generateFunctionCodeBlock):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ (JSC::CodeCache::usedFunctionCode):
+ (JSC):
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::clearUnlinkedCodeForRecompilationIfNotCompiling):
+ (JSC::FunctionExecutable::clearCode):
+ * runtime/Executable.h:
+ (FunctionExecutable):
+
+2012-11-07 Filip Pizlo <fpizlo@apple.com>
+
+ DFG constant folding and CFG simplification should be smart enough to know that if a logical op's operand is proven to have a non-masquerading structure then it always evaluates to true
+ https://bugs.webkit.org/show_bug.cgi?id=101511
+
+ Reviewed by Oliver Hunt.
+
+ To make life easier, this moves BranchDirection into BasicBlock so that after
+ running the CFA, we always know, for each block, what direction the CFA
+ proved. CFG simplification now both uses and preserves cfaBranchDirection in
+ its transformations.
+
+ Also made both LogicalNot and Branch check whether the operand is a known cell
+ with a known structure, and if so, made them do the appropriate folding.
+
+ 5% speed-up on V8/raytrace because it makes raytrace's own null checks
+ evaporate (i.e. idioms like 'if (!x) throw "unhappiness"') thanks to the fact
+ that we were already doing structure check hoisting.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::endBasicBlock):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::mergeToSuccessors):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::BasicBlock):
+ (BasicBlock):
+ * dfg/DFGBranchDirection.h: Added.
+ (DFG):
+ (JSC::DFG::branchDirectionToString):
+ (JSC::DFG::isKnownDirection):
+ (JSC::DFG::branchCondition):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::run):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+
+2012-11-08 Christophe Dumez <christophe.dumez@intel.com>
+
+ [JSC] HTML extensions to String.prototype should escape " as &quot; in argument values
+ https://bugs.webkit.org/show_bug.cgi?id=90667
+
+ Reviewed by Benjamin Poulain.
+
+ Escape quotation mark as &quot; in argument values to:
+ - String.prototype.anchor(name)
+ - String.prototype.fontcolor(color)
+ - String.prototype.fontsize(size)
+ - String.prototype.link(href)
+
+ This behavior matches Chromium/V8 and Firefox/Spidermonkey
+ implementations and is requited by:
+ http://mathias.html5.org/specs/javascript/#escapeattributevalue
+
+ This also fixes a potential security risk (XSS vector).
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncFontcolor):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncAnchor):
+ (JSC::stringProtoFuncLink):
+
+2012-11-08 Anders Carlsson <andersca@apple.com>
+
+ HeapStatistics::s_pauseTimeStarts and s_pauseTimeEnds should be Vectors
+ https://bugs.webkit.org/show_bug.cgi?id=101651
+
+ Reviewed by Andreas Kling.
+
+ HeapStatistics uses Deques when Vectors would work just as good.
+
+ * heap/HeapStatistics.cpp:
+ * heap/HeapStatistics.h:
+ (HeapStatistics):
+
+2012-11-07 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not assume that something is a double just because it might be undefined
+ https://bugs.webkit.org/show_bug.cgi?id=101438
+
+ Reviewed by Oliver Hunt.
+
+ This changes all non-bitop arithmetic to (a) statically expect that variables are
+ defined prior to use in arithmetic and (b) not fall off into double paths just
+ because a value may not be a number. This is accomplished with two new notions of
+ speculation:
+
+ shouldSpeculateIntegerExpectingDefined: Should we speculate that the value is an
+ integer if we ignore undefined (i.e. SpecOther) predictions?
+
+ shouldSpeculateIntegerForArithmetic: Should we speculate that the value is an
+ integer if we ignore non-numeric predictions?
+
+ This is a ~2x speed-up on programs that seem to our prediction propagator to have
+ paths in which otherwise numeric variables are undefined.
+
+ * bytecode/SpeculatedType.h:
+ (JSC::isInt32SpeculationForArithmetic):
+ (JSC):
+ (JSC::isInt32SpeculationExpectingDefined):
+ (JSC::isDoubleSpeculationForArithmetic):
+ (JSC::isNumberSpeculationExpectingDefined):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::addShouldSpeculateInteger):
+ (JSC::DFG::Graph::mulShouldSpeculateInteger):
+ (JSC::DFG::Graph::negateShouldSpeculateInteger):
+ (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
+ (JSC::DFG::Graph::mulImmediateShouldSpeculateInteger):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::shouldSpeculateIntegerForArithmetic):
+ (Node):
+ (JSC::DFG::Node::shouldSpeculateIntegerExpectingDefined):
+ (JSC::DFG::Node::shouldSpeculateDoubleForArithmetic):
+ (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileAdd):
+ (JSC::DFG::SpeculativeJIT::compileArithMod):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_div):
+
+2012-11-06 Filip Pizlo <fpizlo@apple.com>
+
+ JSC should infer when indexed storage contains only integers or doubles
+ https://bugs.webkit.org/show_bug.cgi?id=98606
+
+ Reviewed by Oliver Hunt.
+
+ This adds two new indexing types: int32 and double. It also adds array allocation profiling,
+ which allows array allocations to converge to allocating arrays using those types to which
+ those arrays would have been converted.
+
+ 20% speed-up on navier-stokes. 40% speed-up on various Kraken DSP tests. Some slow-downs too,
+ but a performance win overall on all benchmarks we track.
+
+ * API/JSObjectRef.cpp:
+ (JSObjectMakeArray):
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/AbstractMacroAssembler.h:
+ (JumpList):
+ (JSC::AbstractMacroAssembler::JumpList::JumpList):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::branchDouble):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::jnp):
+ (X86Assembler):
+ (JSC::X86Assembler::X86InstructionFormatter::emitRex):
+ * bytecode/ArrayAllocationProfile.cpp: Added.
+ (JSC):
+ (JSC::ArrayAllocationProfile::updateIndexingType):
+ * bytecode/ArrayAllocationProfile.h: Added.
+ (JSC):
+ (ArrayAllocationProfile):
+ (JSC::ArrayAllocationProfile::ArrayAllocationProfile):
+ (JSC::ArrayAllocationProfile::selectIndexingType):
+ (JSC::ArrayAllocationProfile::updateLastAllocation):
+ (JSC::ArrayAllocationProfile::selectIndexingTypeFor):
+ (JSC::ArrayAllocationProfile::updateLastAllocationFor):
+ * bytecode/ArrayProfile.cpp:
+ (JSC::ArrayProfile::updatedObservedArrayModes):
+ (JSC):
+ * bytecode/ArrayProfile.h:
+ (JSC):
+ (JSC::arrayModesInclude):
+ (JSC::shouldUseSlowPutArrayStorage):
+ (JSC::shouldUseFastArrayStorage):
+ (JSC::shouldUseContiguous):
+ (JSC::shouldUseDouble):
+ (JSC::shouldUseInt32):
+ (ArrayProfile):
+ * bytecode/ByValInfo.h:
+ (JSC::isOptimizableIndexingType):
+ (JSC::jitArrayModeForIndexingType):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
+ (JSC):
+ (JSC::CodeBlock::updateAllValueProfilePredictions):
+ (JSC::CodeBlock::updateAllArrayPredictions):
+ (JSC::CodeBlock::updateAllPredictions):
+ (JSC::CodeBlock::shouldOptimizeNow):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::numberOfArrayAllocationProfiles):
+ (JSC::CodeBlock::addArrayAllocationProfile):
+ (JSC::CodeBlock::updateAllValueProfilePredictions):
+ (JSC::CodeBlock::updateAllArrayPredictions):
+ * bytecode/DFGExitProfile.h:
+ (JSC::DFG::exitKindToString):
+ * bytecode/Instruction.h:
+ (JSC):
+ (JSC::Instruction::Instruction):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/SpeculatedType.h:
+ (JSC):
+ (JSC::isRealNumberSpeculation):
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC):
+ (JSC::UnlinkedCodeBlock::addArrayAllocationProfile):
+ (JSC::UnlinkedCodeBlock::numberOfArrayAllocationProfiles):
+ (UnlinkedCodeBlock):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::newArrayAllocationProfile):
+ (JSC):
+ (JSC::BytecodeGenerator::emitNewArray):
+ (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::fromObserved):
+ (JSC::DFG::ArrayMode::refine):
+ (DFG):
+ (JSC::DFG::ArrayMode::alreadyChecked):
+ (JSC::DFG::arrayTypeToString):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::withType):
+ (ArrayMode):
+ (JSC::DFG::ArrayMode::withTypeAndConversion):
+ (JSC::DFG::ArrayMode::usesButterfly):
+ (JSC::DFG::ArrayMode::isSpecific):
+ (JSC::DFG::ArrayMode::supportsLength):
+ (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getArrayMode):
+ (ByteCodeParser):
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCCallHelpers.h:
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+ (CCallHelpers):
+ * dfg/DFGCallArrayAllocatorSlowPathGenerator.h:
+ (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal):
+ (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ * dfg/DFGNode.h:
+ (NewArrayBufferData):
+ (JSC::DFG::Node::hasIndexingType):
+ (Node):
+ (JSC::DFG::Node::indexingType):
+ (JSC::DFG::Node::setIndexingType):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+ (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (SpeculateIntegerOperand):
+ (JSC::DFG::SpeculateIntegerOperand::use):
+ (SpeculateDoubleOperand):
+ (JSC::DFG::SpeculateDoubleOperand::use):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JIT.h:
+ (JSC::JIT::emitInt32GetByVal):
+ (JIT):
+ (JSC::JIT::emitInt32PutByVal):
+ (JSC::JIT::emitDoublePutByVal):
+ (JSC::JIT::emitContiguousPutByVal):
+ * jit/JITExceptions.cpp:
+ (JSC::genericThrow):
+ * jit/JITInlineMethods.h:
+ (JSC::arrayProfileSaw):
+ (JSC::JIT::chooseArrayMode):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_array):
+ (JSC::JIT::emit_op_new_array_with_size):
+ (JSC::JIT::emit_op_new_array_buffer):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitDoubleGetByVal):
+ (JSC):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emitGenericContiguousPutByVal):
+ (JSC::JIT::emitSlow_op_put_by_val):
+ (JSC::JIT::privateCompileGetByVal):
+ (JSC::JIT::privateCompilePutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emitDoubleGetByVal):
+ (JSC):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emitGenericContiguousPutByVal):
+ (JSC::JIT::emitSlow_op_put_by_val):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ (JSC):
+ * jsc.cpp:
+ (GlobalObject::finishCreation):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::jitCompileAndSetHeuristics):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/x86.rb:
+ * runtime/ArrayConstructor.cpp:
+ (JSC::constructArrayWithSizeQuirk):
+ * runtime/ArrayConstructor.h:
+ (JSC):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncConcat):
+ (JSC::arrayProtoFuncSlice):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ * runtime/Butterfly.h:
+ (JSC::Butterfly::contiguousInt32):
+ (JSC::Butterfly::contiguousDouble):
+ (JSC::Butterfly::fromContiguous):
+ * runtime/ButterflyInlineMethods.h:
+ (JSC::Butterfly::createUninitializedDuringCollection):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncBind):
+ * runtime/IndexingHeaderInlineMethods.h:
+ (JSC::IndexingHeader::indexingPayloadSizeInBytes):
+ * runtime/IndexingType.cpp:
+ (JSC::leastUpperBoundOfIndexingTypes):
+ (JSC):
+ (JSC::leastUpperBoundOfIndexingTypeAndType):
+ (JSC::leastUpperBoundOfIndexingTypeAndValue):
+ (JSC::indexingTypeToString):
+ * runtime/IndexingType.h:
+ (JSC):
+ (JSC::hasUndecided):
+ (JSC::hasInt32):
+ (JSC::hasDouble):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::pop):
+ (JSC::JSArray::push):
+ (JSC::JSArray::shiftCountWithAnyIndexingType):
+ (JSC::JSArray::unshiftCountWithAnyIndexingType):
+ (JSC::compareNumbersForQSortWithInt32):
+ (JSC):
+ (JSC::compareNumbersForQSortWithDouble):
+ (JSC::JSArray::sortNumericVector):
+ (JSC::JSArray::sortNumeric):
+ (JSC::JSArray::sortCompactedVector):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::sortVector):
+ (JSC::JSArray::fillArgList):
+ (JSC::JSArray::copyToArguments):
+ (JSC::JSArray::compactForSorting):
+ * runtime/JSArray.h:
+ (JSArray):
+ (JSC::createContiguousArrayButterfly):
+ (JSC::JSArray::create):
+ (JSC::JSArray::tryCreateUninitialized):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ (JSC::JSGlobalObject::haveABadTime):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::originalArrayStructureForIndexingType):
+ (JSC::JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation):
+ (JSC::JSGlobalObject::arrayStructureForProfileDuringAllocation):
+ (JSC::JSGlobalObject::isOriginalArrayStructure):
+ (JSC::constructEmptyArray):
+ (JSC::constructArray):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly):
+ (JSC::JSObject::getOwnPropertySlotByIndex):
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::enterDictionaryIndexingMode):
+ (JSC::JSObject::createInitialIndexedStorage):
+ (JSC):
+ (JSC::JSObject::createInitialUndecided):
+ (JSC::JSObject::createInitialInt32):
+ (JSC::JSObject::createInitialDouble):
+ (JSC::JSObject::createInitialContiguous):
+ (JSC::JSObject::convertUndecidedToInt32):
+ (JSC::JSObject::convertUndecidedToDouble):
+ (JSC::JSObject::convertUndecidedToContiguous):
+ (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
+ (JSC::JSObject::convertUndecidedToArrayStorage):
+ (JSC::JSObject::convertInt32ToDouble):
+ (JSC::JSObject::convertInt32ToContiguous):
+ (JSC::JSObject::convertInt32ToArrayStorage):
+ (JSC::JSObject::convertDoubleToContiguous):
+ (JSC::JSObject::convertDoubleToArrayStorage):
+ (JSC::JSObject::convertContiguousToArrayStorage):
+ (JSC::JSObject::convertUndecidedForValue):
+ (JSC::JSObject::convertInt32ForValue):
+ (JSC::JSObject::setIndexQuicklyToUndecided):
+ (JSC::JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex):
+ (JSC::JSObject::convertDoubleToContiguousWhilePerformingSetIndex):
+ (JSC::JSObject::ensureInt32Slow):
+ (JSC::JSObject::ensureDoubleSlow):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::ensureArrayStorageSlow):
+ (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
+ (JSC::JSObject::switchToSlowPutArrayStorage):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ (JSC::JSObject::putByIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectIndexBeyondVectorLength):
+ (JSC::JSObject::getNewVectorLength):
+ (JSC::JSObject::countElements):
+ (JSC::JSObject::ensureLengthSlow):
+ (JSC::JSObject::getOwnPropertyDescriptor):
+ * runtime/JSObject.h:
+ (JSC::JSObject::getArrayLength):
+ (JSC::JSObject::getVectorLength):
+ (JSC::JSObject::canGetIndexQuickly):
+ (JSC::JSObject::getIndexQuickly):
+ (JSC::JSObject::tryGetIndexQuickly):
+ (JSC::JSObject::canSetIndexQuickly):
+ (JSC::JSObject::canSetIndexQuicklyForPutDirect):
+ (JSC::JSObject::setIndexQuickly):
+ (JSC::JSObject::initializeIndex):
+ (JSC::JSObject::hasSparseMap):
+ (JSC::JSObject::inSparseIndexingMode):
+ (JSObject):
+ (JSC::JSObject::ensureInt32):
+ (JSC::JSObject::ensureDouble):
+ (JSC::JSObject::ensureLength):
+ (JSC::JSObject::indexingData):
+ (JSC::JSObject::currentIndexingData):
+ (JSC::JSObject::getHolyIndexQuickly):
+ (JSC::JSObject::relevantLength):
+ (JSC::JSObject::currentRelevantLength):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::description):
+ * runtime/LiteralParser.cpp:
+ (JSC::::parse):
+ * runtime/ObjectConstructor.cpp:
+ (JSC::objectConstructorGetOwnPropertyNames):
+ (JSC::objectConstructorKeys):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSplit):
+ * runtime/Structure.cpp:
+ (JSC::Structure::nonPropertyTransition):
+ * runtime/StructureTransitionTable.h:
+ (JSC::newIndexingType):
+
+2012-11-08 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ ASSERT problem on MIPS
+ https://bugs.webkit.org/show_bug.cgi?id=100589
+
+ Reviewed by Oliver Hunt.
+
+ ASSERT fix for MIPS arch.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_resolve_operations):
+
+2012-11-08 Michael Saboff <msaboff@apple.com>
+
+ OpaqueJSClassContextData() should use StringImpl::isolatedCopy() to make string copies
+ https://bugs.webkit.org/show_bug.cgi?id=101507
+
+ Reviewed by Andreas Kling.
+
+ Changed to use isolatedCopy() for key Strings.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+
+2012-11-07 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ WeakBlocks should be HeapBlocks
+ https://bugs.webkit.org/show_bug.cgi?id=101411
+
+ Reviewed by Oliver Hunt.
+
+ Currently WeakBlocks use fastMalloc memory. They are very similar to the other HeapBlocks, however,
+ so we should change them to being allocated with the BlockAllocator.
+
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::BlockAllocator):
+ * heap/BlockAllocator.h: Added a new RegionSet for WeakBlocks.
+ (JSC):
+ (BlockAllocator):
+ (JSC::WeakBlock):
+ * heap/Heap.h: Friended WeakSet to allow access to the BlockAllocator.
+ (Heap):
+ * heap/WeakBlock.cpp:
+ (JSC::WeakBlock::create): Refactored to use HeapBlocks rather than fastMalloc.
+ (JSC::WeakBlock::WeakBlock):
+ * heap/WeakBlock.h: Changed the WeakBlock size to 4 KB so that it divides evenly into the Region size.
+ (JSC):
+ (WeakBlock):
+ * heap/WeakSet.cpp:
+ (JSC::WeakSet::~WeakSet):
+ (JSC::WeakSet::addAllocator):
+
+2012-11-07 Filip Pizlo <fpizlo@apple.com>
+
+ Indentation of ArgList.h is wrong
+ https://bugs.webkit.org/show_bug.cgi?id=101441
+
+ Reviewed by Andreas Kling.
+
+ Just unindented by 4 spaces.
+
+ * runtime/ArgList.h:
+
+2012-11-07 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ [Qt][ARM] REGRESSION(r133688): It made all JSC and layout tests crash on ARM traditional platform
+ https://bugs.webkit.org/show_bug.cgi?id=101465
+
+ Reviewed by Oliver Hunt.
+
+ Fix failing javascriptcore tests on ARM after r133688
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+
+2012-11-06 Oliver Hunt <oliver@apple.com>
+
+ Reduce parser overhead in JSC
+ https://bugs.webkit.org/show_bug.cgi?id=101127
+
+ Reviewed by Filip Pizlo.
+
+ An exciting journey into the world of architecture in which our hero
+ adds yet another layer to JSC codegeneration.
+
+ This patch adds a marginally more compact form of bytecode that is
+ free from any data specific to a given execution context, and that
+ does store any data structures necessary for execution. To actually
+ execute this UnlinkedBytecode we still need to instantiate a real
+ CodeBlock, but this is a much faster linear time operation than any
+ of the earlier parsing or code generation passes.
+
+ As the unlinked code is context free we can then simply use a cache
+ from source to unlinked code mapping to completely avoid all of the
+ old parser overhead. The cache is currently very simple and memory
+ heavy, using the complete source text as a key (rather than SourceCode
+ or equivalent), and a random eviction policy.
+
+ This seems to produce a substantial win when loading identical content
+ in different contexts.
+
+ * API/tests/testapi.c:
+ (main):
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ * bytecode/CodeBlock.h:
+ Moved a number of fields, and a bunch of logic to UnlinkedCodeBlock.h/cpp
+ * bytecode/Opcode.h:
+ Added a global const init no op instruction needed to get correct
+ behaviour without any associated semantics.
+ * bytecode/UnlinkedCodeBlock.cpp: Added.
+ * bytecode/UnlinkedCodeBlock.h: Added.
+ A fairly shallow, GC allocated version of the old CodeBlock
+ classes with a 32bit instruction size, and just metadata
+ size tracking.
+ * bytecompiler/BytecodeGenerator.cpp:
+ * bytecompiler/BytecodeGenerator.h:
+ Replace direct access to m_symbolTable with access through
+ symbolTable(). ProgramCode no longer has a symbol table at
+ all so some previously unconditional (and pointless) uses
+ of symbolTable get null checks.
+ A few other changes to deal with type changes due to us generating
+ unlinked code (eg. pointer free, so profile indices rather than
+ pointers).
+ * dfg/DFGByteCodeParser.cpp:
+ * dfg/DFGCapabilities.h:
+ Support global_init_nop
+ * interpreter/Interpreter.cpp:
+ Now get the ProgramExecutable to initialise new global properties
+ before starting execution.
+ * jit/JIT.cpp:
+ * jit/JITDriver.h:
+ * jit/JITStubs.cpp:
+ * llint/LLIntData.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ Adding init_global_const_nop everywhere else
+ * parser/Parser.h:
+ * parser/ParserModes.h: Added.
+ * parser/ParserTokens.h:
+ Parser no longer needs a global object or callframe to function
+ * runtime/CodeCache.cpp: Added.
+ * runtime/CodeCache.h: Added.
+ A simple, random eviction, Source->UnlinkedCode cache
+ * runtime/Executable.cpp:
+ * runtime/Executable.h:
+ Executables now reference their unlinked counterparts, and
+ request code specifically for the target global object.
+ * runtime/JSGlobalData.cpp:
+ * runtime/JSGlobalData.h:
+ GlobalData now owns a CodeCache and a set of new structures
+ for the unlinked code types.
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObject.h:
+ Utility functions used by executables to perform compilation
+
+ * runtime/JSType.h:
+ Add new JSTypes for unlinked code
+
+2012-11-06 Michael Saboff <msaboff@apple.com>
+
+ JSStringCreateWithCFString() Should create an 8 bit String if possible
+ https://bugs.webkit.org/show_bug.cgi?id=101104
+
+ Reviewed by Darin Adler.
+
+ Try converting the CFString to an 8 bit string using CFStringGetBytes(...,
+ kCFStringEncodingISOLatin1, ...) and return the 8 bit string if successful.
+ If not proceed with 16 bit conversion.
+
+ * API/JSStringRefCF.cpp:
+ (JSStringCreateWithCFString):
+
+2012-11-06 Oliver Hunt <oliver@apple.com>
+
+ Reduce direct m_symbolTable usage in CodeBlock
+ https://bugs.webkit.org/show_bug.cgi?id=101391
+
+ Reviewed by Sam Weinig.
+
+ Simple refactoring.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::dumpStatistics):
+ (JSC::CodeBlock::nameForRegister):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isCaptured):
+
+2012-11-06 Michael Saboff <msaboff@apple.com>
+
+ Lexer::scanRegExp, create 8 bit pattern and flag Identifiers from 16 bit source when possible
+ https://bugs.webkit.org/show_bug.cgi?id=101013
+
+ Reviewed by Darin Adler.
+
+ Changed scanRegExp so that it will create 8 bit identifiers from 8 bit sources and from 16 bit sources
+ whan all the characters are 8 bit. Using two templated helpers, the "is all 8 bit" check is only performed
+ on 16 bit sources. The first helper is orCharacter() that will accumulate the or value of all characters
+ only for 16 bit sources. Replaced the helper Lexer::makeIdentifierSameType() with Lexer::makeRightSizedIdentifier().
+
+ * parser/Lexer.cpp:
+ (JSC::orCharacter<LChar>): Explicit template that serves as a placeholder.
+ (JSC::orCharacter<UChar>): Explicit template that actually or accumulates characters.
+ (JSC::Lexer::scanRegExp):
+ * parser/Lexer.h:
+ (Lexer):
+ (JSC::Lexer::makeRightSizedIdentifier<LChar>): New template that always creates an 8 bit Identifier.
+ (JSC::Lexer::makeRightSizedIdentifier<UChar>): New template that creates an 8 bit Identifier for 8 bit
+ data in a 16 bit source.
+
+2012-11-06 Filip Pizlo <fpizlo@apple.com>
+
+ Indentation of JSCell.h is wrong
+ https://bugs.webkit.org/show_bug.cgi?id=101379
+
+ Rubber stamped by Alexey Proskuryakov.
+
+ Just removed four spaces on a bunch of lines.
+
+ * runtime/JSCell.h:
+
+2012-11-05 Filip Pizlo <fpizlo@apple.com>
+
+ Indentation of JSObject.h is wrong
+ https://bugs.webkit.org/show_bug.cgi?id=101313
+
+ Rubber stamped by Alexey Proskuryakov.
+
+ Just unindented code, since namespace bodies shouldn't be indented.
+
+ * runtime/JSObject.h:
+
+2012-11-05 Filip Pizlo <fpizlo@apple.com>
+
+ Indentation of JSArray.h is wrong
+ https://bugs.webkit.org/show_bug.cgi?id=101314
+
+ Rubber stamped by Alexey Proskuryakov.
+
+ Just removing the indentation inside the namespace body.
+
+ * runtime/JSArray.h:
+
+2012-11-05 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not fall down to patchable GetById just because a prototype had things added to it
+ https://bugs.webkit.org/show_bug.cgi?id=101299
+
+ Reviewed by Geoffrey Garen.
+
+ This looks like a slight win on V8v7 and SunSpider.
+
+ * bytecode/DFGExitProfile.h:
+ (JSC::DFG::exitKindToString):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-11-05 Filip Pizlo <fpizlo@apple.com>
+
+ Get rid of method_check
+ https://bugs.webkit.org/show_bug.cgi?id=101147
+
+ Reviewed by Geoffrey Garen.
+
+ op_method_check no longer buys us anything, since get_by_id proto caching
+ gives just as much profiling information and the DFG inlines monomorphic
+ proto accesses anyway.
+
+ This also has the potential for a speed-up since it makes parsing of
+ profiling data easier. No longer do we have to deal with the confusion of
+ the get_by_id portion of a method_check appearing monomorphic even though
+ we're really dealing with a bimorphic access (method_check specializes for
+ one case and get_by_id for another).
+
+ This looks like a 1% speed-up on both SunSpider and V8v7.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printGetByIdCacheStatus):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::shrinkToFit):
+ (JSC::CodeBlock::unlinkCalls):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::getCallLinkInfo):
+ (JSC::CodeBlock::callLinkInfo):
+ (CodeBlock):
+ * bytecode/GetByIdStatus.cpp:
+ (JSC::GetByIdStatus::computeFromLLInt):
+ * bytecode/MethodCallLinkInfo.cpp: Removed.
+ * bytecode/MethodCallLinkInfo.h: Removed.
+ * bytecode/MethodCallLinkStatus.cpp: Removed.
+ * bytecode/MethodCallLinkStatus.h: Removed.
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::FunctionCallDotNode::emitBytecode):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::PropertyStubCompilationInfo::copyToStubInfo):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::PropertyStubCompilationInfo::slowCaseInfo):
+ (PropertyStubCompilationInfo):
+ (JSC):
+ (JIT):
+ * jit/JITPropertyAccess.cpp:
+ (JSC):
+ (JSC::JIT::emitSlow_op_get_by_id):
+ (JSC::JIT::compileGetByIdSlowCase):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC):
+ (JSC::JIT::compileGetByIdSlowCase):
+ * jit/JITStubs.cpp:
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LowLevelInterpreter.asm:
+
+2012-11-05 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Refactor LLInt64 to distinguish the pointer operations from the 64-bit integer operations
+ https://bugs.webkit.org/show_bug.cgi?id=100321
+
+ Reviewed by Filip Pizlo.
+
+ We have refactored the MacroAssembler and JIT compilers to distinguish
+ the pointer operations from the 64-bit integer operations (see bug #99154).
+ Now we want to do the similar work for LLInt, and the goal is same as
+ the one mentioned in 99154.
+
+ This is the second part of the modification: in the low level interpreter,
+ changing the operations on 64-bit integers to use the "<foo>q" instructions.
+ This also removes some unused/meaningless "<foo>p" instructions.
+
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter.cpp:
+ (JSC::CLoop::execute):
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/armv7.rb:
+ * offlineasm/cloop.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/x86.rb:
+
+2012-11-05 Filip Pizlo <fpizlo@apple.com>
+
+ Prototype chain caching should check that the path from the base object to the slot base involves prototype hops only
+ https://bugs.webkit.org/show_bug.cgi?id=101276
+
+ Reviewed by Gavin Barraclough.
+
+ Changed normalizePrototypeChain() to report an invalid prototype chain if any object is a proxy.
+ This catches cases where our prototype chain checks would have been insufficient to guard against
+ newly introduced properties, despecialized properties, or deleted properties in the chain of
+ objects involved in the access.
+
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDProtoList):
+ (JSC::DFG::tryCachePutByID):
+ (JSC::DFG::tryBuildPutByIdList):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCachePutByID):
+ (JSC::JITThunks::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * runtime/Operations.h:
+ (JSC):
+ (JSC::normalizePrototypeChain):
+
+2012-11-05 Dima Gorbik <dgorbik@apple.com>
+
+ Back out controversial changes from Bug 98665.
+ https://bugs.webkit.org/show_bug.cgi?id=101244
+
+ Reviewed by David Kilzer.
+
+ Backing out changes from Bug 98665 until further discussions take place on rules for including Platform.h in Assertions.h.
+
+ * API/tests/minidom.c:
+ * API/tests/testapi.c:
+
+2012-11-04 Filip Pizlo <fpizlo@apple.com>
+
+ Reduce the verbosity of referring to QNaN in JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=101174
+
+ Reviewed by Geoffrey Garen.
+
+ Introduces a #define QNaN in JSValue.h, and replaces all previous uses of
+ std::numeric_limits<double>::quiet_NaN() with QNaN.
+
+ * API/JSValueRef.cpp:
+ (JSValueMakeNumber):
+ (JSValueToNumber):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitFloatTypedArrayGetByVal):
+ * runtime/CachedTranscendentalFunction.h:
+ (JSC::CachedTranscendentalFunction::initialize):
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ * runtime/DateInstanceCache.h:
+ (JSC::DateInstanceData::DateInstanceData):
+ (JSC::DateInstanceCache::reset):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::InterruptedExecutionError::defaultValue):
+ (JSC::TerminatedExecutionError::defaultValue):
+ * runtime/JSCell.h:
+ (JSC::JSValue::getPrimitiveNumber):
+ * runtime/JSDateMath.cpp:
+ (JSC::parseDateFromNullTerminatedCharacters):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::resetDateCache):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::parseInt):
+ (JSC::jsStrDecimalLiteral):
+ (JSC::toDouble):
+ (JSC::jsToNumber):
+ (JSC::parseFloat):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::toNumberSlowCase):
+ * runtime/JSValue.h:
+ (JSC):
+ * runtime/JSValueInlineMethods.h:
+ (JSC::jsNaN):
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncMax):
+ (JSC::mathProtoFuncMin):
+
+2012-11-03 Filip Pizlo <fpizlo@apple.com>
+
+ Baseline JIT should use structure watchpoints whenever possible
+ https://bugs.webkit.org/show_bug.cgi?id=101146
+
+ Reviewed by Sam Weinig.
+
+ No speed-up yet except on toy programs. I think that it will start to show
+ speed-ups with https://bugs.webkit.org/show_bug.cgi?id=101147, which this is
+ a step towards.
+
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::addStructureTransitionCheck):
+ (JSC):
+ (JSC::JIT::testPrototype):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+
+2012-11-04 Csaba Osztrogonác <ossy@webkit.org>
+
+ [Qt] udis86_itab.c is always regenerated
+ https://bugs.webkit.org/show_bug.cgi?id=100756
+
+ Reviewed by Simon Hausmann.
+
+ * DerivedSources.pri: Generate sources to the generated directory.
+ * disassembler/udis86/differences.txt:
+ * disassembler/udis86/itab.py: Add --outputDir option.
+ (UdItabGenerator.__init__):
+ (genItabH):
+ (genItabC):
+ (main):
+
+2012-11-02 Filip Pizlo <fpizlo@apple.com>
+
+ LLInt 32-bit put_by_val ArrayStorage case should use the right register (t3, not t2) for the index in the publicLength updating path
+ https://bugs.webkit.org/show_bug.cgi?id=101118
+
+ Reviewed by Gavin Barraclough.
+
+ * llint/LowLevelInterpreter32_64.asm:
+
+2012-11-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::Node::converToStructureTransitionWatchpoint should take kindly to ArrayifyToStructure
+ https://bugs.webkit.org/show_bug.cgi?id=101117
+
+ Reviewed by Gavin Barraclough.
+
+ We have logic to convert ArrayifyToStructure to StructureTransitionWatchpoint, which is awesome, except
+ that previously convertToStructureTransitionWatchpoint was (a) asserting that it never saw an
+ ArrayifyToStructure and (b) would incorrectly create a ForwardStructureTransitionWatchpoint if it did.
+
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
+
+2012-11-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::SpeculativeJIT::typedArrayDescriptor should use the Float64Array descriptor for Float64Arrays
+ https://bugs.webkit.org/show_bug.cgi?id=101114
+
+ Reviewed by Gavin Barraclough.
+
+ As in https://bugs.webkit.org/show_bug.cgi?id=101112, this was only wrong when Float64Array descriptors
+ hadn't been initialized yet. That happens rarely, but when it does happen, we would crash.
+
+ This would also become much more wrong if we ever put type size info (num bytes, etc) in the descriptor
+ and used that directly. So it's good to fix it.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
+
+2012-11-02 Filip Pizlo <fpizlo@apple.com>
+
+ JIT::privateCompileGetByVal should use the uint8ClampedArrayDescriptor for compiling accesses to Uint8ClampedArrays
+ https://bugs.webkit.org/show_bug.cgi?id=101112
+
+ Reviewed by Gavin Barraclough.
+
+ The only reason why the code was wrong to use uint8ArrayDescriptor instead is that if we're just using
+ Uint8ClampedArrays then the descriptor for Uint8Array may not have been initialized.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByVal):
+
+2012-11-02 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ MarkedBlocks should use something other than the mark bits to indicate liveness for newly allocated objects
+ https://bugs.webkit.org/show_bug.cgi?id=100877
+
+ Reviewed by Filip Pizlo.
+
+ Currently when we canonicalize cell liveness data in MarkedBlocks, we set the mark bit for every cell in the
+ block except for those in the free list. This allows us to consider objects that were allocated since the
+ previous collection to be considered live until they have a chance to be properly marked by the collector.
+
+ If we want to use the mark bits to signify other types of information, e.g. using sticky mark bits for generational
+ collection, we will have to keep track of newly allocated objects in a different fashion when we canonicalize cell liveness.
+
+ One method would be to allocate a separate set of bits while canonicalizing liveness data. These bits would
+ track the newly allocated objects in the block separately from those objects who had already been marked. We would
+ then check these bits, along with the mark bits, when determining liveness.
+
+ * heap/Heap.h:
+ (Heap):
+ (JSC::Heap::isLive): We now check for the presence of the newlyAllocated Bitmap.
+ (JSC):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::specializedSweep): We clear the newlyAllocated Bitmap if we're creating a free list. This
+ will happen if we canonicalize liveness data for some other reason than collection (e.g. forEachCell) and
+ then start allocating again.
+ (JSC::SetNewlyAllocatedFunctor::SetNewlyAllocatedFunctor):
+ (SetNewlyAllocatedFunctor):
+ (JSC::SetNewlyAllocatedFunctor::operator()): We set the newlyAllocated bits for all the objects
+ that aren't already marked. We undo the bits for the objects in the free list later in canonicalizeCellLivenessData.
+ (JSC::MarkedBlock::canonicalizeCellLivenessData): We should never have a FreeListed block with a newlyAllocated Bitmap.
+ We allocate the new Bitmap, set the bits for all the objects that aren't already marked, and then unset all of the
+ bits for the items currently in the FreeList.
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::clearMarks): We clear the newlyAllocated bitmap if it exists because at this point we don't need it
+ any more.
+ (JSC::MarkedBlock::isEmpty): If we have some objects that are newlyAllocated, we are not empty.
+ (JSC::MarkedBlock::isNewlyAllocated):
+ (JSC):
+ (JSC::MarkedBlock::setNewlyAllocated):
+ (JSC::MarkedBlock::clearNewlyAllocated):
+ (JSC::MarkedBlock::isLive): We now check the newlyAllocated Bitmap, if it exists, when determining liveness of a cell in
+ a block that is Marked.
+ * heap/WeakBlock.cpp:
+ (JSC::WeakBlock::visit): We need to make sure we don't finalize objects that are in the newlyAllocated Bitmap.
+ (JSC::WeakBlock::reap): Ditto.
+
+2012-11-02 Filip Pizlo <fpizlo@apple.com>
+
+ JIT::privateCompileGetByVal should use MacroAssemblerCodePtr::createFromExecutableAddress like JIT::privateCompilePutByVal
+ https://bugs.webkit.org/show_bug.cgi?id=101109
+
+ Reviewed by Gavin Barraclough.
+
+ This fixes crashes on ARMv7 resulting from the return address already being tagged with the THUMB2 bit.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByVal):
+
+2012-11-02 Simon Fraser <simon.fraser@apple.com>
+
+ Enable SUBPIXEL_LAYOUT on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=101076
+
+ Reviewed by Dave Hyatt.
+
+ Define ENABLE_SUBPIXEL_LAYOUT and include it in FEATURE_DEFINES.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-11-02 Michael Saboff <msaboff@apple.com>
+
+ RegExp.prototype.toString Should Produce an 8 bit JSString if possible.
+ https://bugs.webkit.org/show_bug.cgi?id=101003
+
+ Reviewed by Geoffrey Garen.
+
+ Took the logic of regExpObjectSource() and created two templated helpers that uses the
+ source character type when appending to the StringBuilder.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::appendLineTerminatorEscape): Checks line terminate type to come up with escaped version.
+ (JSC::regExpObjectSourceInternal): Templated version of original.
+ (JSC::regExpObjectSource): Wrapper function.
+
+2012-11-02 Adam Barth <abarth@webkit.org>
+
+ ENABLE(UNDO_MANAGER) is disabled everywhere and is not under active development
+ https://bugs.webkit.org/show_bug.cgi?id=100711
+
+ Reviewed by Eric Seidel.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-11-02 Simon Hausmann <simon.hausmann@digia.com>
+
+ [Qt] Fix build on Windows when Qt is configured with -release
+ https://bugs.webkit.org/show_bug.cgi?id=101041
+
+ Reviewed by Jocelyn Turcotte.
+
+ When Qt is configured with -debug or -release, the release/debug build of for example
+ QtCore is not available by default. For LLIntExtractor we always need to build debug
+ _and_ release versions, but we do not actually need any Qt libraries nor qtmain(d).lib.
+ Therefore we can disable all these features but need to keep $$QT.core.includes in the
+ INCLUDEPATH for some defines from qglobal.h.
+
+ * LLIntOffsetsExtractor.pro:
+
+2012-11-01 Mark Lam <mark.lam@apple.com>
+
+ A llint workaround for a toolchain issue.
+ https://bugs.webkit.org/show_bug.cgi?id=101012.
+
+ Reviewed by Michael Saboff.
+
+ * llint/LowLevelInterpreter.asm:
+ - use a local label to workaround the toolchain issue with undeclared
+ global labels.
+
+2012-11-01 Oliver Hunt <oliver@apple.com>
+
+ Remove GlobalObject constant register that is typically unused
+ https://bugs.webkit.org/show_bug.cgi?id=101005
+
+ Reviewed by Geoffrey Garen.
+
+ The GlobalObject constant register is frequently allocated even when it
+ is not used, it is also getting in the way of some other optimisations.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+
+2012-10-31 Filip Pizlo <fpizlo@apple.com>
+
+ DFG optimized string access code should be enabled
+ https://bugs.webkit.org/show_bug.cgi?id=100825
+
+ Reviewed by Oliver Hunt.
+
+ - Removes prediction checks from the parser.
+
+ - Fixes the handling of array mode refinement for strings. I.e. we don't do
+ any refinement - we already know it's going to be a string. We could
+ revisit this in the future, but for now the DFG lacks the ability to
+ handle any array modes other than Array::String for string intrinsics, so
+ this is as good as it gets.
+
+ - Removes uses of isBlahSpeculation for checking if a mode is already
+ checked. isBlahSpeculation implicitly checks if the SpeculatedType is not
+ BOTTOM ("empty"), which breaks for checking if a mode is already checked
+ since a mode may already be "checked" in the sense that we've proven that
+ the code is unreachable.
+
+ ~1% speed-up on V8v7, mostly from a speed-up on crypto, which uses string
+ intrinsics in one of the hot functions.
+
+ * bytecode/SpeculatedType.h:
+ (JSC::speculationChecked):
+ (JSC):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::alreadyChecked):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
+
+2012-10-31 Filip Pizlo <fpizlo@apple.com>
+
+ Sparse array size threshold should be increased to 100000
+ https://bugs.webkit.org/show_bug.cgi?id=100827
+
+ Reviewed by Oliver Hunt.
+
+ This enables the use of contiguous arrays in programs that previously
+ couldn't use them. And I so far can't see any examples of this being
+ a downside. To the extent that there is a downside, it ought to be
+ addressed by GC: https://bugs.webkit.org/show_bug.cgi?id=100828
+
+ * runtime/ArrayConventions.h:
+ (JSC):
+
+2012-10-31 Mark Lam <mark.lam@apple.com>
+
+ C++ llint 64-bit backend needs to zero extend results of int32 operations.
+ https://bugs.webkit.org/show_bug.cgi?id=100899.
+
+ Reviewed by Filip Pizlo.
+
+ llint asm instructions ending in "i" for a 64-bit machine expects the
+ high 32-bit of registers to be zero'ed out when a 32-bit instruction
+ writes into a register. Fixed the C++ llint to honor this.
+
+ Fixed the index register used in BaseIndex addressing to be of size
+ intptr_t as expected.
+
+ Updated CLoopRegister to handle different endiannesss configurations.
+
+ * llint/LowLevelInterpreter.cpp:
+ (JSC::CLoopRegister::clearHighWord):
+ - new method to clear the high 32-bit of a 64-bit register.
+ It's a no-op for the 32-bit build.
+ (CLoopRegister):
+ - CLoopRegister now takes care of packing and byte endianness order.
+ (JSC::CLoop::execute): - Added an assert.
+ * offlineasm/cloop.rb:
+ - Add calls to clearHighWord() wherever needed.
+
+2012-10-31 Mark Lam <mark.lam@apple.com>
+
+ A JSC printf (support for %J+s and %b).
+ https://bugs.webkit.org/show_bug.cgi?id=100566.
+
+ Reviewed by Michael Saboff.
+
+ Added VMInspector::printf(), fprintf(), sprintf(), and snprintf().
+ - %b prints ints as boolean TRUE (non-zero) or FALSE (zero).
+ - %Js prints a WTF::String* like a %s prints a char*.
+ Also works for 16bit WTF::Strings (prints wchar_t* using %S).
+ - '+' is a modifier meaning 'use verbose mode', and %J+s is an example
+ of its use.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * interpreter/VMInspector.cpp:
+ (FormatPrinter):
+ (JSC::FormatPrinter::~FormatPrinter):
+ (JSC::FormatPrinter::print):
+ (JSC::FormatPrinter::printArg):
+ (JSC::FormatPrinter::printWTFString):
+ (JSC::FileFormatPrinter::FileFormatPrinter):
+ (JSC::FileFormatPrinter::printArg):
+ (JSC::StringFormatPrinter::StringFormatPrinter):
+ (JSC::StringFormatPrinter::printArg):
+ (JSC::StringNFormatPrinter::StringNFormatPrinter):
+ (JSC::StringNFormatPrinter::printArg):
+ (JSC::VMInspector::fprintf):
+ (JSC::VMInspector::printf):
+ (JSC::VMInspector::sprintf):
+ (JSC::VMInspector::snprintf):
+ * interpreter/VMInspector.h:
+ (VMInspector):
+
+2012-10-31 Mark Lam <mark.lam@apple.com>
+
+ 64-bit llint PC offset can be negative: using an unsigned shift is a bug.
+ https://bugs.webkit.org/show_bug.cgi?id=100896.
+
+ Reviewed by Filip Pizlo.
+
+ Fixed the PC offset divisions in the 64-bit llint asm to use rshift instead of urshift.
+
+ * llint/LowLevelInterpreter64.asm:
+
+2012-10-30 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ glsl-function-atan.html WebGL conformance test fails after https://bugs.webkit.org/show_bug.cgi?id=99154
+ https://bugs.webkit.org/show_bug.cgi?id=100789
+
+ Reviewed by Filip Pizlo.
+
+ We accidently missed a bitwise double to int64 conversion.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::silentFill):
+
+2012-10-30 Joseph Pecoraro <pecoraro@apple.com>
+
+ [Mac] Sync up FeatureDefine Configuration Files
+ https://bugs.webkit.org/show_bug.cgi?id=100171
+
+ Reviewed by David Kilzer.
+
+ Follow up to better coordinate with iOS feature defines. Make:
+
+ - ENABLE_FILTERS always on
+ - ENABLE_INPUT_* iphonesimulator values point to the iphoneos values
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-30 Joseph Pecoraro <pecoraro@apple.com>
+
+ [Mac] Sync up FeatureDefine Configuration Files
+ https://bugs.webkit.org/show_bug.cgi?id=100171
+
+ Reviewed by David Kilzer.
+
+ Ensure an identical FeatureDefine files across all projects. Changes:
+
+ - ENABLE_CSS_BOX_DECORATION_BREAK should be in all
+ - ENABLE_PDFKIT_PLUGIN should be in all
+ - ENABLE_RESOLUTION_MEDIA_QUERY should be in all
+ - ENABLE_ENCRYPTED_MEDIA should be in all
+ - ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING with corrected value
+ - Some alphabetical ordering cleanup
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-30 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Arrays can change IndexingType in the middle of sorting
+ https://bugs.webkit.org/show_bug.cgi?id=100773
+
+ Reviewed by Filip Pizlo.
+
+ Instead of giving up, we just fetch the appropriate vector based on the current
+ IndexingType of the array.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::sortVector):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC::JSObject::currentIndexingData):
+ (JSC::JSObject::currentRelevantLength):
+
+2012-10-29 Anders Carlsson <andersca@apple.com>
+
+ Build WebKit as C++11 on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=100720
+
+ Reviewed by Daniel Bates.
+
+ * Configurations/Base.xcconfig:
+ Add CLANG_CXX_LANGUAGE_STANDARD=gnu++0x.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::pushFinallyContext):
+ (JSC::BytecodeGenerator::beginSwitch):
+ * llint/LLIntOffsetsExtractor.cpp:
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add8):
+ * runtime/Identifier.h:
+ (JSC::Identifier::add):
+ * runtime/JSONObject.cpp:
+ (JSC::appendStringToStringBuilder):
+ * runtime/StringPrototype.cpp:
+ (JSC::replaceUsingStringSearch):
+ Add static_casts to prevent implicit type conversions in non-constant initializer lists.
+
+2012-10-28 Mark Rowe <mrowe@apple.com>
+
+ Simplify Xcode configuration settings that used to vary between OS versions.
+
+ Reviewed by Dan Bernstein.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+ * Configurations/JavaScriptCore.xcconfig:
+
+2012-10-28 Mark Rowe <mrowe@apple.com>
+
+ Remove references to unsupported OS and Xcode versions.
+
+ Reviewed by Anders Carlsson.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/CompilerVersion.xcconfig: Removed.
+ * Configurations/DebugRelease.xcconfig:
+ * Configurations/Version.xcconfig:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2012-10-29 Michael Saboff <msaboff@apple.com>
+
+ Non-special escape character sequences cause JSC::Lexer::parseString to create 16 bit strings
+ https://bugs.webkit.org/show_bug.cgi?id=100576
+
+ Reviewed by Darin Adler.
+
+ Changed singleEscape() processing to be based on a lookup of a static table. The table
+ covers ASCII characters SPACE through DEL. If a character can be a single character escape,
+ then the table provides the non-zero result of that escape. Updated the result of
+ singleEscape to be an LChar to make the table as small as possible.
+ Added a new test fast/js/normal-character-escapes-in-string-literals.html to validated
+ the behavior.
+
+ * parser/Lexer.cpp:
+ (JSC::singleEscape):
+ (JSC::Lexer::parseString):
+ (JSC::Lexer::parseStringSlowCase):
+
+2012-10-29 Enrica Casucci <enrica@apple.com>
+
+ Add ENABLE_USERSELECT_ALL feature flag.
+ https://bugs.webkit.org/show_bug.cgi?id=100559
+
+ Reviewed by Eric Seidel.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-28 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should be able to emit effectful structure checks
+ https://bugs.webkit.org/show_bug.cgi?id=99260
+
+ Reviewed by Oliver Hunt.
+
+ This change allows us to find out if an array access that has gone polymorphic
+ is operating over known structures - i.e. the primordial array structures of the
+ global object that the code block containing the array access belongs to. We
+ term this state "OriginalArray" for short. The fact that the access has gone
+ polymorphic means that the array profile will not be able to report the set of
+ structures it had seen - but if it can tell us that all of the structures were
+ primordial then it just so happens that we can deduce what the structure set
+ would have been by just querying the code block's global object. This allows us
+ to emit an ArrayifyToStructure instead of an Arrayify if we find that we need to
+ do conversions. The fast path of an ArrayifyToStructure is exactly like the fast
+ path of a CheckStructure and is mostly subject to the same optimizations. It
+ also burns one fewer registers.
+
+ Essentially the notion of OriginalArray is a super cheap way of getting the
+ array profile to tell us a structure set instead of a singleton structure.
+ Currently, the array profile can only tell us the structure seen at an array
+ access if there was exactly one structure. If there were multiple structures, it
+ won't tell us anything other than the array modes and other auxiliary profiling
+ data (whether there were stores to holes, for example). With OriginalArray, we
+ cheaply get a structure set if all of the structures were primordial for the
+ code block's global object, since in that case the array mode set (ArrayModes)
+ can directly tell us the structure set. In the future, we might consider adding
+ complete structure sets to the array profiles, but I suspect that we would hit
+ diminishing returns if we did so - it would only help if we have array accesses
+ that are both polymorphic and are cross-global-object accesses (rare) or if the
+ arrays had named properties or other structure transitions that are unrelated to
+ indexing type (also rare).
+
+ This also does away with Arrayify (and the new ArrayifyToStructure) returning
+ the butterfly pointer. This turns out to be faster and easier to CSE.
+
+ And, this also changes constant folding to be able to eliminate CheckStructure,
+ ForwardCheckStructure, and ArrayifyToStructure in addition to being able to
+ transform them into structure transition watchpoints. This is great for
+ ArrayifyToStructure because then CSE and CFA know that there is no side effect.
+ Converting CheckStructure and ForwardCheckStructure to also behave this way is
+ just a matter of elegance.
+
+ This has no performance impact right now. It's intended to alleviate some of the
+ regressions seen in the early implementation of
+ https://bugs.webkit.org/show_bug.cgi?id=98606.
+
+ * bytecode/ArrayProfile.cpp:
+ (JSC::ArrayProfile::computeUpdatedPrediction):
+ * bytecode/ArrayProfile.h:
+ (JSC):
+ (JSC::ArrayProfile::ArrayProfile):
+ (ArrayProfile):
+ (JSC::ArrayProfile::usesOriginalArrayStructures):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::fromObserved):
+ (JSC::DFG::ArrayMode::alreadyChecked):
+ (JSC::DFG::arrayClassToString):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::ArrayMode::withProfile):
+ (JSC::DFG::ArrayMode::isJSArray):
+ (ArrayMode):
+ (JSC::DFG::ArrayMode::isJSArrayWithOriginalStructure):
+ (JSC::DFG::ArrayMode::supportsLength):
+ (JSC::DFG::ArrayMode::arrayModesWithIndexingShape):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getArrayMode):
+ (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::checkStructureElimination):
+ (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::checkArrayElimination):
+ (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasStructure):
+ (JSC::DFG::Node::hasArrayMode):
+ (JSC::DFG::Node::arrayMode):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::isOriginalArrayStructure):
+ * runtime/Structure.cpp:
+ (JSC::Structure::nonPropertyTransition):
+
+2012-10-28 Filip Pizlo <fpizlo@apple.com>
+
+ There should not be blind spots in array length array profiling
+ https://bugs.webkit.org/show_bug.cgi?id=100620
+
+ Reviewed by Oliver Hunt.
+
+ I don't think this has any performance impact. But it's good to not have random
+ programs occasionally emit a GetById for array length accesses.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+
+2012-10-28 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, make always-true enum-to-int comparisons use casts.
+
+ * dfg/DFGFPRInfo.h:
+ (JSC::DFG::FPRInfo::debugName):
+ * dfg/DFGGPRInfo.h:
+ (JSC::DFG::JSValueSource::tagGPR):
+ (JSC::DFG::GPRInfo::toIndex):
+ (JSC::DFG::GPRInfo::debugName):
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::TypeInfo):
+
+2012-10-27 Filip Pizlo <fpizlo@apple.com>
+
+ OSR exit compilation should defend against argument recoveries from code blocks that are no longer on the inline stack
+ https://bugs.webkit.org/show_bug.cgi?id=100601
+
+ Reviewed by Oliver Hunt.
+
+ This happened to me while I was fixing bugs for https://bugs.webkit.org/show_bug.cgi?id=100599.
+ I'm not sure how to reproduce this.
+
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::baselineCodeBlockFor):
+ (AssemblyHelpers):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+
+2012-10-27 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::Array::Mode needs to be cleaned up
+ https://bugs.webkit.org/show_bug.cgi?id=100599
+
+ Reviewed by Oliver Hunt.
+
+ Turn the previous massive Array::Mode enum into a class that contains four
+ fields, the type, whether it's a JSArray, the level of speculation, and the
+ kind of conversion to perform.
+
+ No performance or behavioral change.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::ArrayMode::fromObserved):
+ (JSC::DFG::ArrayMode::refine):
+ (JSC::DFG::ArrayMode::alreadyChecked):
+ (JSC::DFG::arrayTypeToString):
+ (JSC::DFG::arrayClassToString):
+ (DFG):
+ (JSC::DFG::arraySpeculationToString):
+ (JSC::DFG::arrayConversionToString):
+ (JSC::DFG::ArrayMode::toString):
+ * dfg/DFGArrayMode.h:
+ (DFG):
+ (ArrayMode):
+ (JSC::DFG::ArrayMode::ArrayMode):
+ (JSC::DFG::ArrayMode::type):
+ (JSC::DFG::ArrayMode::arrayClass):
+ (JSC::DFG::ArrayMode::speculation):
+ (JSC::DFG::ArrayMode::conversion):
+ (JSC::DFG::ArrayMode::asWord):
+ (JSC::DFG::ArrayMode::fromWord):
+ (JSC::DFG::ArrayMode::withSpeculation):
+ (JSC::DFG::ArrayMode::usesButterfly):
+ (JSC::DFG::ArrayMode::isJSArray):
+ (JSC::DFG::ArrayMode::isInBounds):
+ (JSC::DFG::ArrayMode::mayStoreToHole):
+ (JSC::DFG::ArrayMode::isOutOfBounds):
+ (JSC::DFG::ArrayMode::isSlowPut):
+ (JSC::DFG::ArrayMode::canCSEStorage):
+ (JSC::DFG::ArrayMode::lengthNeedsStorage):
+ (JSC::DFG::ArrayMode::modeForPut):
+ (JSC::DFG::ArrayMode::isSpecific):
+ (JSC::DFG::ArrayMode::supportsLength):
+ (JSC::DFG::ArrayMode::benefitsFromStructureCheck):
+ (JSC::DFG::ArrayMode::doesConversion):
+ (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
+ (JSC::DFG::ArrayMode::operator==):
+ (JSC::DFG::ArrayMode::operator!=):
+ (JSC::DFG::ArrayMode::arrayModesWithIndexingShape):
+ (JSC::DFG::canCSEStorage):
+ (JSC::DFG::lengthNeedsStorage):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getArrayMode):
+ (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::getArrayLengthElimination):
+ (JSC::DFG::CSEPhase::checkArrayElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::arrayMode):
+ (JSC::DFG::Node::setArrayMode):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::typedArrayDescriptor):
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray):
+ (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
+ (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
+ (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+ (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-27 Dan Bernstein <mitz@apple.com>
+
+ REAL_PLATFORM_NAME build setting is no longer needed
+ https://bugs.webkit.org/show_bug.cgi?id=100587
+
+ Reviewed by Mark Rowe.
+
+ Removed the definition of REAL_PLATFORM_NAME and replaced references to it with references
+ to PLATFORM_NAME.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/CompilerVersion.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+ * Configurations/FeatureDefines.xcconfig:
+ * Configurations/JSC.xcconfig:
+ * Configurations/JavaScriptCore.xcconfig:
+ * Configurations/ToolExecutable.xcconfig:
+
+2012-10-25 Filip Pizlo <fpizlo@apple.com>
+
+ Forward OSR calculation is wrong in the presence of multiple SetLocals, or a mix of SetLocals and Phantoms
+ https://bugs.webkit.org/show_bug.cgi?id=100461
+
+ Reviewed by Oliver Hunt and Gavin Barraclough.
+
+ This does a couple of things. First, it removes the part of the change in r131822 that made the forward
+ OSR exit calculator capable of handling multiple SetLocals. That change was wrong, because it would
+ blindly assume that all SetLocals had the same ValueRecovery, and would ignore the possibility that if
+ there is no value recovery then a ForwardCheckStructure on the first SetLocal would not know how to
+ recover the state associated with the second SetLocal. Then, it introduces the invariant that any bytecode
+ op that decomposes into multiple SetLocals must first emit dead SetLocals as hints and then emit a second
+ set of SetLocals to actually do the setting of the locals. This means that if a ForwardCheckStructure (or
+ any other hoisted forward speculation) is inserted, it will always be inserted on the second set of
+ SetLocals (since hoisting only touches the live ones), at which point OSR will already know about the
+ mov hints implied by the first set of (dead) SetLocals. This gives us the behavior we wanted, namely, that
+ a ForwardCheckStructure applied to a variant set by a resolve_with_base-like operation can correctly do a
+ forward exit while also ensuring that prior to exiting we set the appropriate locals.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+
+2012-10-26 Simon Hausmann <simon.hausmann@digia.com>
+
+ [Qt] Fix the LLInt build on Windows
+ https://bugs.webkit.org/show_bug.cgi?id=97648
+
+ Reviewed by Tor Arne Vestbø.
+
+ The main change for the port on Windows is changing the way offsets are extracted
+ and the LLIntAssembly.h is generated to accomodate release and debug configurations.
+
+ Firstly the LLIntOffsetsExtractor binary is now built as-is (no DESTDIR set) and
+ placed into debug\LLIntOffsetsExtractor.exe and release\LLIntOffsetsExtractor.exe
+ on Windows debug_and_release builds. On other patforms it remainds in the regular
+ out directory.
+
+ Secondly the LLIntAssembly.h files must be different for different build types,
+ so the LLIntAssembly.h generator in DerivedSources.pri operates no on the extractor
+ binary files as input. Using a simple exists() check we verify the presence of either
+ a regular, a debug\LLIntOffsetsExtractor and a release\LLIntOffsetsExtractor binary
+ and process all of them. The resulting assembly files consequently end up in
+ generated\debug\LLIntAssembly.h and generated\release\LLIntAssembly.h.
+
+ In Target.pri we have to also make sure that those directories are in the include
+ path according to the release or debug configuration.
+
+ Lastly a small tweak - swapping WTF.pri and JSC.pri inclusions - in the
+ LLIntOffsetsExtractor build was needed to make sure that we include
+ JavaScriptCore/config.h instead of WTF/config.h, required to fix the
+ build issues originally pasted in bug #97648.
+
+ * DerivedSources.pri:
+ * JavaScriptCore.pro:
+ * LLIntOffsetsExtractor.pro:
+ * Target.pri:
+
+2012-10-26 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ [Qt] Enable JSC's disassembler on x86, x86_64 Linux
+ https://bugs.webkit.org/show_bug.cgi?id=100386
+
+ Reviewed by Simon Hausmann.
+
+ It works fine on Linux x86, x86_64 just needs to be enabled in the
+ QtWebKit build system.
+
+ * DerivedSources.pri:
+ * JavaScriptCore.pri:
+ * Target.pri:
+
+2012-10-26 Thiago Marcos P. Santos <thiago.santos@intel.com>
+
+ Add feature flags for CSS Device Adaptation
+ https://bugs.webkit.org/show_bug.cgi?id=95960
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-26 Simon Hausmann <simon.hausmann@digia.com>
+
+ [WIN] Make LLInt offsets extractor work on Windows
+ https://bugs.webkit.org/show_bug.cgi?id=100369
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Open the input file explicitly in binary mode to prevent ruby/Windows from thinking that
+ it's a text mode file that needs even new line conversions. The binary mode parameter is
+ ignored on other platforms.
+
+ * offlineasm/offsets.rb:
+
+2012-10-25 Michael Saboff <msaboff@apple.com>
+
+ SymbolTableIndexHashTraits::needsDestruction should be set to true
+ https://bugs.webkit.org/show_bug.cgi?id=100437
+
+ Reviewed by Mark Hahnenberg.
+
+ For correctness, set SymbolTableIndexHashTraits::needsDestruction to true since SymbolTableEntry's do
+ need to have their destructor called due to the possibility of rare data.
+
+ * runtime/SymbolTable.h:
+ (SymbolTableIndexHashTraits):
+
+2012-10-25 Filip Pizlo <fpizlo@apple.com>
+
+ DFG Arrayify elimination should replace it with GetButterfly rather than Phantom
+ https://bugs.webkit.org/show_bug.cgi?id=100441
+
+ Reviewed by Oliver Hunt and Gavin Barraclough.
+
+ Made array profiler's to-string helper behave correctly.
+
+ Made Arrayify elimination do the right thing (convert to GetButterfly).
+
+ Made CFA's interference analysis track clobbered array modes correctly, mostly by
+ simplifying the machinery.
+
+ * bytecode/ArrayProfile.cpp:
+ (JSC::arrayModesToString):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::clobberArrayModes):
+ (AbstractValue):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+
+2012-10-25 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION (r131793-r131826): Crash going to wikifonia.org
+ https://bugs.webkit.org/show_bug.cgi?id=100281
+
+ Reviewed by Oliver Hunt.
+
+ Restore something that got lost in the resolve refactoring: the ability to give up on life if
+ we see a resolve of 'arguments'.
+
+ * runtime/JSScope.cpp:
+ (JSC::JSScope::resolveContainingScopeInternal):
+
+2012-10-25 Dominik Röttsches <dominik.rottsches@intel.com>
+
+ Conditionalize XHR timeout support
+ https://bugs.webkit.org/show_bug.cgi?id=100356
+
+ Reviewed by Adam Barth.
+
+ Adding XHR_TIMEOUT feature to conditionalize this on ports without network backend support.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-25 Michael Saboff <msaboff@apple.com>
+
+ REGRESSION (r131836): failures in list styles tests on EFL, GTK
+ https://bugs.webkit.org/show_bug.cgi?id=99824
+
+ Reviewed by Oliver Hunt.
+
+ Saved start of string since it is modified by call convertUTF8ToUTF16().
+
+ * API/JSStringRef.cpp:
+ (JSStringCreateWithUTF8CString):
+
+2012-10-24 Filip Pizlo <fpizlo@apple.com>
+
+ DFG NewArrayBuffer node should keep its data in a structure on the side to free up one of the opInfos
+ https://bugs.webkit.org/show_bug.cgi?id=100328
+
+ Reviewed by Oliver Hunt.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGGraph.h:
+ (Graph):
+ * dfg/DFGNode.h:
+ (NewArrayBufferData):
+ (DFG):
+ (JSC::DFG::Node::newArrayBufferData):
+ (Node):
+ (JSC::DFG::Node::startConstant):
+ (JSC::DFG::Node::numConstants):
+
+2012-10-25 Mark Lam <mark.lam@apple.com>
+
+ Update the C++ llint to work with the latest op_resolve... changes.
+ https://bugs.webkit.org/show_bug.cgi?id=100345.
+
+ Reviewed by Oliver Hunt.
+
+ * llint/LowLevelInterpreter.cpp:
+ (JSC::CLoop::execute):
+ - emit opcode name as label when not using COMPUTED_GOTOs. The new op_resolve
+ opcodes have jumps to these labels.
+ - declare all opcode labels as UNUSED_LABEL()s to keep the compiler happy
+ for opcodes that are not referenced by anyone.
+ * offlineasm/asm.rb:
+ - strip llint_ prefix from opcode names used as labels.
+
+2012-10-24 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Refactor LLInt64 to distinguish the pointer operations from the 64-bit integer operations
+ https://bugs.webkit.org/show_bug.cgi?id=100321
+
+ Reviewed by Filip Pizlo.
+
+ We have refactored the MacroAssembler and JIT compilers to distinguish
+ the pointer operations from the 64-bit integer operations (see bug #99154).
+ Now we want to do the similar work for LLInt, and the goal is same as
+ the one mentioned in 99154.
+
+ This is the first part of the modification: in the offline assembler,
+ adding the support of the "<foo>q" instructions which will be used for
+ 64-bit integer operations.
+
+ * llint/LowLevelInterpreter.cpp:
+ (JSC::CLoop::execute):
+ * offlineasm/cloop.rb:
+ * offlineasm/instructions.rb:
+ * offlineasm/x86.rb:
+
+2012-10-24 Filip Pizlo <fpizlo@apple.com>
+
+ DFG compileBlahBlahByVal methods for Contiguous and ArrayStorage have only one caller and should be removed
+ https://bugs.webkit.org/show_bug.cgi?id=100311
+
+ Reviewed by Mark Hahnenberg.
+
+ Just trying to simplify things before I make them more complicated again.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-23 Andreas Kling <kling@webkit.org>
+
+ CodeBlock: Give m_putToBaseOperations an inline capacity.
+ <http://webkit.org/b/100190>
+ <rdar://problem/12562466>
+
+ Reviewed by Oliver Hunt.
+
+ Since the CodeBlock constructor always inserts a single PutToBaseOperation, but there's no
+ guarantee that more will follow, give the m_putToBaseOperations vector an inline capacity of 1.
+ There are 4009 of these Vectors on Membuster3, and only 126 of them have more than a single entry.
+
+ This change yields a 1.90MB reduction in memory usage.
+
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+
+2012-10-23 Christophe Dumez <christophe.dumez@intel.com>
+
+ Regression(r132143): Assertion hit in JSC::Interpreter::StackPolicy::StackPolicy(JSC::Interpreter&, const WTF::StackBounds&)
+ https://bugs.webkit.org/show_bug.cgi?id=100109
+
+ Reviewed by Oliver Hunt.
+
+ Fix possible integer overflow in StackPolicy constructor by
+ using size_t type instead of int for stack sizes. The value
+ returned by StackBounds::size() is of type size_t but was
+ assigned to an int, which may overflow.
+
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::Interpreter::StackPolicy::StackPolicy):
+
+2012-10-23 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add missing header file.
+
+2012-10-23 Mark Lam <mark.lam@apple.com>
+
+ Make topCallFrame reliable.
+ https://bugs.webkit.org/show_bug.cgi?id=98928.
+
+ Reviewed by Geoffrey Garen.
+
+ - VM entry points and the GC now uses topCallFrame.
+ - The callerFrame value in CallFrames are now always the previous
+ frame on the stack, except for the first frame which has a
+ callerFrame of 0 (not counting the HostCallFrameFlag).
+ Hence, we can now traverse every frame on the stack all the way
+ back to the first frame.
+ - GlobalExec's will no longer be used as the callerFrame values in
+ call frames.
+ - Added fences and traps for debugging the JSStack in debug builds.
+
+ * bytecode/SamplingTool.h:
+ (SamplingTool):
+ (JSC::SamplingTool::CallRecord::CallRecord):
+ * dfg/DFGOperations.cpp:
+ - Fixed 2 DFG helper functions to flush topCallFrame as expected.
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::prepareForExternalCall):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::callerFrameNoFlags):
+ (ExecState):
+ (JSC::ExecState::argIndexForRegister):
+ (JSC::ExecState::getArgumentUnsafe):
+ * interpreter/CallFrameClosure.h:
+ (CallFrameClosure):
+ * interpreter/Interpreter.cpp:
+ (JSC):
+ (JSC::eval):
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ (JSC::Interpreter::endRepeatCall):
+ * interpreter/Interpreter.h:
+ (JSC):
+ (Interpreter):
+ * interpreter/JSStack.cpp:
+ (JSC::JSStack::JSStack):
+ (JSC::JSStack::gatherConservativeRoots):
+ (JSC::JSStack::disableErrorStackReserve):
+ * interpreter/JSStack.h:
+ (JSC):
+ (JSStack):
+ (JSC::JSStack::installFence):
+ (JSC::JSStack::validateFence):
+ (JSC::JSStack::installTrapsAfterFrame):
+ * interpreter/JSStackInlines.h: Added.
+ (JSC):
+ (JSC::JSStack::getTopOfFrame):
+ (JSC::JSStack::getTopOfStack):
+ (JSC::JSStack::getStartOfFrame):
+ (JSC::JSStack::pushFrame):
+ (JSC::JSStack::popFrame):
+ (JSC::JSStack::generateFenceValue):
+ (JSC::JSStack::installFence):
+ (JSC::JSStack::validateFence):
+ (JSC::JSStack::installTrapsAfterFrame):
+ * jit/JITStubs.cpp:
+ (JSC::jitCompileFor):
+ (JSC::lazyLinkFor):
+ - Set frame->codeBlock to 0 for both the above because they are called
+ with partially intitialized frames (cb uninitialized), but may
+ trigger a GC.
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+2012-10-22 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::Array::Undecided should be called DFG::Array::SelectUsingPredictions
+ https://bugs.webkit.org/show_bug.cgi?id=100052
+
+ Reviewed by Oliver Hunt.
+
+ No functional change, just renaming. It's a clearer name that more accurately
+ reflects the meaning, and it eliminates the namespace confusion that will happen
+ with the Undecided indexing type in https://bugs.webkit.org/show_bug.cgi?id=98606
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::fromObserved):
+ (JSC::DFG::refineArrayMode):
+ (JSC::DFG::modeAlreadyChecked):
+ (JSC::DFG::modeToString):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::canCSEStorage):
+ (JSC::DFG::modeIsSpecific):
+ (JSC::DFG::modeSupportsLength):
+ (JSC::DFG::benefitsFromStructureCheck):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-22 Mark Lam <mark.lam@apple.com>
+
+ Change stack recursion checks to be based on stack availability.
+ https://bugs.webkit.org/show_bug.cgi?id=99872.
+
+ Reviewed by Filip Pizlo and Geoffrey Garen.
+
+ - Remove m_reentryDepth, ThreadStackType which are now obsolete.
+ - Replaced the reentryDepth checks with a StackBounds check.
+ - Added the Interpreter::StackPolicy class to compute a reasonable
+ stack capacity requirement given the native stack that the
+ interpreter is executing on at that time.
+ - Reserved an amount of JSStack space for the use of error handling
+ and enable its use (using Interpreter::ErrorHandlingMode) when
+ we're about to throw or report an exception.
+ - Interpreter::StackPolicy also allows more native stack space
+ to be used when in ErrorHandlingMode. This is needed in the case
+ of native stack overflows.
+ - Fixed the parser so that it throws a StackOverflowError instead of
+ a SyntaxError when it encounters a stack overflow.
+
+ * API/JSContextRef.cpp:
+ (JSContextGroupCreate):
+ (JSGlobalContextCreateInGroup):
+ * JavaScriptCore.order:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::ErrorHandlingMode::ErrorHandlingMode):
+ (JSC):
+ (JSC::Interpreter::ErrorHandlingMode::~ErrorHandlingMode):
+ (JSC::Interpreter::StackPolicy::StackPolicy):
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ * interpreter/Interpreter.h:
+ (JSC):
+ (Interpreter):
+ (ErrorHandlingMode):
+ (StackPolicy):
+ (JSC::Interpreter::StackPolicy::requiredCapacity):
+ * interpreter/JSStack.cpp:
+ (JSC):
+ (JSC::JSStack::JSStack):
+ (JSC::JSStack::growSlowCase):
+ (JSC::JSStack::enableErrorStackReserve):
+ (JSC::JSStack::disableErrorStackReserve):
+ * interpreter/JSStack.h:
+ (JSStack):
+ (JSC::JSStack::reservationEnd):
+ (JSC):
+ * jsc.cpp:
+ (jscmain):
+ * parser/Parser.cpp:
+ (JSC::::Parser):
+ * parser/Parser.h:
+ (Parser):
+ (JSC::::parse):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::throwStackOverflowError):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::createContextGroup):
+ (JSC::JSGlobalData::create):
+ (JSC::JSGlobalData::createLeaked):
+ (JSC::JSGlobalData::sharedInstance):
+ * runtime/JSGlobalData.h:
+ (JSC):
+ (JSGlobalData):
+ * runtime/StringRecursionChecker.h:
+ (JSC::StringRecursionChecker::performCheck):
+ * testRegExp.cpp:
+ (realMain):
+
+2012-10-20 Martin Robinson <mrobinson@igalia.com>
+
+ Fix 'make dist' for the GTK+ port
+
+ * GNUmakefile.list.am: Add missing files to the source list.
+
+2012-10-21 Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+
+ [CMake][JSC] Depend on risc.rb to decide when to run the LLInt scripts.
+ https://bugs.webkit.org/show_bug.cgi?id=99917
+
+ Reviewed by Geoffrey Garen.
+
+ Depend on the newly-added risc.rb to make sure we always run the
+ LLInt scripts when one of them changes.
+
+ * CMakeLists.txt:
+
+2012-10-20 Filip Pizlo <fpizlo@apple.com>
+
+ LLInt backends of non-ARM RISC platforms should be able to share code with the existing ARMv7 backend
+ https://bugs.webkit.org/show_bug.cgi?id=99745
+
+ Reviewed by Geoffrey Garen.
+
+ This moves all of the things in armv7.rb that I thought are generally useful out
+ into risc.rb. It also separates some phases (branch ops is separated into one
+ phase that does sensible things, and another that does things that are painfully
+ ARM-specific), and removes ARM assumptions from others by using a callback to
+ drive exactly what lowering must happen. The goal here is to minimize the future
+ maintenance burden of LLInt by ensuring that the various platforms share as much
+ lowering code as possible.
+
+ * offlineasm/armv7.rb:
+ * offlineasm/risc.rb: Added.
+
+2012-10-19 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should have some facility for recognizing redundant CheckArrays and Arrayifies
+ https://bugs.webkit.org/show_bug.cgi?id=99287
+
+ Reviewed by Mark Hahnenberg.
+
+ Adds reasoning about indexing type sets (i.e. ArrayModes) to AbstractValue, which
+ then enables us to fold away CheckArray's and Arrayify's that are redundant.
+
+ * bytecode/ArrayProfile.cpp:
+ (JSC::arrayModesToString):
+ (JSC):
+ * bytecode/ArrayProfile.h:
+ (JSC):
+ (JSC::mergeArrayModes):
+ (JSC::arrayModesAlreadyChecked):
+ * bytecode/StructureSet.h:
+ (JSC::StructureSet::arrayModesFromStructures):
+ (StructureSet):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::AbstractValue):
+ (JSC::DFG::AbstractValue::clear):
+ (JSC::DFG::AbstractValue::isClear):
+ (JSC::DFG::AbstractValue::makeTop):
+ (JSC::DFG::AbstractValue::clobberStructures):
+ (AbstractValue):
+ (JSC::DFG::AbstractValue::setMostSpecific):
+ (JSC::DFG::AbstractValue::set):
+ (JSC::DFG::AbstractValue::operator==):
+ (JSC::DFG::AbstractValue::merge):
+ (JSC::DFG::AbstractValue::filter):
+ (JSC::DFG::AbstractValue::filterArrayModes):
+ (JSC::DFG::AbstractValue::validate):
+ (JSC::DFG::AbstractValue::checkConsistency):
+ (JSC::DFG::AbstractValue::dump):
+ (JSC::DFG::AbstractValue::clobberArrayModes):
+ (JSC::DFG::AbstractValue::clobberArrayModesSlow):
+ (JSC::DFG::AbstractValue::setFuturePossibleStructure):
+ (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::modeAlreadyChecked):
+ * dfg/DFGArrayMode.h:
+ (JSC::DFG::arrayModesFor):
+ (DFG):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::arrayify):
+
+2012-10-19 Filip Pizlo <fpizlo@apple.com>
+
+ Baseline JIT should not inline array allocations, to make them easier to instrument
+ https://bugs.webkit.org/show_bug.cgi?id=99905
+
+ Reviewed by Mark Hahnenberg.
+
+ This will make it easier to instrument array allocations for the purposes of profiling.
+ It also allows us to kill off a bunch of code. And, this doesn't appear to hurt
+ performance at all. That's expected because these days any hot allocation will end up
+ in the DFG JIT, which does inline these allocations.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITInlineMethods.h:
+ (JSC):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_array):
+
+2012-10-19 Oliver Hunt <oliver@apple.com>
+
+ Fix some of the regression cause by the non-local variable reworking
+ https://bugs.webkit.org/show_bug.cgi?id=99896
+
+ Reviewed by Filip Pizlo.
+
+ The non0local variable reworking led to some of the optimisations performed by
+ the bytecode generator being dropped. This in turn put more pressure on the DFG
+ optimisations. This exposed a short coming in our double speculation propogation.
+ Now we try to distinguish between places where we should SpecDoubleReal vs generic
+ SpecDouble.
+
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
+ (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPredictions):
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
+2012-10-19 Michael Saboff <msaboff@apple.com>
+
+ Lexer should create 8 bit Identifiers for RegularExpressions and ASCII identifiers
+ https://bugs.webkit.org/show_bug.cgi?id=99855
+
+ Reviewed by Filip Pizlo.
+
+ Added makeIdentifier helpers that will always make an 8 bit Identifier or make an
+ Identifier that is the same size as the template parameter. Used the first in the fast
+ path when looking for a JS identifier and the second when scanning regular expressions.
+
+ * parser/Lexer.cpp:
+ (JSC::::scanRegExp):
+ * parser/Lexer.h:
+ (Lexer):
+ (JSC::::makeIdentifierSameType):
+ (JSC::::makeLCharIdentifier):
+ (JSC::::lexExpectIdentifier):
+
+2012-10-19 Mark Lam <mark.lam@apple.com>
+
+ Added WTF::StackStats mechanism.
+ https://bugs.webkit.org/show_bug.cgi?id=99805.
+
+ Reviewed by Geoffrey Garen.
+
+ Added StackStats checkpoints and probes.
+
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitNode):
+ (JSC::BytecodeGenerator::emitNodeInConditionContext):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::append):
+ (JSC::visitChildren):
+ (JSC::SlotVisitor::donateKnownParallel):
+ (JSC::SlotVisitor::drain):
+ (JSC::SlotVisitor::drainFromShared):
+ (JSC::SlotVisitor::mergeOpaqueRoots):
+ (JSC::SlotVisitor::internalAppend):
+ (JSC::SlotVisitor::harvestWeakReferences):
+ (JSC::SlotVisitor::finalizeUnconditionalFinalizers):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ * parser/Parser.h:
+ (JSC::Parser::canRecurse):
+ * runtime/StringRecursionChecker.h:
+ (StringRecursionChecker):
+
+2012-10-19 Oliver Hunt <oliver@apple.com>
+
+ REGRESSION(r131822): It made 500+ tests crash on 32 bit platforms
+ https://bugs.webkit.org/show_bug.cgi?id=99814
+
+ Reviewed by Filip Pizlo.
+
+ Call the correct macro in 32bit.
+
+ * llint/LowLevelInterpreter.asm:
+
+2012-10-19 Dongwoo Joshua Im <dw.im@samsung.com>
+
+ Rename ENABLE_CSS3_TEXT_DECORATION to ENABLE_CSS3_TEXT
+ https://bugs.webkit.org/show_bug.cgi?id=99804
+
+ Reviewed by Julien Chaffraix.
+
+ CSS3 text related properties will be implemented under this flag,
+ including text decoration, text-align-last, and text-justify.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-18 Anders Carlsson <andersca@apple.com>
+
+ Clean up RegExpKey
+ https://bugs.webkit.org/show_bug.cgi?id=99798
+
+ Reviewed by Darin Adler.
+
+ RegExpHash doesn't need to be a class template specialization when the class template is specialized
+ for JSC::RegExpKey only. Make it a nested class of RegExp instead. Also, make operator== a friend function
+ so Hash::equal can see it.
+
+ * runtime/RegExpKey.h:
+ (JSC::RegExpKey::RegExpKey):
+ (JSC::RegExpKey::operator==):
+ (RegExpKey):
+ (JSC::RegExpKey::Hash::hash):
+ (JSC::RegExpKey::Hash::equal):
+ (Hash):
+
+2012-10-19 Mark Lam <mark.lam@apple.com>
+
+ Bot greening: Follow up to r131877 to fix the Windows build.
+ https://bugs.webkit.org/show_bug.cgi?id=99739.
+
+ Not reviewed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-10-19 Mark Lam <mark.lam@apple.com>
+
+ Bot greening: Attempt to fix broken Window build after r131836.
+ https://bugs.webkit.org/show_bug.cgi?id=99739.
+
+ Not reviewed.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-10-19 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Unreviewed fix after r131868.
+
+ On JSVALUE64 platforms, JSValue constants can be Imm64 instead of ImmPtr for JIT compilers.
+
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+
+2012-10-18 Filip Pizlo <fpizlo@apple.com>
+
+ Baseline array profiling should be less accurate, and DFG OSR exit should update array profiles on CheckArray and CheckStructure failure
+ https://bugs.webkit.org/show_bug.cgi?id=99261
+
+ Reviewed by Oliver Hunt.
+
+ This makes array profiling stochastic, like value profiling. The point is to avoid
+ noticing one-off indexing types that we'll never see again, but instead to:
+
+ Notice the big ones: We want the DFG to compile based on the things that happen with
+ high probability. So, this change makes array profiling do like value profiling and
+ only notice a random subsampling of indexing types that flowed through an array
+ access. Prior to this patch array profiles noticed all indexing types and weighted
+ them identically.
+
+ Bias the recent: Often an array access will see awkward indexing types during the
+ first handful of executions because of artifacts of program startup. So, we want to
+ bias towards the indexing types that we saw most recently. With this change, array
+ profiling does like value profiling and usually tells use a random sampling that
+ is biased to what happened recently.
+
+ Have a backup plan: The above two things don't work by themselves because our
+ randomness is not that random (nor do we care enough to make it more random), and
+ because some procedures will have a <1/10 probability event that we must handle
+ without bailing because it dominates a hot loop. So, like value profiling, this
+ patch makes array profiling use OSR exits to tell us why we are bailing out, so
+ that we don't make the same mistake again in the future.
+
+ This change also makes the way that the 32-bit OSR exit compiler snatches scratch
+ registers more uniform. We don't need a scratch buffer when we can push and pop.
+
+ * bytecode/DFGExitProfile.h:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitArrayProfilingSite):
+ * llint/LowLevelInterpreter.asm:
+
+2012-10-18 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ [Qt] REGRESSION(r131858): It broke the ARM build
+ https://bugs.webkit.org/show_bug.cgi?id=99809
+
+ Reviewed by Csaba Osztrogonác.
+
+ * dfg/DFGCCallHelpers.h:
+ (CCallHelpers):
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+
+2012-10-18 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Refactor MacroAssembler interfaces to differentiate the pointer operands from the 64-bit integer operands
+ https://bugs.webkit.org/show_bug.cgi?id=99154
+
+ Reviewed by Gavin Barraclough.
+
+ In current JavaScriptCore implementation for JSVALUE64 platform (i.e.,
+ the X64 platform), we assume that the JSValue size is same to the
+ pointer size, and thus EncodedJSValue is simply type defined as a
+ "void*". In the JIT compiler, we also take this assumption and invoke
+ the same macro assembler interfaces for both JSValue and pointer
+ operands. We need to differentiate the operations on pointers from the
+ operations on JSValues, and let them invoking different macro
+ assembler interfaces. For example, we now use the interface of
+ "loadPtr" to load either a pointer or a JSValue, and we need to switch
+ to using "loadPtr" to load a pointer and some new "load64" interface
+ to load a JSValue. This would help us supporting other JSVALUE64
+ platforms where pointer size is not necessarily 64-bits, for example
+ x32 (bug #99153).
+
+ The major modification I made is to introduce the "*64" interfaces in
+ the MacroAssembler for those operations on JSValues, keep the "*Ptr"
+ interfaces for those operations on real pointers, and go through all
+ the JIT compiler code to correct the usage.
+
+ This is the second part of the work, i.e, to correct the usage of the
+ new MacroAssembler interfaces in the JIT compilers, which also means
+ that now EncodedJSValue is defined as a 64-bit integer, and the "*64"
+ interfaces are used for it.
+
+ * assembler/MacroAssembler.h: JSValue immediates should be in Imm64 instead of ImmPtr.
+ (MacroAssembler):
+ (JSC::MacroAssembler::shouldBlind):
+ * dfg/DFGAssemblyHelpers.cpp: Correct the JIT compilers usage of the new interfaces.
+ (JSC::DFG::AssemblyHelpers::jitAssertIsInt32):
+ (JSC::DFG::AssemblyHelpers::jitAssertIsJSInt32):
+ (JSC::DFG::AssemblyHelpers::jitAssertIsJSNumber):
+ (JSC::DFG::AssemblyHelpers::jitAssertIsJSDouble):
+ (JSC::DFG::AssemblyHelpers::jitAssertIsCell):
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::emitPutToCallFrameHeader):
+ (JSC::DFG::AssemblyHelpers::branchIfNotCell):
+ (JSC::DFG::AssemblyHelpers::debugCall):
+ (JSC::DFG::AssemblyHelpers::boxDouble):
+ (JSC::DFG::AssemblyHelpers::unboxDouble):
+ (JSC::DFG::AssemblyHelpers::emitExceptionCheck):
+ * dfg/DFGCCallHelpers.h:
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+ (CCallHelpers):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::generateProtoChainAccessStub):
+ (JSC::DFG::tryCacheGetByID):
+ (JSC::DFG::tryBuildGetByIDList):
+ (JSC::DFG::emitPutReplaceStub):
+ (JSC::DFG::emitPutTransitionStub):
+ * dfg/DFGScratchRegisterAllocator.h:
+ (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer):
+ (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer):
+ * dfg/DFGSilentRegisterSavePlan.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
+ (JSC::DFG::SpeculativeJIT::compileInstanceOfForObject):
+ (JSC::DFG::SpeculativeJIT::compileInstanceOf):
+ (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
+ (JSC::DFG::SpeculativeJIT::silentSpill):
+ (JSC::DFG::SpeculativeJIT::silentFill):
+ (JSC::DFG::SpeculativeJIT::spill):
+ (JSC::DFG::SpeculativeJIT::valueOfJSConstantAsImm64):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (JSC::DFG::SpeculativeJIT::branch64):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::fillDouble):
+ (JSC::DFG::SpeculativeJIT::fillJSValue):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToNumber):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeValueToInt32):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeUInt32ToNumber):
+ (JSC::DFG::SpeculativeJIT::cachedGetById):
+ (JSC::DFG::SpeculativeJIT::cachedPutById):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
+ (JSC::DFG::SpeculativeJIT::convertToDouble):
+ (JSC::DFG::SpeculativeJIT::compileObjectEquality):
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compileDoubleCompare):
+ (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot):
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal):
+ (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal):
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGThunks.cpp:
+ (JSC::DFG::osrExitGenerationThunkGenerator):
+ (JSC::DFG::throwExceptionFromCallSlowPathGenerator):
+ (JSC::DFG::slowPathFor):
+ (JSC::DFG::virtualForThunkGenerator):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpRegisters):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_negate):
+ (JSC::JIT::emitSlow_op_negate):
+ (JSC::JIT::emit_op_rshift):
+ (JSC::JIT::emitSlow_op_urshift):
+ (JSC::JIT::emit_compareAndJumpSlow):
+ (JSC::JIT::emit_op_bitand):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ (JSC::JIT::emit_op_div):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ (JSC::JIT::compileCallEval):
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCall):
+ * jit/JITInlineMethods.h: Have some clean-up work as well.
+ (JSC):
+ (JSC::JIT::emitPutCellToCallFrameHeader):
+ (JSC::JIT::emitPutIntToCallFrameHeader):
+ (JSC::JIT::emitPutToCallFrameHeader):
+ (JSC::JIT::emitGetFromCallFrameHeader32):
+ (JSC::JIT::emitGetFromCallFrameHeader64):
+ (JSC::JIT::emitAllocateJSArray):
+ (JSC::JIT::emitValueProfilingSite):
+ (JSC::JIT::emitGetJITStubArg):
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::emitPutVirtualRegister):
+ (JSC::JIT::emitInitRegister):
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpIfBothJSCells):
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitLoadInt32ToDouble):
+ (JSC::JIT::emitJumpIfImmediateInteger):
+ (JSC::JIT::emitJumpIfNotImmediateInteger):
+ (JSC::JIT::emitJumpIfNotImmediateIntegers):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_mov):
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emit_op_is_undefined):
+ (JSC::JIT::emit_op_is_boolean):
+ (JSC::JIT::emit_op_is_number):
+ (JSC::JIT::emit_op_tear_off_activation):
+ (JSC::JIT::emit_op_not):
+ (JSC::JIT::emit_op_jfalse):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_jtrue):
+ (JSC::JIT::emit_op_bitxor):
+ (JSC::JIT::emit_op_bitor):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emit_op_catch):
+ (JSC::JIT::emit_op_throw_static_error):
+ (JSC::JIT::emit_op_eq_null):
+ (JSC::JIT::emit_op_neq_null):
+ (JSC::JIT::emit_op_create_activation):
+ (JSC::JIT::emit_op_create_arguments):
+ (JSC::JIT::emit_op_init_lazy_reg):
+ (JSC::JIT::emitSlow_op_convert_this):
+ (JSC::JIT::emitSlow_op_not):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC::JIT::emit_resolve_operations):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emitArrayStorageGetByVal):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::compileGetDirectOffset):
+ (JSC::JIT::emit_op_get_by_pname):
+ (JSC::JIT::emitContiguousPutByVal):
+ (JSC::JIT::emitArrayStoragePutByVal):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::emit_op_put_by_id):
+ (JSC::JIT::compilePutDirectOffset):
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitIntTypedArrayGetByVal):
+ (JSC::JIT::emitFloatTypedArrayGetByVal):
+ (JSC::JIT::emitFloatTypedArrayPutByVal):
+ * jit/JITStubCall.h:
+ (JITStubCall):
+ (JSC::JITStubCall::JITStubCall):
+ (JSC::JITStubCall::addArgument):
+ (JSC::JITStubCall::call):
+ (JSC::JITStubCall::callWithValueProfiling):
+ * jit/JSInterfaceJIT.h:
+ (JSC::JSInterfaceJIT::emitJumpIfImmediateNumber):
+ (JSC::JSInterfaceJIT::emitJumpIfNotImmediateNumber):
+ (JSC::JSInterfaceJIT::emitLoadJSCell):
+ (JSC::JSInterfaceJIT::emitLoadInt32):
+ (JSC::JSInterfaceJIT::emitLoadDouble):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::returnDouble):
+ (JSC::SpecializedThunkJIT::tagReturnAsInt32):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::description):
+ * runtime/JSValue.h: Define JSVALUE64 EncodedJSValue as int64_t, which is also unified with JSVALUE32_64.
+ (JSC):
+ * runtime/JSValueInlineMethods.h: New implementation of some JSValue methods to make them more conformant
+ with the new rule that "JSValue is a 64-bit integer rather than a pointer" for JSVALUE64 platforms.
+ (JSC):
+ (JSC::JSValue::JSValue):
+ (JSC::JSValue::operator bool):
+ (JSC::JSValue::operator==):
+ (JSC::JSValue::operator!=):
+ (JSC::reinterpretDoubleToInt64):
+ (JSC::reinterpretInt64ToDouble):
+ (JSC::JSValue::asDouble):
+
+2012-10-18 Michael Saboff <msaboff@apple.com>
+
+ convertUTF8ToUTF16() Should Check for ASCII Input
+ ihttps://bugs.webkit.org/show_bug.cgi?id=99739
+
+ Reviewed by Geoffrey Garen.
+
+ Using the updated convertUTF8ToUTF16() , we can determine if is makes more sense to
+ create a string using the 8 bit source. Added a new OpaqueJSString::create(LChar*, unsigned).
+ Had to add a cast n JSStringCreateWithCFString to differentiate which create() to call.
+
+ * API/JSStringRef.cpp:
+ (JSStringCreateWithUTF8CString):
+ * API/JSStringRefCF.cpp:
+ (JSStringCreateWithCFString):
+ * API/OpaqueJSString.h:
+ (OpaqueJSString::create):
+ (OpaqueJSString):
+ (OpaqueJSString::OpaqueJSString):
+
+2012-10-18 Oliver Hunt <oliver@apple.com>
+
+ Unbreak jsc tests. Last minute "clever"-ness is clearly just not
+ a good plan.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+
+2012-10-18 Oliver Hunt <oliver@apple.com>
+
+ Bytecode should not have responsibility for determining how to perform non-local resolves
+ https://bugs.webkit.org/show_bug.cgi?id=99349
+
+ Reviewed by Gavin Barraclough.
+
+ This patch removes lexical analysis from the bytecode generation. This allows
+ us to delay lookup of a non-local variables until the lookup is actually necessary,
+ and simplifies a lot of the resolve logic in BytecodeGenerator.
+
+ Once a lookup is performed we cache the lookup information in a set of out-of-line
+ buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
+ etc, and allows the respective JITs to recreated optimal lookup code.
+
+ This is currently still a performance regression in LLInt, but most of the remaining
+ regression is caused by a lot of indirection that I'll remove in future work, as well
+ as some work necessary to allow LLInt to perform in line instruction repatching.
+ We will also want to improve the behaviour of the baseline JIT for some of the lookup
+ operations, however this patch was getting quite large already so I'm landing it now
+ that we've reached the bar of "performance-neutral".
+
+ Basic browsing seems to work.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::visitStructures):
+ (JSC):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addResolve):
+ (JSC::CodeBlock::addPutToBase):
+ (CodeBlock):
+ (JSC::CodeBlock::resolveOperations):
+ (JSC::CodeBlock::putToBaseOperation):
+ (JSC::CodeBlock::numberOfResolveOperations):
+ (JSC::CodeBlock::numberOfPutToBaseOperations):
+ (JSC::CodeBlock::addPropertyAccessInstruction):
+ (JSC::CodeBlock::globalObjectConstant):
+ (JSC::CodeBlock::setGlobalObjectConstant):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/ResolveGlobalStatus.cpp:
+ (JSC::computeForStructure):
+ (JSC::ResolveGlobalStatus::computeFor):
+ * bytecode/ResolveGlobalStatus.h:
+ (JSC):
+ (ResolveGlobalStatus):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::ResolveResult::checkValidity):
+ (JSC):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::resolve):
+ (JSC::BytecodeGenerator::resolveConstDecl):
+ (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithThis):
+ (JSC::BytecodeGenerator::emitGetLocalVar):
+ (JSC::BytecodeGenerator::emitInitGlobalConst):
+ (JSC::BytecodeGenerator::emitPutToBase):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::ResolveResult::registerResolve):
+ (JSC::ResolveResult::dynamicResolve):
+ (ResolveResult):
+ (JSC::ResolveResult::ResolveResult):
+ (JSC):
+ (NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::resolved):
+ (JSC::NonlocalResolveInfo::put):
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::getResolveOperations):
+ (JSC::BytecodeGenerator::getResolveWithThisOperations):
+ (JSC::BytecodeGenerator::getResolveBaseOperations):
+ (JSC::BytecodeGenerator::getResolveBaseForPutOperations):
+ (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
+ (JSC::BytecodeGenerator::getPutToBaseOperation):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ResolveNode::isPure):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ForInNode::emitBytecode):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineResolveOperations):
+ (DFG):
+ (JSC::DFG::canCompileOpcode):
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGGraph.h:
+ (ResolveGlobalData):
+ (ResolveOperationData):
+ (DFG):
+ (PutToBaseOperationData):
+ (Graph):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasIdentifier):
+ (JSC::DFG::Node::resolveOperationsDataIndex):
+ (Node):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::resolveOperations):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::putToBaseOperation):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC):
+ (JSC::JIT::emit_resolve_operations):
+ (JSC::JIT::emitSlow_link_resolve_operations):
+ (JSC::JIT::emit_op_resolve):
+ (JSC::JIT::emitSlow_op_resolve):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emitSlow_op_resolve_base):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emitSlow_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_put_to_base):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitSlow_op_init_global_const_check):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitSlow_op_init_global_const_check):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/JSScope.cpp:
+ (JSC::LookupResult::base):
+ (JSC::LookupResult::value):
+ (JSC::LookupResult::setBase):
+ (JSC::LookupResult::setValue):
+ (LookupResult):
+ (JSC):
+ (JSC::setPutPropertyAccessOffset):
+ (JSC::executeResolveOperations):
+ (JSC::JSScope::resolveContainingScopeInternal):
+ (JSC::JSScope::resolveContainingScope):
+ (JSC::JSScope::resolve):
+ (JSC::JSScope::resolveBase):
+ (JSC::JSScope::resolveWithBase):
+ (JSC::JSScope::resolveWithThis):
+ (JSC::JSScope::resolvePut):
+ (JSC::JSScope::resolveGlobal):
+ * runtime/JSScope.h:
+ (JSScope):
+ * runtime/JSVariableObject.cpp:
+ (JSC):
+ * runtime/JSVariableObject.h:
+ (JSVariableObject):
+ * runtime/Structure.h:
+ (JSC::Structure::propertyAccessesAreCacheable):
+ (Structure):
+
+2012-10-18 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Live oversize copied blocks should count toward overall heap fragmentation
+ https://bugs.webkit.org/show_bug.cgi?id=99548
+
+ Reviewed by Filip Pizlo.
+
+ The CopiedSpace uses overall heap fragmentation to determine whether or not it should do any copying.
+ Currently it doesn't include live oversize CopiedBlocks in the calculation, but it should. We should
+ treat them as 100% utilized, since running a copying phase won't be able to free/compact any of their
+ memory. We can also free any dead oversize CopiedBlocks while we're iterating over them, rather than
+ iterating over them again at the end of the copying phase.
+
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::doneFillingBlock):
+ (JSC::CopiedSpace::startedCopying):
+ (JSC::CopiedSpace::doneCopying): Also removed a branch when iterating over from-space at the end of
+ copying. Since we eagerly recycle blocks as soon as they're fully evacuated, we should see no
+ unpinned blocks in from-space at the end of copying.
+ * heap/CopiedSpaceInlineMethods.h:
+ (JSC::CopiedSpace::recycleBorrowedBlock):
+ * heap/CopyVisitorInlineMethods.h:
+ (JSC::CopyVisitor::checkIfShouldCopy):
+
+2012-10-18 Roger Fong <roger_fong@apple.com>
+
+ Unreviewed. Build fix after r131701 and r131777.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-10-18 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Race condition between GCThread and main thread during copying phase
+ https://bugs.webkit.org/show_bug.cgi?id=99641
+
+ Reviewed by Filip Pizlo.
+
+ When a GCThread returns from copyFromShared(), it then calls doneCopying(), which returns
+ its borrowed CopiedBlock to the CopiedSpace. This final block allows the CopiedSpace to
+ continue and finish the cleanup of the copying phase. However, the GCThread can loop back
+ around, see that m_currentPhase is still "Copy", and try to go through the copying phase again.
+ This can cause all sorts of issues. To fix this, we should add a cyclic barrier to GCThread::waitForNextPhase().
+
+ * heap/GCThread.cpp:
+ (JSC::GCThread::waitForNextPhase): All GCThreads will wait when they finish one iteration until the main thread
+ notifies them to move down to the second while loop, where they wait for the next GCPhase to start. They also
+ decrement the m_numberOfActiveGCThreads counter as they begin to wait for the next phase and increment it as
+ they enter the next phase. This allows the main thread to wait in endCurrentPhase() until all the threads have
+ finished the current phase and are waiting on the next phase to begin. Without the counter, there would be
+ no way to ensure that every thread was available for each GCPhase.
+ (JSC::GCThread::gcThreadMain): We now use the m_phaseLock to synchronize with the main thread when we're being created.
+ * heap/GCThreadSharedData.cpp:
+ (JSC::GCThreadSharedData::GCThreadSharedData): As we create each GCThread, we increment the m_numberOfActiveGCThreads
+ counter. When we are done creating the threads, we wait until they're all waiting for the next GCPhase. This prevents
+ us from leaving some GCThreads behind during the first GCPhase, which could hurt us on our very short-running
+ benchmarks (e.g. SunSpider).
+ (JSC::GCThreadSharedData::~GCThreadSharedData):
+ (JSC::GCThreadSharedData::startNextPhase): We atomically swap the two flags, m_gcThreadsShouldWait and m_currentPhase,
+ so that if the threads finish very quickly, they will wait until the main thread is ready to end the current phase.
+ (JSC::GCThreadSharedData::endCurrentPhase): Here atomically we swap the two flags again to allow the threads to
+ advance to waiting on the next GCPhase. We wait until all of the GCThreads have settled into the second wait loop
+ before allowing the main thread to continue. This prevents us from leaving one of the GCThreads stuck in the first
+ wait loop if we were to call startNextPhase() before it had time to wake up and move on to the second wait loop.
+ (JSC):
+ (JSC::GCThreadSharedData::didStartMarking): We now use startNextPhase() to properly swap the flags.
+ (JSC::GCThreadSharedData::didFinishMarking): Ditto for endCurrentPhase().
+ (JSC::GCThreadSharedData::didStartCopying): Ditto.
+ (JSC::GCThreadSharedData::didFinishCopying): Ditto.
+ * heap/GCThreadSharedData.h:
+ (GCThreadSharedData):
+ * heap/Heap.cpp:
+ (JSC::Heap::copyBackingStores): No reason to use the extra reference.
+
+2012-10-18 Pablo Flouret <pablof@motorola.com>
+
+ Implement css3-conditional's @supports rule
+ https://bugs.webkit.org/show_bug.cgi?id=86146
+
+ Reviewed by Antti Koivisto.
+
+ * Configurations/FeatureDefines.xcconfig:
+ Add an ENABLE_CSS3_CONDITIONAL_RULES flag.
+
+2012-10-18 Michael Saboff <msaboff@apple.com>
+
+ Make conversion between JSStringRef and WKStringRef work without character size conversions
+ https://bugs.webkit.org/show_bug.cgi?id=99727
+
+ Reviewed by Anders Carlsson.
+
+ Export the string() method for use in WebKit.
+
+ * API/OpaqueJSString.h:
+ (OpaqueJSString::string):
+
+2012-10-18 Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+
+ [CMake] Avoid unnecessarily running the LLInt generation commands.
+ https://bugs.webkit.org/show_bug.cgi?id=99708
+
+ Reviewed by Rob Buis.
+
+ As described in the comments in the change itself, in some cases
+ the Ruby generation scripts used when LLInt is on would each be
+ run twice in every build even if nothing had changed.
+
+ Fix that by not setting the OBJECT_DEPENDS property of some source
+ files to depend on the generated headers; instead, they are now
+ just part of the final binaries/libraries which use them.
+
+ * CMakeLists.txt:
+
+2012-10-17 Zoltan Horvath <zoltan@webkit.org>
+
+ Remove the JSHeap memory measurement of the PageLoad performacetests since it creates bogus JSGlobalDatas
+ https://bugs.webkit.org/show_bug.cgi?id=99609
+
+ Reviewed by Ryosuke Niwa.
+
+ Remove the implementation since it creates bogus JSGlobalDatas in the layout tests.
+
+ * heap/HeapStatistics.cpp:
+ (JSC):
+ * heap/HeapStatistics.h:
+ (HeapStatistics):
+
+2012-10-17 Sam Weinig <sam@webkit.org>
+
+ Attempt to fix the build.
+
+ * bytecode/GlobalResolveInfo.h: Copied from bytecode/GlobalResolveInfo.h.
+
+2012-10-17 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION (r130826 or r130828): Twitter top bar is dysfunctional
+ https://bugs.webkit.org/show_bug.cgi?id=99577
+ <rdar://problem/12518883>
+
+ Reviewed by Mark Hahnenberg.
+
+ It turns out that it's a good idea to maintain the invariants of your object model, such as that
+ elements past publicLength should have the hole value.
+
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-17 Anders Carlsson <andersca@apple.com>
+
+ Clean up Vector.h
+ https://bugs.webkit.org/show_bug.cgi?id=99622
+
+ Reviewed by Benjamin Poulain.
+
+ Fix fallout from removing std::max and std::min using declarations.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstrings):
+ (JSC::jsSpliceSubstringsWithSeparators):
+ (JSC::stringProtoFuncIndexOf):
+ * yarr/YarrPattern.cpp:
+ (JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
+
+2012-10-17 Oliver Hunt <oliver@apple.com>
+
+ Committing new files is so overrated.
+
+ * bytecode/ResolveOperation.h: Added.
+ (JSC):
+ (JSC::ResolveOperation::getAndReturnScopedVar):
+ (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
+ (ResolveOperation):
+ (JSC::ResolveOperation::getAndReturnGlobalVar):
+ (JSC::ResolveOperation::getAndReturnGlobalProperty):
+ (JSC::ResolveOperation::resolveFail):
+ (JSC::ResolveOperation::skipTopScopeNode):
+ (JSC::ResolveOperation::skipScopes):
+ (JSC::ResolveOperation::returnGlobalObjectAsBase):
+ (JSC::ResolveOperation::setBaseToGlobal):
+ (JSC::ResolveOperation::setBaseToUndefined):
+ (JSC::ResolveOperation::setBaseToScope):
+ (JSC::ResolveOperation::returnScopeAsBase):
+ (JSC::PutToBaseOperation::PutToBaseOperation):
+
+2012-10-17 Michael Saboff <msaboff@apple.com>
+
+ StringPrototype::jsSpliceSubstringsWithSeparators() doesn't optimally handle 8 bit strings
+ https://bugs.webkit.org/show_bug.cgi?id=99230
+
+ Reviewed by Geoffrey Garen.
+
+ Added code to select characters8() or characters16() on the not all 8 bit path for both the
+ processing of the source and the separators.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstringsWithSeparators):
+
+2012-10-17 Filip Pizlo <fpizlo@apple.com>
+
+ Array and object allocations via 'new Object' or 'new Array' should be inlined in bytecode to allow allocation site profiling
+ https://bugs.webkit.org/show_bug.cgi?id=99557
+
+ Reviewed by Geoffrey Garen.
+
+ Removed an inaccurate and misleading comment as per Geoff's review. (I forgot
+ to make this change as part of http://trac.webkit.org/changeset/131644).
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::FunctionCallResolveNode::emitBytecode):
+
+2012-10-17 Oliver Hunt <oliver@apple.com>
+
+ Bytecode should not have responsibility for determining how to perform non-local resolves
+ https://bugs.webkit.org/show_bug.cgi?id=99349
+
+ Reviewed by Gavin Barraclough.
+
+ This patch removes lexical analysis from the bytecode generation. This allows
+ us to delay lookup of a non-local variables until the lookup is actually necessary,
+ and simplifies a lot of the resolve logic in BytecodeGenerator.
+
+ Once a lookup is performed we cache the lookup information in a set of out-of-line
+ buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
+ etc, and allows the respective JITs to recreated optimal lookup code.
+
+ This is currently still a performance regression in LLInt, but most of the remaining
+ regression is caused by a lot of indirection that I'll remove in future work, as well
+ as some work necessary to allow LLInt to perform in line instruction repatching.
+ We will also want to improve the behaviour of the baseline JIT for some of the lookup
+ operations, however this patch was getting quite large already so I'm landing it now
+ that we've reached the bar of "performance-neutral".
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::visitStructures):
+ (JSC):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addResolve):
+ (JSC::CodeBlock::addPutToBase):
+ (CodeBlock):
+ (JSC::CodeBlock::resolveOperations):
+ (JSC::CodeBlock::putToBaseOperation):
+ (JSC::CodeBlock::numberOfResolveOperations):
+ (JSC::CodeBlock::numberOfPutToBaseOperations):
+ (JSC::CodeBlock::addPropertyAccessInstruction):
+ (JSC::CodeBlock::globalObjectConstant):
+ (JSC::CodeBlock::setGlobalObjectConstant):
+ * bytecode/GlobalResolveInfo.h: Removed.
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/ResolveGlobalStatus.cpp:
+ (JSC::computeForStructure):
+ (JSC::ResolveGlobalStatus::computeFor):
+ * bytecode/ResolveGlobalStatus.h:
+ (JSC):
+ (ResolveGlobalStatus):
+ * bytecode/ResolveOperation.h: Added.
+ The new types and logic we use to perform the cached lookups.
+ (JSC):
+ (ResolveOperation):
+ (JSC::ResolveOperation::getAndReturnScopedVar):
+ (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
+ (JSC::ResolveOperation::getAndReturnGlobalVar):
+ (JSC::ResolveOperation::getAndReturnGlobalProperty):
+ (JSC::ResolveOperation::resolveFail):
+ (JSC::ResolveOperation::skipTopScopeNode):
+ (JSC::ResolveOperation::skipScopes):
+ (JSC::ResolveOperation::returnGlobalObjectAsBase):
+ (JSC::ResolveOperation::setBaseToGlobal):
+ (JSC::ResolveOperation::setBaseToUndefined):
+ (JSC::ResolveOperation::setBaseToScope):
+ (JSC::ResolveOperation::returnScopeAsBase):
+ (JSC::PutToBaseOperation::PutToBaseOperation):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::ResolveResult::checkValidity):
+ (JSC):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::resolve):
+ (JSC::BytecodeGenerator::resolveConstDecl):
+ (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithThis):
+ (JSC::BytecodeGenerator::emitGetLocalVar):
+ (JSC::BytecodeGenerator::emitInitGlobalConst):
+ (JSC::BytecodeGenerator::emitPutToBase):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::ResolveResult::registerResolve):
+ (JSC::ResolveResult::dynamicResolve):
+ (ResolveResult):
+ (JSC::ResolveResult::ResolveResult):
+ (JSC):
+ (NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::resolved):
+ (JSC::NonlocalResolveInfo::put):
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::getResolveOperations):
+ (JSC::BytecodeGenerator::getResolveWithThisOperations):
+ (JSC::BytecodeGenerator::getResolveBaseOperations):
+ (JSC::BytecodeGenerator::getResolveBaseForPutOperations):
+ (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
+ (JSC::BytecodeGenerator::getPutToBaseOperation):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ResolveNode::isPure):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ForInNode::emitBytecode):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileResolveOperations):
+ (DFG):
+ (JSC::DFG::canCompilePutToBaseOperation):
+ (JSC::DFG::canCompileOpcode):
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGGraph.h:
+ (ResolveGlobalData):
+ (ResolveOperationData):
+ (DFG):
+ (PutToBaseOperationData):
+ (Graph):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasIdentifier):
+ (JSC::DFG::Node::resolveOperationsDataIndex):
+ (Node):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::resolveOperations):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::putToBaseOperation):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC):
+ (JSC::JIT::emit_resolve_operations):
+ (JSC::JIT::emitSlow_link_resolve_operations):
+ (JSC::JIT::emit_op_resolve):
+ (JSC::JIT::emitSlow_op_resolve):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emitSlow_op_resolve_base):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emitSlow_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_put_to_base):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitSlow_op_init_global_const_check):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitSlow_op_init_global_const_check):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/JSScope.cpp:
+ (JSC::LookupResult::base):
+ (JSC::LookupResult::value):
+ (JSC::LookupResult::setBase):
+ (JSC::LookupResult::setValue):
+ (LookupResult):
+ (JSC):
+ (JSC::setPutPropertyAccessOffset):
+ (JSC::executeResolveOperations):
+ (JSC::JSScope::resolveContainingScopeInternal):
+ (JSC::JSScope::resolveContainingScope):
+ (JSC::JSScope::resolve):
+ (JSC::JSScope::resolveBase):
+ (JSC::JSScope::resolveWithBase):
+ (JSC::JSScope::resolveWithThis):
+ (JSC::JSScope::resolvePut):
+ (JSC::JSScope::resolveGlobal):
+ * runtime/JSScope.h:
+ (JSScope):
+ * runtime/JSVariableObject.cpp:
+ (JSC):
+ * runtime/JSVariableObject.h:
+ (JSVariableObject):
+ * runtime/Structure.h:
+ (JSC::Structure::propertyAccessesAreCacheable):
+ (Structure):
+
+2012-10-17 Filip Pizlo <fpizlo@apple.com>
+
+ Array and object allocations via 'new Object' or 'new Array' should be inlined in bytecode to allow allocation site profiling
+ https://bugs.webkit.org/show_bug.cgi?id=99557
+
+ Reviewed by Geoffrey Garen.
+
+ This uses the old jneq_ptr trick to allow for the bytecode to "see" that the
+ operation in question is what we almost certainly know it to be.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/SpecialPointer.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitCallEval):
+ (JSC::BytecodeGenerator::expectedFunctionForIdentifier):
+ (JSC):
+ (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
+ (JSC::BytecodeGenerator::emitConstruct):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::NewExprNode::emitBytecode):
+ (JSC::FunctionCallValueNode::emitBytecode):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::FunctionCallBracketNode::emitBytecode):
+ (JSC::FunctionCallDotNode::emitBytecode):
+ (JSC::CallFunctionCallDotNode::emitBytecode):
+ (JSC::ApplyFunctionCallDotNode::emitBytecode):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_array_with_size):
+ (JSC):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (LLInt):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * runtime/ArrayConstructor.cpp:
+ (JSC::constructArrayWithSizeQuirk):
+ (JSC):
+ * runtime/ArrayConstructor.h:
+ (JSC):
+ * runtime/CommonIdentifiers.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+
+2012-10-17 Filip Pizlo <fpizlo@apple.com>
+
+ JIT op_get_by_pname should call cti_get_by_val_generic and not cti_get_by_val
+ https://bugs.webkit.org/show_bug.cgi?id=99631
+ <rdar://problem/12483221>
+
+ Reviewed by Mark Hahnenberg.
+
+ cti_get_by_val assumes that the return address has patching metadata associated with it, which won't
+ be true for op_get_by_pname. cti_get_by_val_generic makes no such assumptions.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emitSlow_op_get_by_pname):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emitSlow_op_get_by_pname):
+
+2012-10-17 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Block freeing thread should sleep indefinitely when there's no work to do
+ https://bugs.webkit.org/show_bug.cgi?id=98084
+
+ Reviewed by Geoffrey Garen.
+
+ r130212 didn't fully fix the problem.
+
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::blockFreeingThreadMain): We would just continue to the next iteration if
+ we found that we had zero blocks to copy. We should move the indefinite wait up to where that
+ check is done so that we properly detect the "no more blocks to copy, wait for more" condition.
+
+2012-10-16 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed, rolling out r131516 and r131550.
+ http://trac.webkit.org/changeset/131516
+ http://trac.webkit.org/changeset/131550
+ https://bugs.webkit.org/show_bug.cgi?id=99349
+
+ It caused zillion different problem on different platforms
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC):
+ (JSC::isGlobalResolve):
+ (JSC::instructionOffsetForNth):
+ (JSC::printGlobalResolveInfo):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::visitStructures):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset):
+ (JSC::CodeBlock::globalResolveInfoForBytecodeOffset):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::addGlobalResolveInstruction):
+ (JSC::CodeBlock::addGlobalResolveInfo):
+ (JSC::CodeBlock::globalResolveInfo):
+ (JSC::CodeBlock::numberOfGlobalResolveInfos):
+ (JSC::CodeBlock::globalResolveInfoCount):
+ * bytecode/GlobalResolveInfo.h: Copied from Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp.
+ (JSC):
+ (JSC::GlobalResolveInfo::GlobalResolveInfo):
+ (GlobalResolveInfo):
+ (JSC::getGlobalResolveInfoBytecodeOffset):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/ResolveGlobalStatus.cpp:
+ (JSC):
+ (JSC::computeForStructure):
+ (JSC::computeForLLInt):
+ (JSC::ResolveGlobalStatus::computeFor):
+ * bytecode/ResolveGlobalStatus.h:
+ (JSC):
+ (ResolveGlobalStatus):
+ * bytecode/ResolveOperation.h: Removed.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::ResolveResult::checkValidity):
+ (JSC::ResolveResult::registerPointer):
+ (JSC):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::resolve):
+ (JSC::BytecodeGenerator::resolveConstDecl):
+ (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithBase):
+ (JSC::BytecodeGenerator::emitResolveWithThis):
+ (JSC::BytecodeGenerator::emitGetStaticVar):
+ (JSC::BytecodeGenerator::emitInitGlobalConst):
+ (JSC::BytecodeGenerator::emitPutStaticVar):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::ResolveResult::registerResolve):
+ (JSC::ResolveResult::dynamicResolve):
+ (JSC::ResolveResult::lexicalResolve):
+ (JSC::ResolveResult::indexedGlobalResolve):
+ (JSC::ResolveResult::dynamicIndexedGlobalResolve):
+ (JSC::ResolveResult::globalResolve):
+ (JSC::ResolveResult::dynamicGlobalResolve):
+ (JSC::ResolveResult::type):
+ (JSC::ResolveResult::index):
+ (JSC::ResolveResult::depth):
+ (JSC::ResolveResult::globalObject):
+ (ResolveResult):
+ (JSC::ResolveResult::isStatic):
+ (JSC::ResolveResult::isIndexed):
+ (JSC::ResolveResult::isScoped):
+ (JSC::ResolveResult::isGlobal):
+ (JSC::ResolveResult::ResolveResult):
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ResolveNode::isPure):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ForInNode::emitBytecode):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGGraph.h:
+ (ResolveGlobalData):
+ (DFG):
+ (Graph):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasIdentifier):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ (JSC):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ (JSC::JIT::emit_op_get_global_var_watchable):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_resolve):
+ (JSC):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emit_op_resolve_skip):
+ (JSC::JIT::emit_op_resolve_global):
+ (JSC::JIT::emitSlow_op_resolve_global):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emit_op_resolve_global_dynamic):
+ (JSC::JIT::emitSlow_op_resolve_global_dynamic):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_resolve):
+ (JSC):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emit_op_resolve_skip):
+ (JSC::JIT::emit_op_resolve_global):
+ (JSC::JIT::emitSlow_op_resolve_global):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_get_global_var):
+ (JSC::JIT::emit_op_put_global_var):
+ (JSC::JIT::emit_op_put_global_var_check):
+ (JSC::JIT::emitSlow_op_put_global_var_check):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC):
+ (JSC::JIT::emit_op_put_scoped_var):
+ (JSC::JIT::emit_op_get_global_var):
+ (JSC::JIT::emit_op_put_global_var):
+ (JSC::JIT::emit_op_put_global_var_check):
+ (JSC::JIT::emitSlow_op_put_global_var_check):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/JSScope.cpp:
+ (JSC::JSScope::resolve):
+ (JSC::JSScope::resolveSkip):
+ (JSC::JSScope::resolveGlobal):
+ (JSC::JSScope::resolveGlobalDynamic):
+ (JSC::JSScope::resolveBase):
+ (JSC::JSScope::resolveWithBase):
+ (JSC::JSScope::resolveWithThis):
+ * runtime/JSScope.h:
+ (JSScope):
+ * runtime/JSVariableObject.cpp:
+ * runtime/JSVariableObject.h:
+ * runtime/Structure.h:
+
+2012-10-16 Dongwoo Joshua Im <dw.im@samsung.com>
+
+ [GTK] Fix build break - ResolveOperations.h is not in WebKit.
+ https://bugs.webkit.org/show_bug.cgi?id=99538
+
+ Unreviewed build fix.
+
+ There are some files including ResolveOperations.h which is not exist at all.
+
+ * GNUmakefile.list.am: s/ResolveOperations.h/ResolveOperation.h/
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: s/ResolveOperations.h/ResolveOperation.h/
+
+2012-10-16 Jian Li <jianli@chromium.org>
+
+ Rename feature define ENABLE_WIDGET_REGION to ENABLE_DRAGGBALE_REGION
+ https://bugs.webkit.org/show_bug.cgi?id=98975
+
+ Reviewed by Adam Barth.
+
+ Renaming is needed to better match with the draggable region code.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-15 Oliver Hunt <oliver@apple.com>
+
+ Bytecode should not have responsibility for determining how to perform non-local resolves
+ https://bugs.webkit.org/show_bug.cgi?id=99349
+
+ Reviewed by Gavin Barraclough.
+
+ This patch removes lexical analysis from the bytecode generation. This allows
+ us to delay lookup of a non-local variables until the lookup is actually necessary,
+ and simplifies a lot of the resolve logic in BytecodeGenerator.
+
+ Once a lookup is performed we cache the lookup information in a set of out-of-line
+ buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
+ etc, and allows the respective JITs to recreated optimal lookup code.
+
+ This is currently still a performance regression in LLInt, but most of the remaining
+ regression is caused by a lot of indirection that I'll remove in future work, as well
+ as some work necessary to allow LLInt to perform in line instruction repatching.
+ We will also want to improve the behaviour of the baseline JIT for some of the lookup
+ operations, however this patch was getting quite large already so I'm landing it now
+ that we've reached the bar of "performance-neutral".
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::visitStructures):
+ (JSC):
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addResolve):
+ (JSC::CodeBlock::addPutToBase):
+ (CodeBlock):
+ (JSC::CodeBlock::resolveOperations):
+ (JSC::CodeBlock::putToBaseOperation):
+ (JSC::CodeBlock::numberOfResolveOperations):
+ (JSC::CodeBlock::numberOfPutToBaseOperations):
+ (JSC::CodeBlock::addPropertyAccessInstruction):
+ (JSC::CodeBlock::globalObjectConstant):
+ (JSC::CodeBlock::setGlobalObjectConstant):
+ * bytecode/GlobalResolveInfo.h: Removed.
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecode/ResolveGlobalStatus.cpp:
+ (JSC::computeForStructure):
+ (JSC::ResolveGlobalStatus::computeFor):
+ * bytecode/ResolveGlobalStatus.h:
+ (JSC):
+ (ResolveGlobalStatus):
+ * bytecode/ResolveOperation.h: Added.
+ The new types and logic we use to perform the cached lookups.
+ (JSC):
+ (ResolveOperation):
+ (JSC::ResolveOperation::getAndReturnScopedVar):
+ (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
+ (JSC::ResolveOperation::getAndReturnGlobalVar):
+ (JSC::ResolveOperation::getAndReturnGlobalProperty):
+ (JSC::ResolveOperation::resolveFail):
+ (JSC::ResolveOperation::skipTopScopeNode):
+ (JSC::ResolveOperation::skipScopes):
+ (JSC::ResolveOperation::returnGlobalObjectAsBase):
+ (JSC::ResolveOperation::setBaseToGlobal):
+ (JSC::ResolveOperation::setBaseToUndefined):
+ (JSC::ResolveOperation::setBaseToScope):
+ (JSC::ResolveOperation::returnScopeAsBase):
+ (JSC::PutToBaseOperation::PutToBaseOperation):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::ResolveResult::checkValidity):
+ (JSC):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::resolve):
+ (JSC::BytecodeGenerator::resolveConstDecl):
+ (JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithBaseForPut):
+ (JSC::BytecodeGenerator::emitResolveWithThis):
+ (JSC::BytecodeGenerator::emitGetLocalVar):
+ (JSC::BytecodeGenerator::emitInitGlobalConst):
+ (JSC::BytecodeGenerator::emitPutToBase):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::ResolveResult::registerResolve):
+ (JSC::ResolveResult::dynamicResolve):
+ (ResolveResult):
+ (JSC::ResolveResult::ResolveResult):
+ (JSC):
+ (NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
+ (JSC::NonlocalResolveInfo::resolved):
+ (JSC::NonlocalResolveInfo::put):
+ (BytecodeGenerator):
+ (JSC::BytecodeGenerator::getResolveOperations):
+ (JSC::BytecodeGenerator::getResolveWithThisOperations):
+ (JSC::BytecodeGenerator::getResolveBaseOperations):
+ (JSC::BytecodeGenerator::getResolveBaseForPutOperations):
+ (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
+ (JSC::BytecodeGenerator::getPutToBaseOperation):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ResolveNode::isPure):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::PostfixNode::emitResolve):
+ (JSC::PrefixNode::emitResolve):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ForInNode::emitBytecode):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ByteCodeParser):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::handleGetByOffset):
+ (DFG):
+ (JSC::DFG::ByteCodeParser::parseResolveOperations):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileResolveOperations):
+ (DFG):
+ (JSC::DFG::canCompilePutToBaseOperation):
+ (JSC::DFG::canCompileOpcode):
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGGraph.h:
+ (ResolveGlobalData):
+ (ResolveOperationData):
+ (DFG):
+ (PutToBaseOperationData):
+ (Graph):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasIdentifier):
+ (JSC::DFG::Node::resolveOperationsDataIndex):
+ (Node):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::OSRExit):
+ * dfg/DFGOSRExit.h:
+ (OSRExit):
+ * dfg/DFGOSRExitCompiler.cpp:
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::resolveOperations):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::putToBaseOperation):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC):
+ (JSC::JIT::emit_resolve_operations):
+ (JSC::JIT::emitSlow_link_resolve_operations):
+ (JSC::JIT::emit_op_resolve):
+ (JSC::JIT::emitSlow_op_resolve):
+ (JSC::JIT::emit_op_resolve_base):
+ (JSC::JIT::emitSlow_op_resolve_base):
+ (JSC::JIT::emit_op_resolve_with_base):
+ (JSC::JIT::emitSlow_op_resolve_with_base):
+ (JSC::JIT::emit_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_resolve_with_this):
+ (JSC::JIT::emitSlow_op_put_to_base):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_put_to_base):
+ (JSC):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitSlow_op_init_global_const_check):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_init_global_const):
+ (JSC::JIT::emit_op_init_global_const_check):
+ (JSC::JIT::emitSlow_op_init_global_const_check):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC):
+ * jit/JITStubs.h:
+ * llint/LLIntSlowPaths.cpp:
+ (LLInt):
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/JSScope.cpp:
+ (JSC::LookupResult::base):
+ (JSC::LookupResult::value):
+ (JSC::LookupResult::setBase):
+ (JSC::LookupResult::setValue):
+ (LookupResult):
+ (JSC):
+ (JSC::setPutPropertyAccessOffset):
+ (JSC::executeResolveOperations):
+ (JSC::JSScope::resolveContainingScopeInternal):
+ (JSC::JSScope::resolveContainingScope):
+ (JSC::JSScope::resolve):
+ (JSC::JSScope::resolveBase):
+ (JSC::JSScope::resolveWithBase):
+ (JSC::JSScope::resolveWithThis):
+ (JSC::JSScope::resolvePut):
+ (JSC::JSScope::resolveGlobal):
+ * runtime/JSScope.h:
+ (JSScope):
+ * runtime/JSVariableObject.cpp:
+ (JSC):
+ * runtime/JSVariableObject.h:
+ (JSVariableObject):
+ * runtime/Structure.h:
+ (JSC::Structure::propertyAccessesAreCacheable):
+ (Structure):
+
+2012-10-16 Filip Pizlo <fpizlo@apple.com>
+
+ Accidental switch fall-through in DFG::FixupPhase
+ https://bugs.webkit.org/show_bug.cgi?id=96956
+ <rdar://problem/12313242>
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+
+2012-10-16 Filip Pizlo <fpizlo@apple.com>
+
+ GetScopedVar CSE matches dead GetScopedVar's leading to IR corruption
+ https://bugs.webkit.org/show_bug.cgi?id=99470
+ <rdar://problem/12363698>
+
+ Reviewed by Mark Hahnenberg.
+
+ All it takes is to follow the "if (!shouldGenerate) continue" idiom and everything will be OK.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::globalVarLoadElimination):
+ (JSC::DFG::CSEPhase::scopedVarLoadElimination):
+ (JSC::DFG::CSEPhase::globalVarWatchpointElimination):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkStructureElimination):
+ (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+
+2012-10-16 Dima Gorbik <dgorbik@apple.com>
+
+ Remove Platform.h include from the header files.
+ https://bugs.webkit.org/show_bug.cgi?id=98665
+
+ Reviewed by Eric Seidel.
+
+ We don't want other clients that include WebKit headers to know about Platform.h.
+
+ * API/tests/minidom.c:
+ * API/tests/testapi.c:
+
+2012-10-16 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ Add missing MIPS functions to assembler.
+ https://bugs.webkit.org/show_bug.cgi?id=98856
+
+ Reviewed by Oliver Hunt.
+
+ Implement missing functions in MacroAssemblerMIPS and MIPSAssembler.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::lb):
+ (MIPSAssembler):
+ (JSC::MIPSAssembler::lh):
+ (JSC::MIPSAssembler::cvtds):
+ (JSC::MIPSAssembler::cvtsd):
+ (JSC::MIPSAssembler::vmov):
+ * assembler/MacroAssemblerMIPS.h:
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::load8Signed):
+ (JSC::MacroAssemblerMIPS::load16Signed):
+ (JSC::MacroAssemblerMIPS::moveDoubleToInts):
+ (JSC::MacroAssemblerMIPS::moveIntsToDouble):
+ (JSC::MacroAssemblerMIPS::loadFloat):
+ (JSC::MacroAssemblerMIPS::loadDouble):
+ (JSC::MacroAssemblerMIPS::storeFloat):
+ (JSC::MacroAssemblerMIPS::storeDouble):
+ (JSC::MacroAssemblerMIPS::addDouble):
+ (JSC::MacroAssemblerMIPS::convertFloatToDouble):
+ (JSC::MacroAssemblerMIPS::convertDoubleToFloat):
+
+2012-10-16 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ MIPS assembler coding-style fix.
+ https://bugs.webkit.org/show_bug.cgi?id=99359
+
+ Reviewed by Oliver Hunt.
+
+ Coding style fix of existing MIPS assembler header files.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::addiu):
+ (JSC::MIPSAssembler::addu):
+ (JSC::MIPSAssembler::subu):
+ (JSC::MIPSAssembler::mul):
+ (JSC::MIPSAssembler::andInsn):
+ (JSC::MIPSAssembler::andi):
+ (JSC::MIPSAssembler::nor):
+ (JSC::MIPSAssembler::orInsn):
+ (JSC::MIPSAssembler::ori):
+ (JSC::MIPSAssembler::xorInsn):
+ (JSC::MIPSAssembler::xori):
+ (JSC::MIPSAssembler::slt):
+ (JSC::MIPSAssembler::sltu):
+ (JSC::MIPSAssembler::sltiu):
+ (JSC::MIPSAssembler::sll):
+ (JSC::MIPSAssembler::sllv):
+ (JSC::MIPSAssembler::sra):
+ (JSC::MIPSAssembler::srav):
+ (JSC::MIPSAssembler::srl):
+ (JSC::MIPSAssembler::srlv):
+ (JSC::MIPSAssembler::lbu):
+ (JSC::MIPSAssembler::lw):
+ (JSC::MIPSAssembler::lwl):
+ (JSC::MIPSAssembler::lwr):
+ (JSC::MIPSAssembler::lhu):
+ (JSC::MIPSAssembler::sb):
+ (JSC::MIPSAssembler::sh):
+ (JSC::MIPSAssembler::sw):
+ (JSC::MIPSAssembler::addd):
+ (JSC::MIPSAssembler::subd):
+ (JSC::MIPSAssembler::muld):
+ (JSC::MIPSAssembler::divd):
+ (JSC::MIPSAssembler::lwc1):
+ (JSC::MIPSAssembler::ldc1):
+ (JSC::MIPSAssembler::swc1):
+ (JSC::MIPSAssembler::sdc1):
+ (MIPSAssembler):
+ (JSC::MIPSAssembler::relocateJumps):
+ (JSC::MIPSAssembler::linkWithOffset):
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::add32):
+ (JSC::MacroAssemblerMIPS::and32):
+ (JSC::MacroAssemblerMIPS::sub32):
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::load8):
+ (JSC::MacroAssemblerMIPS::load32):
+ (JSC::MacroAssemblerMIPS::load32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerMIPS::load16):
+ (JSC::MacroAssemblerMIPS::store8):
+ (JSC::MacroAssemblerMIPS::store16):
+ (JSC::MacroAssemblerMIPS::store32):
+ (JSC::MacroAssemblerMIPS::nearCall):
+ (JSC::MacroAssemblerMIPS::test8):
+ (JSC::MacroAssemblerMIPS::test32):
+
+2012-10-16 Yuqiang Xian <yuqiang.xian@intel.com>
+
+ Refactor MacroAssembler interfaces to differentiate the pointer operands from the 64-bit integer operands
+ https://bugs.webkit.org/show_bug.cgi?id=99154
+
+ Reviewed by Gavin Barraclough.
+
+ In current JavaScriptCore implementation for JSVALUE64 platform (i.e.,
+ the X64 platform), we assume that the JSValue size is same to the
+ pointer size, and thus EncodedJSValue is simply type defined as a
+ "void*". In the JIT compiler, we also take this assumption and invoke
+ the same macro assembler interfaces for both JSValue and pointer
+ operands. We need to differentiate the operations on pointers from the
+ operations on JSValues, and let them invoking different macro
+ assembler interfaces. For example, we now use the interface of
+ "loadPtr" to load either a pointer or a JSValue, and we need to switch
+ to using "loadPtr" to load a pointer and some new "load64" interface
+ to load a JSValue. This would help us supporting other JSVALUE64
+ platforms where pointer size is not necessarily 64-bits, for example
+ x32 (bug #99153).
+
+ The major modification I made is to introduce the "*64" interfaces in
+ the MacroAssembler for those operations on JSValues, keep the "*Ptr"
+ interfaces for those operations on real pointers, and go through all
+ the JIT compiler code to correct the usage.
+
+ This is the first part of the work, i.e, to add the *64 interfaces to
+ the MacroAssembler.
+
+ * assembler/AbstractMacroAssembler.h: Add the Imm64 interfaces.
+ (AbstractMacroAssembler):
+ (JSC::AbstractMacroAssembler::TrustedImm64::TrustedImm64):
+ (TrustedImm64):
+ (JSC::AbstractMacroAssembler::Imm64::Imm64):
+ (Imm64):
+ (JSC::AbstractMacroAssembler::Imm64::asTrustedImm64):
+ * assembler/MacroAssembler.h: map <foo>Ptr methods to <foo>64 for X86_64.
+ (MacroAssembler):
+ (JSC::MacroAssembler::peek64):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::poke64):
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::andPtr):
+ (JSC::MacroAssembler::negPtr):
+ (JSC::MacroAssembler::orPtr):
+ (JSC::MacroAssembler::rotateRightPtr):
+ (JSC::MacroAssembler::subPtr):
+ (JSC::MacroAssembler::xorPtr):
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::loadPtrWithAddressOffsetPatch):
+ (JSC::MacroAssembler::loadPtrWithCompactAddressOffsetPatch):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::storePtrWithAddressOffsetPatch):
+ (JSC::MacroAssembler::movePtrToDouble):
+ (JSC::MacroAssembler::moveDoubleToPtr):
+ (JSC::MacroAssembler::comparePtr):
+ (JSC::MacroAssembler::testPtr):
+ (JSC::MacroAssembler::branchPtr):
+ (JSC::MacroAssembler::branchTestPtr):
+ (JSC::MacroAssembler::branchAddPtr):
+ (JSC::MacroAssembler::branchSubPtr):
+ (JSC::MacroAssembler::shouldBlindDouble):
+ (JSC::MacroAssembler::shouldBlind):
+ (JSC::MacroAssembler::RotatedImm64::RotatedImm64):
+ (RotatedImm64):
+ (JSC::MacroAssembler::rotationBlindConstant):
+ (JSC::MacroAssembler::loadRotationBlindedConstant):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::and64):
+ (JSC::MacroAssembler::store64):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::shouldBlindForSpecificArch):
+ (MacroAssemblerX86Common):
+ (JSC::MacroAssemblerX86Common::move):
+ * assembler/MacroAssemblerX86_64.h: Add the <foo>64 methods for X86_64.
+ (JSC::MacroAssemblerX86_64::branchAdd32):
+ (JSC::MacroAssemblerX86_64::add64):
+ (MacroAssemblerX86_64):
+ (JSC::MacroAssemblerX86_64::and64):
+ (JSC::MacroAssemblerX86_64::neg64):
+ (JSC::MacroAssemblerX86_64::or64):
+ (JSC::MacroAssemblerX86_64::rotateRight64):
+ (JSC::MacroAssemblerX86_64::sub64):
+ (JSC::MacroAssemblerX86_64::xor64):
+ (JSC::MacroAssemblerX86_64::load64):
+ (JSC::MacroAssemblerX86_64::load64WithAddressOffsetPatch):
+ (JSC::MacroAssemblerX86_64::load64WithCompactAddressOffsetPatch):
+ (JSC::MacroAssemblerX86_64::store64):
+ (JSC::MacroAssemblerX86_64::store64WithAddressOffsetPatch):
+ (JSC::MacroAssemblerX86_64::move64ToDouble):
+ (JSC::MacroAssemblerX86_64::moveDoubleTo64):
+ (JSC::MacroAssemblerX86_64::compare64):
+ (JSC::MacroAssemblerX86_64::branch64):
+ (JSC::MacroAssemblerX86_64::branchTest64):
+ (JSC::MacroAssemblerX86_64::test64):
+ (JSC::MacroAssemblerX86_64::branchAdd64):
+ (JSC::MacroAssemblerX86_64::branchSub64):
+ (JSC::MacroAssemblerX86_64::branchPtrWithPatch):
+ (JSC::MacroAssemblerX86_64::storePtrWithPatch):
+
+2012-10-15 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Make CopiedSpace and MarkedSpace regions independent
+ https://bugs.webkit.org/show_bug.cgi?id=99222
+
+ Reviewed by Filip Pizlo.
+
+ Right now CopiedSpace and MarkedSpace have the same block size and share the same regions,
+ but there's no reason that they can't have different block sizes while still sharing the
+ same underlying regions. We should factor the two "used" lists of regions apart so that
+ MarkedBlocks and CopiedBlocks can be different sizes. Regions will still be a uniform size
+ so that when they become empty they may be shared between the CopiedSpace and the MarkedSpace,
+ since benchmarks indicate that sharing is a boon for performance.
+
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::BlockAllocator):
+ * heap/BlockAllocator.h:
+ (JSC):
+ (Region):
+ (JSC::Region::create): We now have a fixed size for Regions so that empty regions can continue to
+ be shared between the MarkedSpace and CopiedSpace. Once they are used for a specific type of block,
+ however, they can only be used for that type of block until they become empty again.
+ (JSC::Region::createCustomSize):
+ (JSC::Region::Region):
+ (JSC::Region::~Region):
+ (JSC::Region::reset):
+ (BlockAllocator):
+ (JSC::BlockAllocator::RegionSet::RegionSet):
+ (RegionSet):
+ (JSC::BlockAllocator::tryAllocateFromRegion): We change this function so that it correctly
+ moves blocks between empty, partial, and full lists.
+ (JSC::BlockAllocator::allocate):
+ (JSC::BlockAllocator::allocateCustomSize):
+ (JSC::BlockAllocator::deallocate): Ditto.
+ (JSC::CopiedBlock):
+ (JSC::MarkedBlock):
+ (JSC::BlockAllocator::regionSetFor): We use this so that we can use the same allocate/deallocate
+ functions with different RegionSets. We specialize the function for each type of block that we
+ want to allocate.
+ * heap/CopiedBlock.h:
+ (CopiedBlock):
+ * heap/CopiedSpace.h:
+ (CopiedSpace):
+ * heap/HeapBlock.h:
+ (HeapBlock):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::MarkedBlock): For oversize MarkedBlocks, if the block size gets too big we can
+ underflow the endAtom, which will cause us to segfault when we try to sweep a block. If we're a
+ custom size MarkedBlock we need to calculate endAtom so it doesn't underflow.
+
+2012-10-14 Filip Pizlo <fpizlo@apple.com>
+
+ JIT::JIT fails to initialize all of its fields
+ https://bugs.webkit.org/show_bug.cgi?id=99283
+
+ Reviewed by Andreas Kling.
+
+ There were two groups of such fields, all of which are eventually initialized
+ prior to use inside of privateCompile(). But it's safer to make sure that they
+ are initialized in the constructor as well, since we may use the JIT to do a
+ stub compile without calling into privateCompile().
+
+ Unsigned index fields for dynamic repatching meta-data: this change
+ initializes them to UINT_MAX, so we should crash if we try to use those
+ indices without initializing them.
+
+ Boolean flags for value profiling: this change initializes them to false, so
+ we at worst turn off value profiling.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+
+2012-10-15 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ We should avoid weakCompareAndSwap when parallel GC is disabled
+ https://bugs.webkit.org/show_bug.cgi?id=99331
+
+ Reviewed by Filip Pizlo.
+
+ CopiedBlock::reportLiveBytes and didEvacuateBytes uses weakCompareAndSwap, which some platforms
+ don't support. For platforms that don't have parallel GC enabled, we should just use a normal store.
+
+ * heap/CopiedBlock.h:
+ (JSC::CopiedBlock::reportLiveBytes):
+ (JSC::CopiedBlock::didEvacuateBytes):
+
+2012-10-15 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add missing header file.
+
+2012-10-14 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should handle polymorphic array modes by eagerly transforming arrays into the most general applicable form
+ https://bugs.webkit.org/show_bug.cgi?id=99269
+
+ Reviewed by Geoffrey Garen.
+
+ This kills off a bunch of code for "polymorphic" array modes in the DFG. It should
+ also be a performance win for code that uses a lot of array storage arrays.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::fromObserved):
+ (JSC::DFG::modeAlreadyChecked):
+ (JSC::DFG::modeToString):
+ * dfg/DFGArrayMode.h:
+ (DFG):
+ (JSC::DFG::modeUsesButterfly):
+ (JSC::DFG::modeIsJSArray):
+ (JSC::DFG::mayStoreToTail):
+ (JSC::DFG::mayStoreToHole):
+ (JSC::DFG::canCSEStorage):
+ (JSC::DFG::modeSupportsLength):
+ (JSC::DFG::benefitsFromStructureCheck):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-14 Filip Pizlo <fpizlo@apple.com>
+
+ REGRESSION(126886): Fat binary builds don't know how to handle architecture variants to which the LLInt is agnostic
+ https://bugs.webkit.org/show_bug.cgi?id=99270
+
+ Reviewed by Geoffrey Garen.
+
+ The fix is to hash cons the offsets based on configuration index, not the offsets
+ themselves.
+
+ * offlineasm/offsets.rb:
+
+2012-10-13 Filip Pizlo <fpizlo@apple.com>
+
+ IndexingType should not have a bit for each type
+ https://bugs.webkit.org/show_bug.cgi?id=98997
+
+ Reviewed by Oliver Hunt.
+
+ Somewhat incidentally, the introduction of butterflies led to each indexing
+ type being represented by a unique bit. This is superficially nice since it
+ allows you to test if a structure corresponds to a particular indexing type
+ by saying !!(structure->indexingType() & TheType). But the downside is that
+ given the 8 bits we have for the m_indexingType field, that leaves only a
+ small number of possible indexing types if we have one per bit.
+
+ This changeset changes the indexing type to be:
+
+ Bit #1: Tells you if you're an array.
+
+ Bits #2 - #5: 16 possible indexing types, including the blank type for
+ objects that don't have indexed properties.
+
+ Bits #6-8: Auxiliary bits that we could use for other things. Currently we
+ just use one of those bits, for MayHaveIndexedAccessors.
+
+ This is performance-neutral, and is primarily intended to give us more
+ breathing room for introducing new inferred array modes.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::JumpList::jumps):
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::patchableBranch32):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::patchableBranch32):
+ (MacroAssemblerARMv7):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::modeAlreadyChecked):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateJSArray):
+ (JSC::JIT::chooseArrayMode):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emitArrayStorageGetByVal):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emitContiguousPutByVal):
+ (JSC::JIT::emitArrayStoragePutByVal):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emitArrayStorageGetByVal):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emitContiguousPutByVal):
+ (JSC::JIT::emitArrayStoragePutByVal):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/IndexingType.h:
+ (JSC):
+ (JSC::hasIndexedProperties):
+ (JSC::hasContiguous):
+ (JSC::hasFastArrayStorage):
+ (JSC::hasArrayStorage):
+ (JSC::shouldUseSlowPut):
+ * runtime/JSGlobalObject.cpp:
+ (JSC):
+ * runtime/StructureTransitionTable.h:
+ (JSC::newIndexingType):
+
+2012-10-14 Filip Pizlo <fpizlo@apple.com>
+
+ DFG structure check hoisting should attempt to ignore side effects and make transformations that are sound even in their presence
+ https://bugs.webkit.org/show_bug.cgi?id=99262
+
+ Reviewed by Oliver Hunt.
+
+ This hugely simplifies the structure check hoisting phase. It will no longer be necessary
+ to modify it when the effectfulness of operations changes. This also enables the hoister
+ to hoist effectful things in the future.
+
+ The downside is that the hoister may end up adding strictly more checks than were present
+ in the original code, if the code truly has a lot of side-effects. I don't see evidence
+ of this happening. This patch does have some speed-ups and some slow-downs, but is
+ neutral in the average, and the slow-downs do not appear to have more structure checks
+ than ToT.
+
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck):
+ (StructureCheckHoistingPhase):
+ (CheckData):
+ (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData):
+
+2012-10-14 Filip Pizlo <fpizlo@apple.com>
+
+ Fix the build of universal binary with ARMv7s of JavaScriptCore
+
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+
+2012-10-13 Filip Pizlo <fpizlo@apple.com>
+
+ Array length array profiling is broken in the baseline JIT
+ https://bugs.webkit.org/show_bug.cgi?id=99258
+
+ Reviewed by Oliver Hunt.
+
+ The code generator for array length stubs calls into
+ emitArrayProfilingSiteForBytecodeIndex(), which emits profiling only if
+ canBeOptimized() returns true. But m_canBeOptimized is only initialized during
+ full method compiles, so in a stub compile it may (or may not) be false, meaning
+ that we may, or may not, get meaningful profiling info.
+
+ This appeared to not affect too many programs since the LLInt has good array
+ length array profiling.
+
+ * jit/JIT.h:
+ (JSC::JIT::compilePatchGetArrayLength):
+
+2012-10-14 Patrick Gansterer <paroga@webkit.org>
+
+ Build fix for WinCE after r131089.
+
+ WinCE does not support getenv().
+
+ * runtime/Options.cpp:
+ (JSC::overrideOptionWithHeuristic):
+
+2012-10-12 Kangil Han <kangil.han@samsung.com>
+
+ Fix build error on DFGSpeculativeJIT32_64.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=99234
+
+ Reviewed by Anders Carlsson.
+
+ Seems BUG 98608 causes build error on 32bit machine so fix it.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-12 Filip Pizlo <fpizlo@apple.com>
+
+ Contiguous array allocation should always be inlined
+ https://bugs.webkit.org/show_bug.cgi?id=98608
+
+ Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+ This inlines contiguous array allocation in the most obvious way possible.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::branchSubPtr):
+ (MacroAssembler):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::branchSubPtr):
+ (MacroAssemblerX86_64):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGCCallHelpers.h:
+ (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
+ (CCallHelpers):
+ * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: Added.
+ (DFG):
+ (CallArrayAllocatorSlowPathGenerator):
+ (JSC::DFG::CallArrayAllocatorSlowPathGenerator::CallArrayAllocatorSlowPathGenerator):
+ (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal):
+ (CallArrayAllocatorWithVariableSizeSlowPathGenerator):
+ (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableSizeSlowPathGenerator):
+ (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+ (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Race condition during CopyingPhase can lead to deadlock
+ https://bugs.webkit.org/show_bug.cgi?id=99226
+
+ Reviewed by Filip Pizlo.
+
+ The main thread calls startCopying() for each of the GCThreads at the beginning of the copy phase.
+ It then proceeds to start copying. If copying completes before one of the GCThreads wakes up, the
+ main thread will set m_currentPhase back to NoPhase, the GCThread will wake up, see that there's
+ nothing to do, and then it will go back to sleep without ever calling CopyVisitor::doneCopying()
+ to return its borrowed block to the CopiedSpace. CopiedSpace::doneCopying() will then sleep forever
+ waiting on the block.
+
+ The fix for this is to make sure we call CopiedSpace::doneCopying() on the main thread before we
+ call GCThreadSharedData::didFinishCopying(), which sets the m_currentPhase flag to NoPhase. This
+ way we will wait until all threads have woken up and given back their borrowed blocks before
+ clearing the flag.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::copyBackingStores):
+
+2012-10-12 Anders Carlsson <andersca@apple.com>
+
+ Move macros from Parser.h to Parser.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=99217
+
+ Reviewed by Andreas Kling.
+
+ There are a bunch of macros in Parser.h that are only used in Parser.cpp. Move them to Parser.cpp
+ so they won't pollute the global namespace.
+ * parser/Parser.cpp:
+ * parser/Parser.h:
+ (JSC):
+
+2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Another build fix after r131213
+
+ Added some symbol magic to placate the linker on some platforms.
+
+ * JavaScriptCore.order:
+
+2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Build fix after r131213
+
+ Removed an unused variable that was making compilers unhappy.
+
+ * heap/GCThread.cpp:
+ (JSC::GCThread::GCThread):
+ * heap/GCThread.h:
+ (GCThread):
+ * heap/GCThreadSharedData.cpp:
+ (JSC::GCThreadSharedData::GCThreadSharedData):
+
+2012-10-09 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Copying collection shouldn't require O(live bytes) memory overhead
+ https://bugs.webkit.org/show_bug.cgi?id=98792
+
+ Reviewed by Filip Pizlo.
+
+ Currently our copying collection occurs simultaneously with the marking phase. We'd like
+ to be able to reuse CopiedBlocks as soon as they become fully evacuated, but this is not
+ currently possible because we don't know the liveness statistics of each old CopiedBlock
+ until marking/copying has already finished. Instead, we have to allocate additional memory
+ from the OS to use as our working set of CopiedBlocks while copying. We then return the
+ fully evacuated old CopiedBlocks back to the block allocator, thus giving our copying phase
+ an O(live bytes) overhead.
+
+ To fix this, we should instead split the copying phase apart from the marking phase. This
+ way we have full liveness data for each CopiedBlock during the copying phase so that we
+ can reuse them the instant they become fully evacuated. With the additional liveness data
+ that each CopiedBlock accumulates, we can add some additional heuristics to the collector.
+ For example, we can calculate our global Heap fragmentation and only choose to do a copying
+ phase if that fragmentation exceeds some limit. As another example, we can skip copying
+ blocks that are already above a particular fragmentation limit, which allows older objects
+ to coalesce into blocks that are rarely copied.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * heap/CopiedBlock.h:
+ (CopiedBlock):
+ (JSC::CopiedBlock::CopiedBlock): Added support for tracking live bytes in a CopiedBlock in a
+ thread-safe fashion.
+ (JSC::CopiedBlock::reportLiveBytes): Adds a number of live bytes to the block in a thread-safe
+ fashion using compare and swap.
+ (JSC):
+ (JSC::CopiedBlock::didSurviveGC): Called when a block survives a single GC without being
+ evacuated. This could be called for a couple reasons: (a) the block was pinned or (b) we
+ decided not to do any copying. A block can become pinned for a few reasons: (1) a pointer into
+ the block was found during the conservative scan. (2) the block was deemed full enough to
+ not warrant any copying. (3) The block is oversize and was found to be live.
+ (JSC::CopiedBlock::didEvacuateBytes): Called when some number of bytes are copied from this
+ block. If the number of live bytes ever hits zero, the block will return itself to the
+ BlockAllocator to be recycled.
+ (JSC::CopiedBlock::canBeRecycled): Indicates that a block has no live bytes and can be
+ immediately recycled. This is used for blocks that are found to have zero live bytes at the
+ beginning of the copying phase.
+ (JSC::CopiedBlock::shouldEvacuate): This function returns true if the current fragmentation
+ of the block is above our fragmentation threshold, and false otherwise.
+ (JSC::CopiedBlock::isPinned): Added an accessor for the pinned flag
+ (JSC::CopiedBlock::liveBytes):
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::CopiedSpace):
+ (JSC::CopiedSpace::doneFillingBlock): Changed so that we can exchange our filled block for a
+ fresh block. This avoids the situation where a thread returns its borrowed block, it's the last
+ borrowed block, so CopiedSpace thinks that copying has completed, and it starts doing all of the
+ copying phase cleanup. In actuality, the thread wanted another block after returning the current
+ block. So we allow the thread to atomically exchange its block for another block.
+ (JSC::CopiedSpace::startedCopying): Added the calculation of global Heap fragmentation to
+ determine if the copying phase should commence. We include the MarkedSpace in our fragmentation
+ calculation by assuming that the MarkedSpace is 0% fragmented since we can reuse any currently
+ free memory in it (i.e. we ignore any internal fragmentation in the MarkedSpace). While we're
+ calculating the fragmentation of CopiedSpace, we also return any free blocks we find along the
+ way (meaning liveBytes() == 0).
+ (JSC):
+ (JSC::CopiedSpace::doneCopying): We still have to iterate over all the blocks, regardless of
+ whether the copying phase took place or not so that we can reset all of the live bytes counters
+ and un-pin any pinned blocks.
+ * heap/CopiedSpace.h:
+ (CopiedSpace):
+ (JSC::CopiedSpace::shouldDoCopyPhase):
+ * heap/CopiedSpaceInlineMethods.h:
+ (JSC::CopiedSpace::recycleEvacuatedBlock): This function is distinct from recycling a borrowed block
+ because a borrowed block hasn't been added to the CopiedSpace yet, but an evacuated block is still
+ currently in CopiedSpace, so we have to make sure we properly remove all traces of the block from
+ CopiedSpace before returning it to BlockAllocator.
+ (JSC::CopiedSpace::recycleBorrowedBlock): Renamed to indicate the distinction mentioned above.
+ * heap/CopyVisitor.cpp: Added.
+ (JSC):
+ (JSC::CopyVisitor::CopyVisitor):
+ (JSC::CopyVisitor::copyFromShared): Main function for any thread participating in the copying phase.
+ Grabs chunks of MarkedBlocks from the shared list and copies the backing store of anybody who needs
+ it until there are no more chunks to copy.
+ * heap/CopyVisitor.h: Added.
+ (JSC):
+ (CopyVisitor):
+ * heap/CopyVisitorInlineMethods.h: Added.
+ (JSC):
+ (GCCopyPhaseFunctor):
+ (JSC::GCCopyPhaseFunctor::GCCopyPhaseFunctor):
+ (JSC::GCCopyPhaseFunctor::operator()):
+ (JSC::CopyVisitor::checkIfShouldCopy): We don't have to check shouldEvacuate() because all of those
+ checks are done during the marking phase.
+ (JSC::CopyVisitor::allocateNewSpace):
+ (JSC::CopyVisitor::allocateNewSpaceSlow):
+ (JSC::CopyVisitor::startCopying): Initialization function for a thread that is about to start copying.
+ (JSC::CopyVisitor::doneCopying):
+ (JSC::CopyVisitor::didCopy): This callback is called by an object that has just successfully copied its
+ backing store. It indicates to the CopiedBlock that somebody has just finished evacuating some number of
+ bytes from it, and, if the CopiedBlock now has no more live bytes, can be recycled immediately.
+ * heap/GCThread.cpp: Added.
+ (JSC):
+ (JSC::GCThread::GCThread): This is a new class that encapsulates a single thread responsible for participating
+ in a specific set of GC phases. Currently, that set of phases includes Mark, Copy, and Exit. Each thread
+ monitors a shared variable in its associated GCThreadSharedData. The main thread updates this m_currentPhase
+ variable as collection progresses through the various phases. Parallel marking still works exactly like it
+ has. In other words, the "run loop" for each of the GC threads sits above any individual phase, thus keeping
+ the separate phases of the collector orthogonal.
+ (JSC::GCThread::threadID):
+ (JSC::GCThread::initializeThreadID):
+ (JSC::GCThread::slotVisitor):
+ (JSC::GCThread::copyVisitor):
+ (JSC::GCThread::waitForNextPhase):
+ (JSC::GCThread::gcThreadMain):
+ (JSC::GCThread::gcThreadStartFunc):
+ * heap/GCThread.h: Added.
+ (JSC):
+ (GCThread):
+ * heap/GCThreadSharedData.cpp: The GCThreadSharedData now has a list of GCThread objects rather than raw
+ ThreadIdentifiers.
+ (JSC::GCThreadSharedData::resetChildren):
+ (JSC::GCThreadSharedData::childVisitCount):
+ (JSC::GCThreadSharedData::GCThreadSharedData):
+ (JSC::GCThreadSharedData::~GCThreadSharedData):
+ (JSC::GCThreadSharedData::reset):
+ (JSC::GCThreadSharedData::didStartMarking): Callback to let the GCThreadSharedData know that marking has
+ started and updates the m_currentPhase variable and notifies the GCThreads accordingly.
+ (JSC::GCThreadSharedData::didFinishMarking): Ditto for finishing marking.
+ (JSC::GCThreadSharedData::didStartCopying): Ditto for starting the copying phase.
+ (JSC::GCThreadSharedData::didFinishCopying): Ditto for finishing copying.
+ * heap/GCThreadSharedData.h:
+ (JSC):
+ (GCThreadSharedData):
+ (JSC::GCThreadSharedData::getNextBlocksToCopy): Atomically gets the next chunk of work for a copying thread.
+ * heap/Heap.cpp:
+ (JSC::Heap::Heap):
+ (JSC::Heap::markRoots):
+ (JSC):
+ (JSC::Heap::copyBackingStores): Responsible for setting up the copying phase, notifying the copying threads,
+ and doing any copying work if necessary.
+ (JSC::Heap::collect):
+ * heap/Heap.h:
+ (Heap):
+ (JSC):
+ (JSC::CopyFunctor::CopyFunctor):
+ (CopyFunctor):
+ (JSC::CopyFunctor::operator()):
+ * heap/IncrementalSweeper.cpp: Changed the incremental sweeper to have a reference to the list of MarkedBlocks
+ that need sweeping, since this now resides in the Heap so that it can be easily shared by the GCThreads.
+ (JSC::IncrementalSweeper::IncrementalSweeper):
+ (JSC::IncrementalSweeper::startSweeping):
+ * heap/IncrementalSweeper.h:
+ (JSC):
+ (IncrementalSweeper):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::setup):
+ (JSC::SlotVisitor::drainFromShared): We no longer do any copying-related work here.
+ (JSC):
+ * heap/SlotVisitor.h:
+ (SlotVisitor):
+ * heap/SlotVisitorInlineMethods.h:
+ (JSC):
+ (JSC::SlotVisitor::copyLater): Notifies the CopiedBlock that there are some live bytes that may need
+ to be copied.
+ * runtime/Butterfly.h:
+ (JSC):
+ (Butterfly):
+ * runtime/ButterflyInlineMethods.h:
+ (JSC::Butterfly::createUninitializedDuringCollection): Uses the new CopyVisitor.
+ * runtime/ClassInfo.h:
+ (MethodTable): Added new "virtual" function copyBackingStore to method table.
+ (JSC):
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::copyBackingStore): Default implementation that does nothing.
+ (JSC):
+ * runtime/JSCell.h:
+ (JSC):
+ (JSCell):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::copyButterfly): Does the actual copying of the butterfly.
+ (JSC):
+ (JSC::JSObject::visitButterfly): Calls copyLater for the butterfly.
+ (JSC::JSObject::copyBackingStore):
+ * runtime/JSObject.h:
+ (JSObject):
+ (JSC::JSCell::methodTable):
+ (JSC::JSCell::inherits):
+ * runtime/Options.h: Added two new constants, minHeapUtilization and minCopiedBlockUtilization,
+ to govern the amount of fragmentation we allow before doing copying.
+ (JSC):
+
+2012-10-12 Filip Pizlo <fpizlo@apple.com>
+
+ DFG array allocation calls should not return an encoded JSValue
+ https://bugs.webkit.org/show_bug.cgi?id=99196
+
+ Reviewed by Mark Hahnenberg.
+
+ The array allocation operations now return a pointer instead. This makes it
+ easier to share code between 32-bit and 64-bit.
+
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-01 Jer Noble <jer.noble@apple.com>
+
+ Enable ENCRYPTED_MEDIA support on Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=98044
+
+ Reviewed by Anders Carlsson.
+
+ Enable the ENCRYPTED_MEDIA flag.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-12 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed. It should be possible to build JSC on ARMv7.
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::patchableBranchPtr):
+
+2012-10-11 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ BlockAllocator should use regions as its VM allocation abstraction
+ https://bugs.webkit.org/show_bug.cgi?id=99107
+
+ Reviewed by Geoffrey Garen.
+
+ Currently the BlockAllocator allocates a single block at a time directly from the OS. Our block
+ allocations are on the large-ish side (64 KB) to amortize across many allocations the expense of
+ mapping new virtual memory from the OS. These large blocks are then shared between the MarkedSpace
+ and the CopiedSpace. This design makes it difficult to vary the size of the blocks in different
+ parts of the Heap while still allowing us to amortize the VM allocation costs.
+
+ We should redesign the BlockAllocator so that it has a layer of indirection between blocks that are
+ used by the allocator/collector and our primary unit of VM allocation from the OS. In particular,
+ the BlockAllocator should allocate Regions of virtual memory from the OS, which are then subdivided
+ into one or more Blocks to be used in our custom allocators. This design has the following nice properties:
+
+ 1) We can remove the knowledge of PageAllocationAligned from HeapBlocks. Each HeapBlock will now
+ only know what Region it belongs to. The Region maintains all the metadata for how to allocate
+ and deallocate virtual memory from the OS.
+
+ 2) We can easily allocate in larger chunks than we need to satisfy a particular request for a Block.
+ We can then continue to amortize our VM allocation costs while allowing for smaller block sizes,
+ which should increase locality in the mutator when allocating, lazy sweeping, etc.
+
+ 3) By encapsulating the logic of where our memory comes from inside of the Region class, we can more
+ easily transition over to allocating VM from a specific range of pre-reserved address space. This
+ will be a necessary step along the way to 32-bit pointers.
+
+ This particular patch will not change the size of MarkedBlocks or CopiedBlocks, nor will it change how
+ much VM we allocate per failed Block request. It only sets up the data structures that we need to make
+ these changes in future patches.
+
+ Most of the changes in this patch relate to the addition of the Region class to be used by the
+ BlockAllocator and the threading of changes made to BlockAllocator's interface through to the call sites.
+
+ * heap/BlockAllocator.cpp: The BlockAllocator now has three lists that track the three disjoint sets of
+ Regions that it cares about: empty regions, partially full regions, and completely full regions.
+ Empty regions have no blocks currently in use and can be freed immediately if the freeing thread
+ determines they should be. Partial regions have some blocks used, but aren't completely in use yet.
+ These regions are preferred for recycling before empty regions to mitigate fragmentation within regions.
+ Completely full regions are no longer able to be used for allocations. Regions move between these
+ three lists as they are created and their constituent blocks are allocated and deallocated.
+ (JSC::BlockAllocator::BlockAllocator):
+ (JSC::BlockAllocator::~BlockAllocator):
+ (JSC::BlockAllocator::releaseFreeRegions):
+ (JSC::BlockAllocator::waitForRelativeTimeWhileHoldingLock):
+ (JSC::BlockAllocator::waitForRelativeTime):
+ (JSC::BlockAllocator::blockFreeingThreadMain):
+ * heap/BlockAllocator.h:
+ (JSC):
+ (DeadBlock):
+ (JSC::DeadBlock::DeadBlock):
+ (Region):
+ (JSC::Region::blockSize):
+ (JSC::Region::isFull):
+ (JSC::Region::isEmpty):
+ (JSC::Region::create): This function is responsible for doing the actual VM allocation. This should be the
+ only function in the entire JSC object runtime that calls out the OS for virtual memory allocation.
+ (JSC::Region::Region):
+ (JSC::Region::~Region):
+ (JSC::Region::allocate):
+ (JSC::Region::deallocate):
+ (BlockAllocator):
+ (JSC::BlockAllocator::tryAllocateFromRegion): Helper function that encapsulates checking a particular list
+ of regions for a free block.
+ (JSC::BlockAllocator::allocate):
+ (JSC::BlockAllocator::allocateCustomSize): This function is responsible for allocating one-off custom size
+ regions for use in oversize allocations in both the MarkedSpace and the CopiedSpace. These regions are not
+ tracked by the BlockAllocator. The only pointer to them is in the HeapBlock that is returned. These regions
+ contain exactly one block.
+ (JSC::BlockAllocator::deallocate):
+ (JSC::BlockAllocator::deallocateCustomSize): This function is responsible for deallocating one-off custom size
+ regions. The regions are deallocated back to the OS eagerly.
+ * heap/CopiedBlock.h: Re-worked CopiedBlocks to use Regions instead of PageAllocationAligned.
+ (CopiedBlock):
+ (JSC::CopiedBlock::createNoZeroFill):
+ (JSC::CopiedBlock::create):
+ (JSC::CopiedBlock::CopiedBlock):
+ (JSC::CopiedBlock::payloadEnd):
+ (JSC::CopiedBlock::capacity):
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::~CopiedSpace):
+ (JSC::CopiedSpace::tryAllocateOversize):
+ (JSC::CopiedSpace::tryReallocateOversize):
+ (JSC::CopiedSpace::doneCopying):
+ * heap/CopiedSpaceInlineMethods.h:
+ (JSC::CopiedSpace::allocateBlockForCopyingPhase):
+ (JSC::CopiedSpace::allocateBlock):
+ * heap/HeapBlock.h:
+ (JSC::HeapBlock::destroy):
+ (JSC::HeapBlock::HeapBlock):
+ (JSC::HeapBlock::region):
+ (HeapBlock):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::allocateBlock):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::create):
+ (JSC::MarkedBlock::MarkedBlock):
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::capacity):
+ * heap/MarkedSpace.cpp:
+ (JSC::MarkedSpace::freeBlock):
+
+2012-10-11 Filip Pizlo <fpizlo@apple.com>
+
+ UInt32ToNumber and OSR exit should be aware of copy propagation and correctly recover both versions of a variable that was subject to a UInt32ToNumber cast
+ https://bugs.webkit.org/show_bug.cgi?id=99100
+ <rdar://problem/12480955>
+
+ Reviewed by Michael Saboff and Mark Hahnenberg.
+
+ Fixed by forcing UInt32ToNumber to use a different register. This "undoes" the copy propagation that we
+ would have been doing, since it has no performance effect in this case and has the benefit of making the
+ OSR exit compiler a lot simpler.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber):
+
+2012-10-11 Geoffrey Garen <ggaren@apple.com>
+
+ Removed some more static assumptions about inline object capacity
+ https://bugs.webkit.org/show_bug.cgi?id=98603
+
+ Reviewed by Filip Pizlo.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): Use JSObject::allocationSize()
+ for a little more flexibility. We still pass it a constant inline capacity
+ because the JIT doesn't have a strategy for selecting a size class based
+ on non-constant capacity yet. "INLINE_STORAGE_CAPACITY" is a marker for
+ code that makes static assumptions about object size.
+
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateBasicJSObject):
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm: Ditto for the rest of our many execution engines.
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::allocationSize):
+ (JSC::JSFinalObject::finishCreation):
+ (JSC::JSFinalObject::create): New helper function for computing object
+ size dynamically, since we plan to have objects of different sizes.
+
+ (JSC::JSFinalObject::JSFinalObject): Note that our m_inlineStorage used
+ to auto-generate an implicit C++ constructor with default null initialization.
+ This memory is not observed in its uninitialized state, and our LLInt and
+ JIT allocators do not initialize it, so I did not add any explicit code
+ to do so, now that the implicit code is gone.
+
+ (JSC::JSObject::offsetOfInlineStorage): Changed the math here to match
+ inlineStorageUnsafe(), since we can rely on an explicit data member anymore.
+
+2012-10-11 Geoffrey Garen <ggaren@apple.com>
+
+ Enable RUNTIME_HEURISTICS all the time, for easier testing
+ https://bugs.webkit.org/show_bug.cgi?id=99090
+
+ Reviewed by Filip Pizlo.
+
+ I find myself using this a lot, and there doesn't seem to be an obvious
+ reason to compile it out, since it only runs once at startup.
+
+ * runtime/Options.cpp:
+ (JSC::overrideOptionWithHeuristic):
+ (JSC::Options::initialize):
+ * runtime/Options.h: Removed the #ifdef.
+
+2012-10-11 Geoffrey Garen <ggaren@apple.com>
+
+ Removed ASSERT_CLASS_FITS_IN_CELL
+ https://bugs.webkit.org/show_bug.cgi?id=97634
+
+ Reviewed by Mark Hahnenberg.
+
+ Our collector now supports arbitrarily sized objects, so the ASSERT is not needed.
+
+ * API/JSCallbackFunction.cpp:
+ * API/JSCallbackObject.cpp:
+ * heap/MarkedSpace.h:
+ * jsc.cpp:
+ * runtime/Arguments.cpp:
+ * runtime/ArrayConstructor.cpp:
+ * runtime/ArrayPrototype.cpp:
+ * runtime/BooleanConstructor.cpp:
+ * runtime/BooleanObject.cpp:
+ * runtime/BooleanPrototype.cpp:
+ * runtime/DateConstructor.cpp:
+ * runtime/DatePrototype.cpp:
+ * runtime/Error.cpp:
+ * runtime/ErrorConstructor.cpp:
+ * runtime/ErrorPrototype.cpp:
+ * runtime/FunctionConstructor.cpp:
+ * runtime/FunctionPrototype.cpp:
+ * runtime/InternalFunction.cpp:
+ * runtime/JSActivation.cpp:
+ * runtime/JSArray.cpp:
+ * runtime/JSBoundFunction.cpp:
+ * runtime/JSFunction.cpp:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalThis.cpp:
+ * runtime/JSNameScope.cpp:
+ * runtime/JSNotAnObject.cpp:
+ * runtime/JSONObject.cpp:
+ * runtime/JSObject.cpp:
+ * runtime/JSPropertyNameIterator.cpp:
+ * runtime/JSScope.cpp:
+ * runtime/JSWithScope.cpp:
+ * runtime/JSWrapperObject.cpp:
+ * runtime/MathObject.cpp:
+ * runtime/NameConstructor.cpp:
+ * runtime/NamePrototype.cpp:
+ * runtime/NativeErrorConstructor.cpp:
+ * runtime/NativeErrorPrototype.cpp:
+ * runtime/NumberConstructor.cpp:
+ * runtime/NumberObject.cpp:
+ * runtime/NumberPrototype.cpp:
+ * runtime/ObjectConstructor.cpp:
+ * runtime/ObjectPrototype.cpp:
+ * runtime/RegExpConstructor.cpp:
+ * runtime/RegExpMatchesArray.cpp:
+ * runtime/RegExpObject.cpp:
+ * runtime/RegExpPrototype.cpp:
+ * runtime/StringConstructor.cpp:
+ * runtime/StringObject.cpp:
+ * runtime/StringPrototype.cpp:
+ * testRegExp.cpp: Removed the ASSERT.
+
+2012-10-11 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should inline code blocks that use new_array_buffer
+ https://bugs.webkit.org/show_bug.cgi?id=98996
+
+ Reviewed by Geoffrey Garen.
+
+ This adds plumbing to drop in constant buffers from the inlinees to the inliner.
+ It's smart about not duplicating buffers needlessly but doesn't try to completely
+ hash-cons them, either.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::numberOfConstantBuffers):
+ (JSC::CodeBlock::addConstantBuffer):
+ (JSC::CodeBlock::constantBufferAsVector):
+ (JSC::CodeBlock::constantBuffer):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (ConstantBufferKey):
+ (JSC::DFG::ConstantBufferKey::ConstantBufferKey):
+ (JSC::DFG::ConstantBufferKey::operator==):
+ (JSC::DFG::ConstantBufferKey::hash):
+ (JSC::DFG::ConstantBufferKey::isHashTableDeletedValue):
+ (JSC::DFG::ConstantBufferKey::codeBlock):
+ (JSC::DFG::ConstantBufferKey::index):
+ (DFG):
+ (JSC::DFG::ConstantBufferKeyHash::hash):
+ (JSC::DFG::ConstantBufferKeyHash::equal):
+ (ConstantBufferKeyHash):
+ (WTF):
+ (ByteCodeParser):
+ (InlineStackEntry):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canInlineOpcode):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-10-10 Zoltan Horvath <zoltan@webkit.org>
+
+ Pageload tests should measure memory usage
+ https://bugs.webkit.org/show_bug.cgi?id=93958
+
+ Reviewed by Ryosuke Niwa.
+
+ Add JS Heap and Heap memory measurement to PageLoad tests.
+
+ * heap/HeapStatistics.cpp:
+ (JSC::HeapStatistics::usedJSHeap): Add new private function to expose the used JS Heap size.
+ (JSC):
+ * heap/HeapStatistics.h:
+ (HeapStatistics): Add new private function to expose the used JS Heap size.
+
+2012-10-10 Balazs Kilvady <kilvadyb@homejinni.com>
+
+ RegisterFile to JSStack rename fix for a struct member.
+
+ Compilation problem in debug build on MIPS
+ https://bugs.webkit.org/show_bug.cgi?id=98808
+
+ Reviewed by Alexey Proskuryakov.
+
+ In ASSERT conditions structure field name "registerFile" was replaced
+ with type name "JSStack" and it should be "stack".
+
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks): structure member name fix.
+
+2012-10-10 Michael Saboff <msaboff@apple.com>
+
+ After r130344, OpaqueJSString::string() shouldn't directly return the wrapped String
+ https://bugs.webkit.org/show_bug.cgi?id=98801
+
+ Reviewed by Geoffrey Garen.
+
+ Return a copy of the wrapped String so that the wrapped string cannot be turned into
+ an Identifier.
+
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::string):
+ * API/OpaqueJSString.h:
+ (OpaqueJSString):
+
+2012-10-10 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Add moveDoubleToInts and moveIntsToDouble to MacroAssemblerARM
+ https://bugs.webkit.org/show_bug.cgi?id=98855
+
+ Reviewed by Filip Pizlo.
+
+ Implement the missing moveDoubleToInts and moveIntsToDouble
+ methods in the MacroAssemblerARM after r130839.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::moveDoubleToInts):
+ (MacroAssemblerARM):
+ (JSC::MacroAssemblerARM::moveIntsToDouble):
+
+2012-10-09 Filip Pizlo <fpizlo@apple.com>
+
+ Typed arrays should not be 20x slower in the baseline JIT than in the DFG JIT
+ https://bugs.webkit.org/show_bug.cgi?id=98605
+
+ Reviewed by Oliver Hunt and Gavin Barraclough.
+
+ This adds typed array get_by_val/put_by_val patching to the baseline JIT. It's
+ a big (~40%) win on benchmarks that have trouble staying in the DFG JIT. Even
+ if we fix those benchmarks, this functionality gives us the insurance that we
+ typically desire with all speculative optimizations: even if we bail to
+ baseline, we're still reasonably performant.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/MacroAssembler.cpp: Added.
+ (JSC):
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::patchableBranchPtr):
+ * assembler/MacroAssemblerARMv7.h:
+ (MacroAssemblerARMv7):
+ (JSC::MacroAssemblerARMv7::moveDoubleToInts):
+ (JSC::MacroAssemblerARMv7::moveIntsToDouble):
+ (JSC::MacroAssemblerARMv7::patchableBranchPtr):
+ * assembler/MacroAssemblerX86.h:
+ (MacroAssemblerX86):
+ (JSC::MacroAssemblerX86::moveDoubleToInts):
+ (JSC::MacroAssemblerX86::moveIntsToDouble):
+ * bytecode/ByValInfo.h:
+ (JSC::hasOptimizableIndexingForClassInfo):
+ (JSC):
+ (JSC::hasOptimizableIndexing):
+ (JSC::jitArrayModeForClassInfo):
+ (JSC::jitArrayModeForStructure):
+ (JSC::ByValInfo::ByValInfo):
+ (ByValInfo):
+ * dfg/DFGAssemblyHelpers.cpp:
+ (DFG):
+ * dfg/DFGAssemblyHelpers.h:
+ (AssemblyHelpers):
+ (JSC::DFG::AssemblyHelpers::boxDouble):
+ (JSC::DFG::AssemblyHelpers::unboxDouble):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::privateCompileGetByVal):
+ (JSC::JIT::privateCompilePutByVal):
+ (JSC::JIT::emitIntTypedArrayGetByVal):
+ (JSC):
+ (JSC::JIT::emitFloatTypedArrayGetByVal):
+ (JSC::JIT::emitIntTypedArrayPutByVal):
+ (JSC::JIT::emitFloatTypedArrayPutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSCell.h:
+ * runtime/JSGlobalData.h:
+ (JSGlobalData):
+ (JSC::JSGlobalData::typedArrayDescriptor):
+ * runtime/TypedArrayDescriptor.h: Added.
+ (JSC):
+ (JSC::TypedArrayDescriptor::TypedArrayDescriptor):
+ (TypedArrayDescriptor):
+
+2012-10-09 Michael Saboff <msaboff@apple.com>
+
+ Add tests to testapi for null OpaqueJSStrings
+ https://bugs.webkit.org/show_bug.cgi?id=98805
+
+ Reviewed by Geoffrey Garen.
+
+ Added tests that check that OpaqueJSString, which is wrapped via JSStringRef, properly returns
+ null strings and that a null string in a JSStringRef will return a NULL JSChar* and 0 length
+ via the JSStringGetCharactersPtr() and JSStringGetLength() APIs respectively. Added a check that
+ JSValueMakeFromJSONString() properly handles a null string as well.
+
+ * API/tests/testapi.c:
+ (main):
+
+2012-10-09 Jian Li <jianli@chromium.org>
+
+ Update the CSS property used to support draggable regions.
+ https://bugs.webkit.org/show_bug.cgi?id=97156
+
+ Reviewed by Adam Barth.
+
+ The CSS property to support draggable regions, guarded under
+ WIDGET_REGION is now disabled from Mac WebKit, in order not to cause
+ confusion with DASHBOARD_SUPPORT feature.
+
+ * Configurations/FeatureDefines.xcconfig: Disable WIDGET_REGION feature.
+
+2012-10-09 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, adding forgotten files.
+
+ * bytecode/ByValInfo.h: Added.
+ (JSC):
+ (JSC::isOptimizableIndexingType):
+ (JSC::jitArrayModeForIndexingType):
+ (JSC::ByValInfo::ByValInfo):
+ (ByValInfo):
+ (JSC::getByValInfoBytecodeIndex):
+ * runtime/IndexingType.cpp: Added.
+ (JSC):
+ (JSC::indexingTypeToString):
+
+2012-10-08 Filip Pizlo <fpizlo@apple.com>
+
+ JSC should infer when indexed storage is contiguous, and optimize for it
+ https://bugs.webkit.org/show_bug.cgi?id=97288
+
+ Reviewed by Mark Hahnenberg.
+
+ This introduces a new kind of indexed property storage called Contiguous,
+ which has the following properties:
+
+ - No header bits beyond IndexedHeader. This results in a 16 byte reduction
+ in memory usage per array versus an ArrayStorage array. It also means
+ that the total memory usage for an empty array is now just 3 * 8 on both
+ 32-bit and 64-bit. Of that, only 8 bytes are array-specific; the rest is
+ our standard object header overhead.
+
+ - No need for hole checks on store. This results in a ~4% speed-up on
+ Kraken and a ~1% speed-up on V8v7.
+
+ - publicLength <= vectorLength. This means that doing new Array(blah)
+ immediately allocates room for blah elements.
+
+ - No sparse map or index bias.
+
+ If you ever do things to an array that would require publicLength >
+ vectorLength, a sparse map, or index bias, then we switch to ArrayStorage
+ mode. This seems to never happen in any benchmark we track, and is unlikely
+ to happen very frequently on any website.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::JumpList::append):
+ * assembler/MacroAssembler.h:
+ (MacroAssembler):
+ (JSC::MacroAssembler::patchableBranchTest32):
+ * bytecode/ByValInfo.h: Added.
+ (JSC):
+ (JSC::isOptimizableIndexingType):
+ (JSC::jitArrayModeForIndexingType):
+ (JSC::ByValInfo::ByValInfo):
+ (ByValInfo):
+ (JSC::getByValInfoBytecodeIndex):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::getByValInfo):
+ (JSC::CodeBlock::setNumberOfByValInfos):
+ (JSC::CodeBlock::numberOfByValInfos):
+ (JSC::CodeBlock::byValInfo):
+ * bytecode/SamplingTool.h:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::fromObserved):
+ (JSC::DFG::modeAlreadyChecked):
+ (JSC::DFG::modeToString):
+ * dfg/DFGArrayMode.h:
+ (DFG):
+ (JSC::DFG::modeUsesButterfly):
+ (JSC::DFG::modeIsJSArray):
+ (JSC::DFG::isInBoundsAccess):
+ (JSC::DFG::mayStoreToTail):
+ (JSC::DFG::mayStoreToHole):
+ (JSC::DFG::modeIsPolymorphic):
+ (JSC::DFG::polymorphicIncludesContiguous):
+ (JSC::DFG::polymorphicIncludesArrayStorage):
+ (JSC::DFG::canCSEStorage):
+ (JSC::DFG::modeSupportsLength):
+ (JSC::DFG::benefitsFromStructureCheck):
+ (JSC::DFG::isEffectful):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::getArrayLengthElimination):
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::blessArrayOperation):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryCacheGetByID):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ (JSC::DFG::SpeculativeJIT::arrayify):
+ (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+ (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
+ (DFG):
+ * dfg/DFGSpeculativeJIT.h:
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister):
+ (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal):
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal):
+ (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
+ (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * interpreter/Interpreter.cpp:
+ (SamplingScope):
+ (JSC::SamplingScope::SamplingScope):
+ (JSC::SamplingScope::~SamplingScope):
+ (JSC):
+ (JSC::Interpreter::execute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::ByValCompilationInfo::ByValCompilationInfo):
+ (ByValCompilationInfo):
+ (JSC):
+ (JIT):
+ (JSC::JIT::compileGetByVal):
+ (JSC::JIT::compilePutByVal):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateJSArray):
+ (JSC::JIT::emitArrayProfileStoreToHoleSpecialCase):
+ (JSC):
+ (JSC::arrayProfileSaw):
+ (JSC::JIT::chooseArrayMode):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emitSlow_op_get_argument_by_val):
+ (JSC::JIT::emit_op_new_array):
+ (JSC::JIT::emitSlow_op_new_array):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emitSlow_op_get_argument_by_val):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emitArrayStorageGetByVal):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emitContiguousPutByVal):
+ (JSC::JIT::emitArrayStoragePutByVal):
+ (JSC::JIT::emitSlow_op_put_by_val):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByVal):
+ (JSC::JIT::privateCompilePutByVal):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC):
+ (JSC::JIT::emitContiguousGetByVal):
+ (JSC::JIT::emitArrayStorageGetByVal):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::emitContiguousPutByVal):
+ (JSC::JIT::emitArrayStoragePutByVal):
+ (JSC::JIT::emitSlow_op_put_by_val):
+ * jit/JITStubs.cpp:
+ (JSC::getByVal):
+ (JSC):
+ (JSC::DEFINE_STUB_FUNCTION):
+ (JSC::putByVal):
+ * jit/JITStubs.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * runtime/ArrayConventions.h:
+ (JSC::isDenseEnoughForVector):
+ * runtime/ArrayPrototype.cpp:
+ (JSC):
+ (JSC::shift):
+ (JSC::unshift):
+ (JSC::arrayProtoFuncPush):
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ * runtime/Butterfly.h:
+ (Butterfly):
+ (JSC::Butterfly::fromPointer):
+ (JSC::Butterfly::pointer):
+ (JSC::Butterfly::publicLength):
+ (JSC::Butterfly::vectorLength):
+ (JSC::Butterfly::setPublicLength):
+ (JSC::Butterfly::setVectorLength):
+ (JSC::Butterfly::contiguous):
+ (JSC::Butterfly::fromContiguous):
+ * runtime/ButterflyInlineMethods.h:
+ (JSC::Butterfly::unshift):
+ (JSC::Butterfly::shift):
+ * runtime/IndexingHeaderInlineMethods.h:
+ (JSC::IndexingHeader::indexingPayloadSizeInBytes):
+ * runtime/IndexingType.cpp: Added.
+ (JSC):
+ (JSC::indexingTypeToString):
+ * runtime/IndexingType.h:
+ (JSC):
+ (JSC::hasContiguous):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::setLengthWithArrayStorage):
+ (JSC::JSArray::setLength):
+ (JSC):
+ (JSC::JSArray::pop):
+ (JSC::JSArray::push):
+ (JSC::JSArray::shiftCountWithArrayStorage):
+ (JSC::JSArray::shiftCountWithAnyIndexingType):
+ (JSC::JSArray::unshiftCountWithArrayStorage):
+ (JSC::JSArray::unshiftCountWithAnyIndexingType):
+ (JSC::JSArray::sortNumericVector):
+ (JSC::JSArray::sortNumeric):
+ (JSC::JSArray::sortCompactedVector):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::sortVector):
+ (JSC::JSArray::fillArgList):
+ (JSC::JSArray::copyToArguments):
+ (JSC::JSArray::compactForSorting):
+ * runtime/JSArray.h:
+ (JSC::JSArray::shiftCountForShift):
+ (JSC::JSArray::shiftCountForSplice):
+ (JSArray):
+ (JSC::JSArray::shiftCount):
+ (JSC::JSArray::unshiftCountForShift):
+ (JSC::JSArray::unshiftCountForSplice):
+ (JSC::JSArray::unshiftCount):
+ (JSC::JSArray::isLengthWritable):
+ (JSC::createContiguousArrayButterfly):
+ (JSC):
+ (JSC::JSArray::create):
+ (JSC::JSArray::tryCreateUninitialized):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ (JSC::JSGlobalObject::haveABadTime):
+ (JSC::JSGlobalObject::visitChildren):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::arrayStructureWithArrayStorage):
+ (JSC::JSGlobalObject::addressOfArrayStructureWithArrayStorage):
+ (JSC::constructEmptyArray):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::visitButterfly):
+ (JSC::JSObject::getOwnPropertySlotByIndex):
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::enterDictionaryIndexingMode):
+ (JSC::JSObject::createInitialContiguous):
+ (JSC):
+ (JSC::JSObject::createArrayStorage):
+ (JSC::JSObject::convertContiguousToArrayStorage):
+ (JSC::JSObject::ensureContiguousSlow):
+ (JSC::JSObject::ensureArrayStorageSlow):
+ (JSC::JSObject::ensureIndexedStorageSlow):
+ (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
+ (JSC::JSObject::switchToSlowPutArrayStorage):
+ (JSC::JSObject::setPrototype):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::defineOwnIndexedProperty):
+ (JSC::JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes):
+ (JSC::JSObject::putByIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
+ (JSC::JSObject::putDirectIndexBeyondVectorLength):
+ (JSC::JSObject::getNewVectorLength):
+ (JSC::JSObject::countElementsInContiguous):
+ (JSC::JSObject::increaseVectorLength):
+ (JSC::JSObject::ensureContiguousLengthSlow):
+ (JSC::JSObject::getOwnPropertyDescriptor):
+ * runtime/JSObject.h:
+ (JSC::JSObject::getArrayLength):
+ (JSC::JSObject::getVectorLength):
+ (JSC::JSObject::canGetIndexQuickly):
+ (JSC::JSObject::getIndexQuickly):
+ (JSC::JSObject::tryGetIndexQuickly):
+ (JSC::JSObject::canSetIndexQuickly):
+ (JSC::JSObject::canSetIndexQuicklyForPutDirect):
+ (JSC::JSObject::setIndexQuickly):
+ (JSC::JSObject::initializeIndex):
+ (JSC::JSObject::hasSparseMap):
+ (JSC::JSObject::inSparseIndexingMode):
+ (JSObject):
+ (JSC::JSObject::ensureContiguous):
+ (JSC::JSObject::ensureIndexedStorage):
+ (JSC::JSObject::ensureContiguousLength):
+ (JSC::JSObject::indexingData):
+ (JSC::JSObject::relevantLength):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::description):
+ * runtime/Options.cpp:
+ (JSC::Options::initialize):
+ * runtime/Structure.cpp:
+ (JSC::Structure::needsSlowPutIndexing):
+ (JSC):
+ (JSC::Structure::suggestedArrayStorageTransition):
+ * runtime/Structure.h:
+ (Structure):
+ * runtime/StructureTransitionTable.h:
+ (JSC::newIndexingType):
+
+2012-10-09 Michael Saboff <msaboff@apple.com>
+
+ After r130344, OpaqueJSString::identifier() adds wrapped String to identifier table
+ https://bugs.webkit.org/show_bug.cgi?id=98693
+ REGRESSION (r130344): Install failed in Install Environment
+ <rdar://problem/12450118>
+
+ Reviewed by Mark Rowe.
+
+ Use Identifier(LChar*, length) or Identifier(UChar*, length) constructors so that we don't
+ add the String instance in the OpaqueJSString to any identifier tables.
+
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::identifier):
+
+2012-10-08 Mark Lam <mark.lam@apple.com>
+
+ Renamed RegisterFile to JSStack, and removed prototype of the
+ previously deleted Interpreter::privateExecute().
+ https://bugs.webkit.org/show_bug.cgi?id=98717.
+
+ Reviewed by Filip Pizlo.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.order:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/BytecodeConventions.h:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::nameForRegister):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ * bytecode/ValueRecovery.h:
+ (JSC::ValueRecovery::alreadyInJSStack):
+ (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt32):
+ (JSC::ValueRecovery::alreadyInJSStackAsUnboxedCell):
+ (JSC::ValueRecovery::alreadyInJSStackAsUnboxedBoolean):
+ (JSC::ValueRecovery::alreadyInJSStackAsUnboxedDouble):
+ (JSC::ValueRecovery::displacedInJSStack):
+ (JSC::ValueRecovery::isAlreadyInJSStack):
+ (JSC::ValueRecovery::virtualRegister):
+ (JSC::ValueRecovery::dump):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::resolveCallee):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitConstruct):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::registerFor):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ * dfg/DFGAssemblyHelpers.h:
+ (JSC::DFG::AssemblyHelpers::emitGetFromCallFrameHeaderPtr):
+ (JSC::DFG::AssemblyHelpers::emitPutToCallFrameHeader):
+ (JSC::DFG::AssemblyHelpers::emitPutImmediateToCallFrameHeader):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::getDirect):
+ (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal):
+ (JSC::DFG::ByteCodeParser::addCall):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGGenerationInfo.h:
+ (GenerationInfo):
+ (JSC::DFG::GenerationInfo::needsSpill):
+ * dfg/DFGGraph.h:
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compileEntry):
+ (JSC::DFG::JITCompiler::compileFunction):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::beginCall):
+ * dfg/DFGOSREntry.cpp:
+ (JSC::DFG::prepareOSREntry):
+ * dfg/DFGOSRExitCompiler32_64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGOSRExitCompiler64.cpp:
+ (JSC::DFG::OSRExitCompiler::compileExit):
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::tryBuildGetByIDList):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+ (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::spill):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillInteger):
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGThunks.cpp:
+ (JSC::DFG::throwExceptionFromCallSlowPathGenerator):
+ (JSC::DFG::slowPathFor):
+ (JSC::DFG::virtualForThunkGenerator):
+ * dfg/DFGValueSource.cpp:
+ (JSC::DFG::ValueSource::dump):
+ * dfg/DFGValueSource.h:
+ (JSC::DFG::dataFormatToValueSourceKind):
+ (JSC::DFG::valueSourceKindToDataFormat):
+ (JSC::DFG::isInJSStack):
+ (JSC::DFG::ValueSource::forSpeculation):
+ (JSC::DFG::ValueSource::isInJSStack):
+ (JSC::DFG::ValueSource::valueRecovery):
+ * dfg/DFGVariableEventStream.cpp:
+ (JSC::DFG::VariableEventStream::reconstruct):
+ * heap/Heap.cpp:
+ (JSC::Heap::stack):
+ (JSC::Heap::getConservativeRegisterRoots):
+ (JSC::Heap::markRoots):
+ * heap/Heap.h:
+ (JSC):
+ (Heap):
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::stack):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::calleeAsValue):
+ (JSC::ExecState::callee):
+ (JSC::ExecState::codeBlock):
+ (JSC::ExecState::scope):
+ (JSC::ExecState::callerFrame):
+ (JSC::ExecState::returnPC):
+ (JSC::ExecState::hasReturnPC):
+ (JSC::ExecState::clearReturnPC):
+ (JSC::ExecState::bytecodeOffsetForNonDFGCode):
+ (JSC::ExecState::setBytecodeOffsetForNonDFGCode):
+ (JSC::ExecState::inlineCallFrame):
+ (JSC::ExecState::codeOriginIndexForDFG):
+ (JSC::ExecState::currentVPC):
+ (JSC::ExecState::setCurrentVPC):
+ (JSC::ExecState::setCallerFrame):
+ (JSC::ExecState::setScope):
+ (JSC::ExecState::init):
+ (JSC::ExecState::argumentCountIncludingThis):
+ (JSC::ExecState::offsetFor):
+ (JSC::ExecState::setArgumentCountIncludingThis):
+ (JSC::ExecState::setCallee):
+ (JSC::ExecState::setCodeBlock):
+ (JSC::ExecState::setReturnPC):
+ (JSC::ExecState::setInlineCallFrame):
+ (ExecState):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::slideRegisterWindowForCall):
+ (JSC::eval):
+ (JSC::loadVarargs):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ (JSC::Interpreter::endRepeatCall):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::stack):
+ (Interpreter):
+ (JSC::Interpreter::execute):
+ (JSC):
+ * interpreter/JSStack.cpp: Copied from Source/JavaScriptCore/interpreter/RegisterFile.cpp.
+ (JSC::stackStatisticsMutex):
+ (JSC::JSStack::~JSStack):
+ (JSC::JSStack::growSlowCase):
+ (JSC::JSStack::gatherConservativeRoots):
+ (JSC::JSStack::releaseExcessCapacity):
+ (JSC::JSStack::initializeThreading):
+ (JSC::JSStack::committedByteCount):
+ (JSC::JSStack::addToCommittedByteCount):
+ * interpreter/JSStack.h: Copied from Source/JavaScriptCore/interpreter/RegisterFile.h.
+ (JSStack):
+ (JSC::JSStack::JSStack):
+ (JSC::JSStack::shrink):
+ (JSC::JSStack::grow):
+ * interpreter/RegisterFile.cpp: Removed.
+ * interpreter/RegisterFile.h: Removed.
+ * interpreter/VMInspector.cpp:
+ (JSC::VMInspector::dumpFrame):
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC):
+ (JIT):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileLoadVarargs):
+ (JSC::JIT::compileCallEval):
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCall):
+ * jit/JITCall32_64.cpp:
+ (JSC::JIT::emit_op_ret):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ (JSC::JIT::compileLoadVarargs):
+ (JSC::JIT::compileCallEval):
+ (JSC::JIT::compileCallEvalSlowCase):
+ (JSC::JIT::compileOpCall):
+ * jit/JITCode.h:
+ (JSC):
+ (JSC::JITCode::execute):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutToCallFrameHeader):
+ (JSC::JIT::emitPutCellToCallFrameHeader):
+ (JSC::JIT::emitPutIntToCallFrameHeader):
+ (JSC::JIT::emitPutImmediateToCallFrameHeader):
+ (JSC::JIT::emitGetFromCallFrameHeaderPtr):
+ (JSC::JIT::emitGetFromCallFrameHeader32):
+ (JSC::JIT::updateTopCallFrame):
+ (JSC::JIT::unmap):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_end):
+ (JSC::JIT::emit_op_ret):
+ (JSC::JIT::emit_op_ret_object_or_this):
+ (JSC::JIT::emit_op_create_this):
+ (JSC::JIT::emit_op_get_arguments_length):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ (JSC::JIT::emit_op_resolve_global_dynamic):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompileCTINativeCall):
+ (JSC::JIT::emit_op_end):
+ (JSC::JIT::emit_op_create_this):
+ (JSC::JIT::emit_op_get_arguments_length):
+ (JSC::JIT::emit_op_get_argument_by_val):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC::JIT::emit_op_put_scoped_var):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+ (JSC::JIT::emit_op_put_scoped_var):
+ * jit/JITStubs.cpp:
+ (JSC::ctiTrampoline):
+ (JSC::JITThunks::JITThunks):
+ (JSC):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ (JSC):
+ (JITStackFrame):
+ * jit/JSInterfaceJIT.h:
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::SpecializedThunkJIT):
+ (JSC::SpecializedThunkJIT::returnJSValue):
+ (JSC::SpecializedThunkJIT::returnDouble):
+ (JSC::SpecializedThunkJIT::returnInt32):
+ (JSC::SpecializedThunkJIT::returnJSCell):
+ * llint/LLIntData.cpp:
+ (JSC::LLInt::Data::performAssertions):
+ * llint/LLIntOffsetsExtractor.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ (JSC::LLInt::genericCall):
+ * llint/LLIntSlowPaths.h:
+ (LLInt):
+ * llint/LowLevelInterpreter.asm:
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::tearOffForInlineCallFrame):
+ * runtime/CommonSlowPaths.h:
+ (JSC::CommonSlowPaths::arityCheckFor):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::visitChildren):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::globalExec):
+ * runtime/JSGlobalObject.h:
+ (JSC):
+ (JSGlobalObject):
+ * runtime/JSLock.cpp:
+ (JSC):
+ * runtime/JSVariableObject.h:
+ (JSVariableObject):
+ * runtime/MemoryStatistics.cpp:
+ (JSC::globalMemoryStatistics):
+
+2012-10-08 Kiran Muppala <cmuppala@apple.com>
+
+ Throttle DOM timers on hidden pages.
+ https://bugs.webkit.org/show_bug.cgi?id=98474
+
+ Reviewed by Maciej Stachowiak.
+
+ Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-08 Michael Saboff <msaboff@apple.com>
+
+ After r130344, OpaqueJSString() creates an empty string which should be a null string
+ https://bugs.webkit.org/show_bug.cgi?id=98417
+
+ Reviewed by Sam Weinig.
+
+ Changed create() of a null string to return 0. This is the same behavior as before r130344.
+
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::create):
+
+2012-10-07 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>
+
+ Rename first/second to key/value in HashMap iterators
+ https://bugs.webkit.org/show_bug.cgi?id=82784
+
+ Reviewed by Eric Seidel.
+
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::getOwnNonIndexPropertyNames):
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::~OpaqueJSClass):
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ (OpaqueJSClass::contextData):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::EvalCodeCache::visitAggregate):
+ (JSC::CodeBlock::nameForRegister):
+ * bytecode/JumpTable.h:
+ (JSC::StringJumpTable::offsetForValue):
+ (JSC::StringJumpTable::ctiForValue):
+ * bytecode/LazyOperandValueProfile.cpp:
+ (JSC::LazyOperandValueProfileParser::getIfPresent):
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::dump):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::addVar):
+ (JSC::BytecodeGenerator::addGlobalVar):
+ (JSC::BytecodeGenerator::addConstant):
+ (JSC::BytecodeGenerator::addConstantValue):
+ (JSC::BytecodeGenerator::emitLoad):
+ (JSC::BytecodeGenerator::addStringConstant):
+ (JSC::BytecodeGenerator::emitLazyNewFunction):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::PropertyListNode::emitBytecode):
+ * debugger/Debugger.cpp:
+ * dfg/DFGArgumentsSimplificationPhase.cpp:
+ (JSC::DFG::ArgumentsSimplificationPhase::run):
+ (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse):
+ (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse):
+ (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize):
+ (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
+ * dfg/DFGAssemblyHelpers.cpp:
+ (JSC::DFG::AssemblyHelpers::decodedCodeMapFor):
+ * dfg/DFGByteCodeCache.h:
+ (JSC::DFG::ByteCodeCache::~ByteCodeCache):
+ (JSC::DFG::ByteCodeCache::get):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::cellConstant):
+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck):
+ (JSC::DFG::StructureCheckHoistingPhase::noticeClobber):
+ * heap/Heap.cpp:
+ (JSC::Heap::markProtectedObjects):
+ * heap/Heap.h:
+ (JSC::Heap::forEachProtectedCell):
+ * heap/JITStubRoutineSet.cpp:
+ (JSC::JITStubRoutineSet::markSlow):
+ (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines):
+ * heap/SlotVisitor.cpp:
+ (JSC::SlotVisitor::internalAppend):
+ * heap/Weak.h:
+ (JSC::weakRemove):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::ctiStub):
+ * parser/Parser.cpp:
+ (JSC::::parseStrictObjectLiteral):
+ * profiler/Profile.cpp:
+ (JSC::functionNameCountPairComparator):
+ (JSC::Profile::debugPrintDataSampleStyle):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::getOwnNonIndexPropertyNames):
+ (JSC::JSActivation::symbolTablePutWithAttributes):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::setLength):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getOwnPropertySlotByIndex):
+ (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::defineOwnIndexedProperty):
+ (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage):
+ (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
+ (JSC::JSObject::getOwnPropertyDescriptor):
+ * runtime/JSSymbolTableObject.cpp:
+ (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
+ * runtime/JSSymbolTableObject.h:
+ (JSC::symbolTableGet):
+ (JSC::symbolTablePut):
+ (JSC::symbolTablePutWithAttributes):
+ * runtime/RegExpCache.cpp:
+ (JSC::RegExpCache::invalidateCode):
+ * runtime/SparseArrayValueMap.cpp:
+ (JSC::SparseArrayValueMap::putEntry):
+ (JSC::SparseArrayValueMap::putDirect):
+ (JSC::SparseArrayValueMap::visitChildren):
+ * runtime/WeakGCMap.h:
+ (JSC::WeakGCMap::clear):
+ (JSC::WeakGCMap::set):
+ * tools/ProfileTreeNode.h:
+ (JSC::ProfileTreeNode::sampleChild):
+ (JSC::ProfileTreeNode::childCount):
+ (JSC::ProfileTreeNode::dumpInternal):
+ (JSC::ProfileTreeNode::compareEntries):
+
+2012-10-05 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ JSC should have a way to gather and log Heap memory use and pause times
+ https://bugs.webkit.org/show_bug.cgi?id=98431
+
+ Reviewed by Geoffrey Garen.
+
+ In order to improve our infrastructure for benchmark-driven development, we should
+ have a centralized method of gathering and logging various statistics about the state
+ of the JS heap. This would allow us to create and to use other tools to analyze the
+ output of the VM after running various workloads.
+
+ The first two statistics that might be interesting is memory use by JSC and GC pause
+ times. We can control whether this recording happens through the use of the Options
+ class, allowing us to either use environment variables or command line flags.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * heap/Heap.cpp:
+ (JSC::Heap::collect): If we finish a collection and are still over our set GC heap size,
+ we end the program immediately and report an error. Also added recording of pause times.
+ * heap/Heap.h:
+ (Heap):
+ (JSC::Heap::shouldCollect): When we set a specific GC heap size through Options, we
+ ignore all other heuristics on when we should collect and instead only ask if we're
+ greater than the amount specified in the Option value. This allows us to view time/memory
+ tradeoffs more clearly.
+ * heap/HeapStatistics.cpp: Added.
+ (JSC):
+ (JSC::HeapStatistics::initialize):
+ (JSC::HeapStatistics::recordGCPauseTime):
+ (JSC::HeapStatistics::logStatistics):
+ (JSC::HeapStatistics::exitWithFailure):
+ (JSC::HeapStatistics::reportSuccess):
+ (JSC::HeapStatistics::parseMemoryAmount):
+ (StorageStatistics):
+ (JSC::StorageStatistics::StorageStatistics):
+ (JSC::StorageStatistics::operator()):
+ (JSC::StorageStatistics::objectWithOutOfLineStorageCount):
+ (JSC::StorageStatistics::objectCount):
+ (JSC::StorageStatistics::storageSize):
+ (JSC::StorageStatistics::storageCapacity):
+ (JSC::HeapStatistics::showObjectStatistics): Moved the old showHeapStatistics (renamed to showObjectStatistics)
+ to try to start collecting our various memory statistics gathering/reporting mechanisms scattered throughout the
+ codebase into one place.
+ * heap/HeapStatistics.h: Added.
+ (JSC):
+ (HeapStatistics):
+ * jsc.cpp:
+ (main):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce): We need to initialize our data structures for recording
+ statistics if necessary.
+ * runtime/Options.cpp: Add new Options for the various types of statistics we'll be gathering.
+ (JSC::parse):
+ (JSC):
+ (JSC::Options::initialize): Initialize the various new options using environment variables.
+ (JSC::Options::dumpOption):
+ * runtime/Options.h:
+ (JSC):
+
+2012-10-04 Rik Cabanier <cabanier@adobe.com>
+
+ Turn Compositing on by default in WebKit build
+ https://bugs.webkit.org/show_bug.cgi?id=98315
+
+ Reviewed by Simon Fraser.
+
+ enable -webkit-blend-mode on trunk.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-10-04 Michael Saboff <msaboff@apple.com>
+
+ Crash in Safari at com.apple.JavaScriptCore: WTF::StringImpl::is8Bit const + 12
+ https://bugs.webkit.org/show_bug.cgi?id=98433
+
+ Reviewed by Jessie Berlin.
+
+ The problem is due to a String with a null StringImpl (i.e. a null string).
+ Added a length check before the is8Bit() check since length() checks for a null StringImpl. Changed the
+ characters16() call to characters() since it can handle a null StringImpl as well.
+
+ * API/JSValueRef.cpp:
+ (JSValueMakeFromJSONString):
+
+2012-10-04 Benjamin Poulain <bpoulain@apple.com>
+
+ Use copyLCharsFromUCharSource() for IdentifierLCharFromUCharTranslator translation
+ https://bugs.webkit.org/show_bug.cgi?id=98335
+
+ Reviewed by Michael Saboff.
+
+ Michael Saboff added an optimized version of UChar->LChar conversion in r125846.
+ Use this function in JSC::Identifier.
+
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierLCharFromUCharTranslator::translate):
+
+2012-10-04 Michael Saboff <msaboff@apple.com>
+
+ After r130344, OpaqueJSString() creates a empty string which should be a null string
+ https://bugs.webkit.org/show_bug.cgi?id=98417
+
+ Reviewed by Alexey Proskuryakov.
+
+ Removed the setting of enclosed string to an empty string from default constructor.
+ Before changeset r130344, the semantic was the default constructor produced a null
+ string.
+
+ * API/OpaqueJSString.h:
+ (OpaqueJSString::OpaqueJSString):
+
+2012-10-04 Csaba Osztrogonác <ossy@webkit.org>
+
+ [Qt] Add missing LLInt dependencies to the build system
+ https://bugs.webkit.org/show_bug.cgi?id=98394
+
+ Reviewed by Geoffrey Garen.
+
+ * DerivedSources.pri:
+ * LLIntOffsetsExtractor.pro:
+
+2012-10-03 Geoffrey Garen <ggaren@apple.com>
+
+ Next step toward fixing Windows: add new symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-10-03 Geoffrey Garen <ggaren@apple.com>
+
+ First step toward fixing Windows: remove old symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-10-03 Geoffrey Garen <ggaren@apple.com>
+
+ Removed the assumption that "final" objects have a fixed number of inline slots
+ https://bugs.webkit.org/show_bug.cgi?id=98332
+
+ Reviewed by Filip Pizlo.
+
+ This is a step toward object size inference.
+
+ I replaced the inline storage capacity constant with a data member per
+ structure, set the the maximum supported value for the constant to 100,
+ then fixed what broke. (Note that even though this patch increases the
+ theoretical maximum inline capacity, it doesn't change any actual inline
+ capacity.)
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetDirectOffset): These functions just get a rename:
+ the constant they need is the first out of line offset along the offset
+ number line, which is not necessarily the same thing (and is, in this
+ patch, never the same thing) as the inline capacity of any given object.
+
+ (JSC::JIT::emit_op_get_by_pname):
+ * jit/JITPropertyAccess32_64.cpp: This function changes functionality,
+ since it needs to convert from the abstract offset number line to an
+ actual offset in memory, and it can't assume that inline and out-of-line
+ offsets are contiguous on the number line.
+
+ (JSC::JIT::compileGetDirectOffset): Updated for rename.
+
+ (JSC::JIT::emit_op_get_by_pname): Same as emit_op_get_by_pname above.
+
+ * llint/LowLevelInterpreter.asm: Updated to mirror changes in PropertyOffset.h,
+ since we duplicate values from there.
+
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm: Just like the JIT, most things are just
+ renames, and get_by_pname changes to do more math. I also standardized
+ offset calculations to use a hard-coded "-2", to match the JIT. This
+ isn't really better, but it makes global search and replace easier,
+ should we choose to refactor this code not to hard-code constants.
+
+ I also renamed loadPropertyAtVariableOffsetKnownNotFinal to
+ loadPropertyAtVariableOffsetKnownNotInline in order to sever the assumption
+ that inline capacity is tied to object type, and I changed the 64bit LLInt
+ to use this -- not using this previously seems to have been an oversight.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::visitChildren):
+ (JSC::JSFinalObject::visitChildren):
+ * runtime/JSObject.h:
+ (JSC::JSObject::offsetForLocation):
+ (JSNonFinalObject):
+ (JSC::JSFinalObject::createStructure):
+ (JSFinalObject):
+ (JSC::JSFinalObject::finishCreation): Updated for above changes.
+
+ * runtime/JSPropertyNameIterator.h:
+ (JSPropertyNameIterator):
+ (JSC::JSPropertyNameIterator::finishCreation): Store the inline capacity
+ of our object, since it's not a constant.
+
+ (JSC::JSPropertyNameIterator::getOffset): Removed. This function was
+ wrong. Luckily, it was also unused, since the C++ interpreter is gone.
+
+ * runtime/PropertyMapHashTable.h:
+ (PropertyTable): Use a helper function instead of hard-coding assumptions
+ about object types.
+
+ (JSC::PropertyTable::nextOffset):
+ * runtime/PropertyOffset.h:
+ (JSC):
+ (JSC::checkOffset):
+ (JSC::validateOffset):
+ (JSC::isInlineOffset):
+ (JSC::numberOfSlotsForLastOffset):
+ (JSC::propertyOffsetFor): Refactored these functions to take inline capacity
+ as an argument, since it's not fixed at compile time anymore.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::Structure::putSpecificValue):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::outOfLineCapacity):
+ (JSC::Structure::hasInlineStorage):
+ (JSC::Structure::inlineCapacity):
+ (JSC::Structure::inlineSize):
+ (JSC::Structure::firstValidOffset):
+ (JSC::Structure::lastValidOffset):
+ (JSC::Structure::create): Removed some hard-coded assumptions about inline
+ capacity and object type, and replaced with more liberal use of helper functions.
+
+2012-10-03 Michael Saboff <msaboff@apple.com>
+
+ OpaqueJSString doesn't optimally handle 8 bit strings
+ https://bugs.webkit.org/show_bug.cgi?id=98300
+
+ Reviewed by Geoffrey Garen.
+
+ Change OpaqueJSString to store and manage a String instead of a UChar buffer.
+ The member string is a copy of any string used during creation.
+
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::create):
+ (OpaqueJSString::identifier):
+ * API/OpaqueJSString.h:
+ (OpaqueJSString::characters):
+ (OpaqueJSString::length):
+ (OpaqueJSString::string):
+ (OpaqueJSString::OpaqueJSString):
+ (OpaqueJSString):
+
+2012-10-03 Filip Pizlo <fpizlo@apple.com>
+
+ Array.splice should be fast when it is used to remove elements other than the very first
+ https://bugs.webkit.org/show_bug.cgi?id=98236
+
+ Reviewed by Michael Saboff.
+
+ Applied the same technique that was used to optimize the unshift case of splice in
+ http://trac.webkit.org/changeset/129676. This is a >20x speed-up on programs that
+ use splice for element removal.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::shift):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::shiftCount):
+ * runtime/JSArray.h:
+ (JSArray):
+
+2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Delayed structure sweep can leak structures without bound
+ https://bugs.webkit.org/show_bug.cgi?id=96546
+
+ Reviewed by Geoffrey Garen.
+
+ This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only
+ allocators. We now have separate allocators for our three types of objects: those objects with no destructors,
+ those objects with destructors and with immortal structures, and those objects with destructors that don't have
+ immortal structures. All of the objects of the third type (destructors without immortal structures) now
+ inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores
+ the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction.
+
+ * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor.
+ (JSC):
+ (JSC::JSCallbackConstructor::JSCallbackConstructor):
+ * API/JSCallbackConstructor.h:
+ (JSCallbackConstructor):
+ * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for
+ JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer.
+ (JSC):
+ (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add
+ the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides
+ to subclass this. We use this same technique for many other subclasses of JSGlobalObject.
+ (JSC::::createStructure):
+ * API/JSCallbackObject.h:
+ (JSCallbackObject):
+ (JSC):
+ * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead.
+ (OpaqueJSClass::prototype):
+ * API/JSObjectRef.cpp: Ditto.
+ (JSObjectMake):
+ (JSObjectGetPrivate):
+ (JSObjectSetPrivate):
+ (JSObjectGetPrivateProperty):
+ (JSObjectSetPrivateProperty):
+ (JSObjectDeletePrivateProperty):
+ * API/JSValueRef.cpp: Ditto.
+ (JSValueIsObjectOfClass):
+ * API/JSWeakObjectMapRefPrivate.cpp: Ditto.
+ * JSCTypedArrayStubs.h:
+ (JSC):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG.
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
+ * heap/Heap.cpp:
+ (JSC):
+ * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function
+ since it's always safe to sweep Structures now.
+ (JSC::Heap::allocatorForObjectWithNormalDestructor):
+ (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor):
+ (Heap):
+ (JSC::Heap::allocateWithNormalDestructor):
+ (JSC):
+ (JSC::Heap::allocateWithImmortalStructureDestructor):
+ * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the
+ IncrementalSweeper since it's always safe to sweep Structures now.
+ (JSC::IncrementalSweeper::IncrementalSweeper):
+ (JSC::IncrementalSweeper::sweepNextBlock):
+ (JSC::IncrementalSweeper::startSweeping):
+ (JSC::IncrementalSweeper::willFinishSweeping):
+ (JSC):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add
+ tracking of the specific destructor type of allocator.
+ (JSC::MarkedAllocator::tryAllocateHelper):
+ (JSC::MarkedAllocator::allocateBlock):
+ * heap/MarkedAllocator.h:
+ (JSC::MarkedAllocator::destructorType):
+ (MarkedAllocator):
+ (JSC::MarkedAllocator::MarkedAllocator):
+ (JSC::MarkedAllocator::init):
+ * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping.
+ We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls.
+ (JSC::MarkedBlock::create):
+ (JSC::MarkedBlock::MarkedBlock):
+ (JSC):
+ (JSC::MarkedBlock::specializedSweep):
+ (JSC::MarkedBlock::sweep):
+ (JSC::MarkedBlock::sweepHelper):
+ * heap/MarkedBlock.h:
+ (JSC):
+ (JSC::MarkedBlock::allocator):
+ (JSC::MarkedBlock::destructorType):
+ * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace.
+ (JSC::MarkedSpace::MarkedSpace):
+ (JSC::MarkedSpace::resetAllocators):
+ (JSC::MarkedSpace::canonicalizeCellLivenessData):
+ (JSC::MarkedSpace::isPagedOut):
+ (JSC::MarkedSpace::freeBlock):
+ * heap/MarkedSpace.h:
+ (MarkedSpace):
+ (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor):
+ (JSC::MarkedSpace::normalDestructorAllocatorFor):
+ (JSC::MarkedSpace::allocateWithImmortalStructureDestructor):
+ (JSC::MarkedSpace::allocateWithNormalDestructor):
+ (JSC::MarkedSpace::forEachBlock):
+ * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function.
+ * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT.
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateBasicJSObject):
+ (JSC::JIT::emitAllocateJSFinalObject):
+ (JSC::JIT::emitAllocateJSArray):
+ * jsc.cpp:
+ (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from
+ JSDestructibleObject.
+ * runtime/Arguments.cpp: Inherit from JSDestructibleObject.
+ (JSC):
+ * runtime/Arguments.h:
+ (Arguments):
+ (JSC::Arguments::Arguments):
+ * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor.
+ (JSC):
+ * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures.
+ (JSC):
+ * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject.
+ (JSC):
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/InternalFunction.h:
+ (InternalFunction):
+ * runtime/JSCell.h: Added two static bools, needsDestruction and hasImmortalStructure, that classes can override
+ to indicate at compile time which part of the heap they should be allocated in.
+ (JSC::allocateCell): Use the appropriate allocator depending on the destructor type.
+ * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be
+ accessed safely when the object is being destroyed.
+ (JSC):
+ (JSDestructibleObject):
+ (JSC::JSDestructibleObject::classInfo):
+ (JSC::JSDestructibleObject::JSDestructibleObject):
+ (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe.
+ * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all
+ of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well.
+ (JSC::JSGlobalObject::reset):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one
+ for the m_rareData field when it's created.
+ (JSC::JSGlobalObject::create):
+ (JSC):
+ * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject.
+ (JSGlobalThis):
+ (JSC::JSGlobalThis::JSGlobalThis):
+ * runtime/JSPropertyNameIterator.h: Has an immortal Structure.
+ (JSC):
+ * runtime/JSScope.cpp:
+ (JSC):
+ * runtime/JSString.h: Has an immortal Structure.
+ (JSC):
+ * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject.
+ (JSWrapperObject):
+ (JSC::JSWrapperObject::JSWrapperObject):
+ * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff.
+ (JSC):
+ * runtime/NameInstance.h: Inherit from JSDestructibleObject.
+ (NameInstance):
+ * runtime/RegExp.h: Has immortal Structure.
+ (JSC):
+ * runtime/RegExpObject.cpp: Inheritance cleanup.
+ (JSC):
+ * runtime/SparseArrayValueMap.h: Has immortal Structure.
+ (JSC):
+ * runtime/Structure.h: Has immortal Structure.
+ (JSC):
+ * runtime/StructureChain.h: Ditto.
+ (JSC):
+ * runtime/SymbolTable.h: Ditto.
+ (SharedSymbolTable):
+ (JSC):
+
+== Rolled over to ChangeLog-2012-10-02 ==
diff --git a/Source/JavaScriptCore/Configurations/Base.xcconfig b/Source/JavaScriptCore/Configurations/Base.xcconfig
index 2de8597d7..19a93909b 100644
--- a/Source/JavaScriptCore/Configurations/Base.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Base.xcconfig
@@ -48,6 +48,13 @@ GCC_STRICT_ALIASING = YES;
GCC_THREADSAFE_STATICS = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+// FIXME: <http://webkit.org/b/109834> JavaSciptCore should build with -Wshorten-64-to-32
+GCC_WARN_64_TO_32_BIT_CONVERSION = $(GCC_WARN_64_TO_32_BIT_CONVERSION_$(CURRENT_ARCH));
+GCC_WARN_64_TO_32_BIT_CONVERSION_ = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7 = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_armv7s = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_i386 = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION_x86_64 = NO;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
@@ -59,16 +66,7 @@ VALID_ARCHS = $(VALID_ARCHS_$(PLATFORM_NAME));
VALID_ARCHS_iphoneos = $(ARCHS_STANDARD_32_BIT);
VALID_ARCHS_iphonesimulator = $(ARCHS_STANDARD_32_BIT);
VALID_ARCHS_macosx = i386 ppc x86_64 ppc64 $(ARCHS_UNIVERSAL_IPHONE_OS);
-WARNING_CFLAGS_BASE = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare;
-WARNING_CFLAGS = $(WARNING_CFLAGS_$(PLATFORM_NAME));
-WARNING_CFLAGS_iphoneos = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
-WARNING_CFLAGS_iphonesimulator = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
-WARNING_CFLAGS_macosx = $(WARNING_CFLAGS_macosx_$(CURRENT_ARCH));
-WARNING_CFLAGS_macosx_ = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
-WARNING_CFLAGS_macosx_i386 = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
-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_x86_64 = $(WARNING_CFLAGS_BASE);
+WARNING_CFLAGS = -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare;
HEADER_SEARCH_PATHS = . icu "${BUILT_PRODUCTS_DIR}/usr/local/include" $(HEADER_SEARCH_PATHS);
TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index 00678accd..4903d2bf8 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -33,8 +33,14 @@
ENABLE_3D_RENDERING = ENABLE_3D_RENDERING;
ENABLE_ACCELERATED_2D_CANVAS = ;
-ENABLE_ANIMATION_API = ;
ENABLE_BLOB = ENABLE_BLOB;
+ENABLE_CACHE_PARTITIONING = $(ENABLE_CACHE_PARTITIONING_$(PLATFORM_NAME));
+ENABLE_CACHE_PARTITIONING_macosx = $(ENABLE_CACHE_PARTITIONING_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+ENABLE_CACHE_PARTITIONING_macosx_1070 = ;
+ENABLE_CACHE_PARTITIONING_macosx_1080 = ENABLE_CACHE_PARTITIONING;
+ENABLE_CACHE_PARTITIONING_macosx_1090 = ENABLE_CACHE_PARTITIONING;
+ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
+ENABLE_CANVAS_PROXY = ;
ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
ENABLE_CSP_NEXT = ;
ENABLE_CSS_BOX_DECORATION_BREAK = ENABLE_CSS_BOX_DECORATION_BREAK;
@@ -46,34 +52,47 @@ ENABLE_CSS_IMAGE_ORIENTATION = ;
ENABLE_CSS_IMAGE_RESOLUTION = ;
ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS;
ENABLE_CSS_SHADERS = ENABLE_CSS_SHADERS;
+ENABLE_CSS_SHAPES = ENABLE_CSS_SHAPES;
ENABLE_CSS_STICKY_POSITION = ENABLE_CSS_STICKY_POSITION;
+ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED = ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED;
ENABLE_CSS_VARIABLES = ;
-ENABLE_CSS3_BACKGROUND = ;
ENABLE_CSS3_CONDITIONAL_RULES = ;
ENABLE_CSS3_TEXT = ;
+ENABLE_CSS3_TEXT_LINE_BREAK = ;
+ENABLE_CURSOR_VISIBILITY = ENABLE_CURSOR_VISIBILITY;
ENABLE_CUSTOM_SCHEME_HANDLER = ;
ENABLE_DASHBOARD_SUPPORT = $(ENABLE_DASHBOARD_SUPPORT_$(PLATFORM_NAME));
ENABLE_DASHBOARD_SUPPORT_macosx = ENABLE_DASHBOARD_SUPPORT;
ENABLE_DATALIST_ELEMENT = ;
ENABLE_DATA_TRANSFER_ITEMS = ;
ENABLE_DETAILS_ELEMENT = ENABLE_DETAILS_ELEMENT;
-ENABLE_DEVICE_ORIENTATION = ;
+ENABLE_DEVICE_ORIENTATION = $(ENABLE_DEVICE_ORIENTATION_$(PLATFORM_NAME));
+ENABLE_DEVICE_ORIENTATION_iphoneos = ENABLE_DEVICE_ORIENTATION;
+ENABLE_DEVICE_ORIENTATION_iphonesimulator = $(ENABLE_DEVICE_ORIENTATION_iphoneos);
ENABLE_DIALOG_ELEMENT = ;
ENABLE_DIRECTORY_UPLOAD = ;
+ENABLE_DOM4_EVENTS_CONSTRUCTOR = ENABLE_DOM4_EVENTS_CONSTRUCTOR;
ENABLE_DRAGGABLE_REGION = ;
ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(PLATFORM_NAME));
ENABLE_ENCRYPTED_MEDIA_macosx = $(ENABLE_ENCRYPTED_MEDIA_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ENABLE_ENCRYPTED_MEDIA_macosx_1070 = ;
ENABLE_ENCRYPTED_MEDIA_macosx_1080 = ;
ENABLE_ENCRYPTED_MEDIA_macosx_1090 = ENABLE_ENCRYPTED_MEDIA;
+ENABLE_ENCRYPTED_MEDIA_V2 = $(ENABLE_ENCRYPTED_MEDIA_V2_$(PLATFORM_NAME));
+ENABLE_ENCRYPTED_MEDIA_V2_macosx = $(ENABLE_ENCRYPTED_MEDIA_V2_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+ENABLE_ENCRYPTED_MEDIA_V2_macosx_1070 = ;
+ENABLE_ENCRYPTED_MEDIA_V2_macosx_1080 = ;
+ENABLE_ENCRYPTED_MEDIA_V2_macosx_1090 = ENABLE_ENCRYPTED_MEDIA_V2;
ENABLE_FILE_SYSTEM = ;
ENABLE_FILTERS = ENABLE_FILTERS;
-ENABLE_FULLSCREEN_API = ENABLE_FULLSCREEN_API;
+ENABLE_FONT_LOAD_EVENTS = ;
+ENABLE_FULLSCREEN_API = $(ENABLE_FULLSCREEN_API_$(PLATFORM_NAME));
+ENABLE_FULLSCREEN_API_macosx = ENABLE_FULLSCREEN_API;
ENABLE_GAMEPAD = ;
ENABLE_GEOLOCATION = ENABLE_GEOLOCATION;
ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING = $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING_$(PLATFORM_NAME));
ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING_macosx = ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING;
-ENABLE_HIGH_DPI_CANVAS = ENABLE_HIGH_DPI_CANVAS;
+ENABLE_HIGH_DPI_CANVAS = $(ENABLE_HIGH_DPI_CANVAS_$(PLATFORM_NAME));
ENABLE_ICONDATABASE = $(ENABLE_ICONDATABASE_$(PLATFORM_NAME));
ENABLE_ICONDATABASE_macosx = ENABLE_ICONDATABASE;
ENABLE_IFRAME_SEAMLESS = ENABLE_IFRAME_SEAMLESS;
@@ -83,9 +102,9 @@ ENABLE_INPUT_TYPE_COLOR = ;
ENABLE_INPUT_TYPE_DATE = $(ENABLE_INPUT_TYPE_DATE_$(PLATFORM_NAME));
ENABLE_INPUT_TYPE_DATE_iphoneos = ENABLE_INPUT_TYPE_DATE;
ENABLE_INPUT_TYPE_DATE_iphonesimulator = $(ENABLE_INPUT_TYPE_DATE_iphoneos);
-ENABLE_INPUT_TYPE_DATETIME = $(ENABLE_INPUT_TYPE_DATETIME_$(PLATFORM_NAME));
-ENABLE_INPUT_TYPE_DATETIME_iphoneos = ENABLE_INPUT_TYPE_DATETIME;
-ENABLE_INPUT_TYPE_DATETIME_iphonesimulator = $(ENABLE_INPUT_TYPE_DATETIME_iphoneos);
+ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE = $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE_$(PLATFORM_NAME));
+ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE_iphoneos = ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE;
+ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE_iphonesimulator = $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE_iphoneos);
ENABLE_INPUT_TYPE_DATETIMELOCAL = $(ENABLE_INPUT_TYPE_DATETIMELOCAL_$(PLATFORM_NAME));
ENABLE_INPUT_TYPE_DATETIMELOCAL_iphoneos = ENABLE_INPUT_TYPE_DATETIMELOCAL;
ENABLE_INPUT_TYPE_DATETIMELOCAL_iphonesimulator = $(ENABLE_INPUT_TYPE_DATETIMELOCAL_iphoneos);
@@ -108,49 +127,55 @@ ENABLE_LEGACY_NOTIFICATIONS_macosx_1090 = ENABLE_LEGACY_NOTIFICATIONS;
ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
ENABLE_LINK_PREFETCH = ;
-ENABLE_LINK_PRERENDER = ;
ENABLE_MATHML = ENABLE_MATHML;
ENABLE_MEDIA_SOURCE = ;
ENABLE_MEDIA_STATISTICS = ;
ENABLE_METER_ELEMENT = ENABLE_METER_ELEMENT;
ENABLE_MHTML = ;
ENABLE_MICRODATA = ;
-ENABLE_MUTATION_OBSERVERS = ENABLE_MUTATION_OBSERVERS;
+ENABLE_MOUSE_CURSOR_SCALE = ENABLE_MOUSE_CURSOR_SCALE;
ENABLE_NAVIGATOR_CONTENT_UTILS = ;
+ENABLE_NOSNIFF = ;
ENABLE_NOTIFICATIONS = $(ENABLE_NOTIFICATIONS_$(PLATFORM_NAME));
ENABLE_NOTIFICATIONS_macosx = $(ENABLE_NOTIFICATIONS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ENABLE_NOTIFICATIONS_macosx_1070 = ;
ENABLE_NOTIFICATIONS_macosx_1080 = ENABLE_NOTIFICATIONS;
ENABLE_NOTIFICATIONS_macosx_1090 = ENABLE_NOTIFICATIONS;
-ENABLE_PAGE_VISIBILITY_API = ;
+ENABLE_PAGE_VISIBILITY_API = ENABLE_PAGE_VISIBILITY_API;
ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(PLATFORM_NAME));
-ENABLE_PDFKIT_PLUGIN_macosx = $(ENABLE_PDFKIT_PLUGIN_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
-ENABLE_PDFKIT_PLUGIN_macosx_1070 = ;
-ENABLE_PDFKIT_PLUGIN_macosx_1080 = ;
-ENABLE_PDFKIT_PLUGIN_macosx_1090 = ENABLE_PDFKIT_PLUGIN;
+ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
+ENABLE_PLUGIN_PROXY_FOR_VIDEO = $(ENABLE_PLUGIN_PROXY_FOR_VIDEO_$(PLATFORM_NAME));
+ENABLE_PLUGIN_PROXY_FOR_VIDEO_iphoneos = ENABLE_PLUGIN_PROXY_FOR_VIDEO;
+ENABLE_PLUGIN_PROXY_FOR_VIDEO_iphonesimulator = $(ENABLE_PLUGIN_PROXY_FOR_VIDEO_iphoneos);
ENABLE_PROGRESS_ELEMENT = ENABLE_PROGRESS_ELEMENT;
ENABLE_PROXIMITY_EVENTS = ;
+ENABLE_PUBLIC_SUFFIX_LIST = $(ENABLE_PUBLIC_SUFFIX_LIST_$(PLATFORM_NAME));
+ENABLE_PUBLIC_SUFFIX_LIST_macosx = $(ENABLE_PUBLIC_SUFFIX_LIST_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+ENABLE_PUBLIC_SUFFIX_LIST_macosx_1070 = ;
+ENABLE_PUBLIC_SUFFIX_LIST_macosx_1080 = ENABLE_PUBLIC_SUFFIX_LIST;
+ENABLE_PUBLIC_SUFFIX_LIST_macosx_1090 = ENABLE_PUBLIC_SUFFIX_LIST;
ENABLE_QUOTA = ;
ENABLE_REQUEST_ANIMATION_FRAME = ENABLE_REQUEST_ANIMATION_FRAME;
ENABLE_RESOLUTION_MEDIA_QUERY = ;
ENABLE_SCRIPTED_SPEECH = ;
ENABLE_SHADOW_DOM = ;
ENABLE_SHARED_WORKERS = ENABLE_SHARED_WORKERS;
+ENABLE_SPEECH_SYNTHESIS = $(ENABLE_SPEECH_SYNTHESIS_$(PLATFORM_NAME));
+ENABLE_SPEECH_SYNTHESIS_macosx = ENABLE_SPEECH_SYNTHESIS;
ENABLE_SQL_DATABASE = ENABLE_SQL_DATABASE;
ENABLE_STYLE_SCOPED = ;
-ENABLE_SUBPIXEL_LAYOUT = ENABLE_SUBPIXEL_LAYOUT;
+ENABLE_SUBPIXEL_LAYOUT = ;
ENABLE_SVG = ENABLE_SVG;
-ENABLE_SVG_DOM_OBJC_BINDINGS = $(ENABLE_SVG_DOM_OBJC_BINDINGS_$(PLATFORM_NAME));
-ENABLE_SVG_DOM_OBJC_BINDINGS_macosx = ENABLE_SVG_DOM_OBJC_BINDINGS;
ENABLE_SVG_FONTS = ENABLE_SVG_FONTS;
ENABLE_TEMPLATE_ELEMENT = ;
ENABLE_TEXT_AUTOSIZING = ;
-ENABLE_TEXT_NOTIFICATIONS_ONLY = ENABLE_TEXT_NOTIFICATIONS_ONLY;
+ENABLE_THREADED_HTML_PARSER = ;
ENABLE_TOUCH_ICON_LOADING = ;
ENABLE_USERSELECT_ALL = ENABLE_USERSELECT_ALL;
ENABLE_VIDEO = ENABLE_VIDEO;
ENABLE_VIDEO_TRACK = $(ENABLE_VIDEO_TRACK_$(PLATFORM_NAME));
ENABLE_VIDEO_TRACK_macosx = ENABLE_VIDEO_TRACK;
+ENABLE_VIEW_MODE_CSS_MEDIA = ;
ENABLE_WEBGL = ENABLE_WEBGL;
ENABLE_WEB_AUDIO = ENABLE_WEB_AUDIO;
ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS;
@@ -159,5 +184,4 @@ ENABLE_WORKERS = ENABLE_WORKERS;
ENABLE_XHR_TIMEOUT = ENABLE_XHR_TIMEOUT;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_BACKGROUND) $(ENABLE_CSS3_TEXT) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(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_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT);
-
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
diff --git a/Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig b/Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig
index bd733d4a2..a91c75730 100644
--- a/Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig
+++ b/Source/JavaScriptCore/Configurations/ToolExecutable.xcconfig
@@ -31,3 +31,9 @@ SKIP_INSTALL = $(SKIP_INSTALL_$(FORCE_TOOL_INSTALL));
SKIP_INSTALL_ = YES;
SKIP_INSTALL_NO = YES;
SKIP_INSTALL_YES = NO;
+
+GCC_ENABLE_OBJC_GC = NO;
+CLANG_ENABLE_OBJC_ARC = $(CLANG_ENABLE_OBJC_ARC_$(CURRENT_ARCH));
+CLANG_ENABLE_OBJC_ARC_x86_64 = YES;
+CLANG_ENABLE_OBJC_ARC_armv7 = YES;
+CLANG_ENABLE_OBJC_ARC_armv7s = YES;
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index 943e88ecf..e2531abb4 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 = 537;
-MINOR_VERSION = 21;
+MAJOR_VERSION = 538;
+MINOR_VERSION = 1;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/DerivedSources.make b/Source/JavaScriptCore/DerivedSources.make
index b0b637e88..517063d78 100644
--- a/Source/JavaScriptCore/DerivedSources.make
+++ b/Source/JavaScriptCore/DerivedSources.make
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
+# Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -41,7 +41,6 @@ all : \
DateConstructor.lut.h \
DatePrototype.lut.h \
ErrorPrototype.lut.h \
- HeaderDetection.h \
JSONObject.lut.h \
JSGlobalObject.lut.h \
KeywordLookup.h \
@@ -51,13 +50,11 @@ all : \
NumberConstructor.lut.h \
NumberPrototype.lut.h \
ObjectConstructor.lut.h \
- ObjectPrototype.lut.h \
RegExpConstructor.lut.h \
RegExpPrototype.lut.h \
RegExpJitTables.h \
RegExpObject.lut.h \
StringConstructor.lut.h \
- StringPrototype.lut.h \
docs/bytecode.html \
udis86_itab.h \
#
@@ -84,19 +81,3 @@ KeywordLookup.h: KeywordLookupGenerator.py Keywords.table
udis86_itab.h: $(JavaScriptCore)/disassembler/udis86/itab.py $(JavaScriptCore)/disassembler/udis86/optable.xml
(PYTHONPATH=$(JavaScriptCore)/disassembler/udis86 python $(JavaScriptCore)/disassembler/udis86/itab.py $(JavaScriptCore)/disassembler/udis86/optable.xml || exit 1)
-
-# header detection
-
-ifeq ($(OS),MACOS)
-
-HeaderDetection.h : DerivedSources.make /System/Library/CoreServices/SystemVersion.plist
- rm -f $@
- echo "/* This is a generated file. Do not edit. */" > $@
- if [ -f $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders/pthread_machdep.h ]; then echo "#define HAVE_PTHREAD_MACHDEP_H 1" >> $@; else echo >> $@; fi
-
-else
-
-HeaderDetection.h :
- echo > $@
-
-endif
diff --git a/Source/JavaScriptCore/DerivedSources.pri b/Source/JavaScriptCore/DerivedSources.pri
index 8bbc29d2a..c27c15f3e 100644
--- a/Source/JavaScriptCore/DerivedSources.pri
+++ b/Source/JavaScriptCore/DerivedSources.pri
@@ -20,12 +20,10 @@ LUT_FILES += \
runtime/NumberConstructor.cpp \
runtime/NumberPrototype.cpp \
runtime/ObjectConstructor.cpp \
- runtime/ObjectPrototype.cpp \
runtime/RegExpConstructor.cpp \
runtime/RegExpObject.cpp \
runtime/RegExpPrototype.cpp \
runtime/StringConstructor.cpp \
- runtime/StringPrototype.cpp \
KEYWORDLUT_FILES += \
parser/Keywords.table
diff --git a/Source/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSCTestRunnerUtils.h b/Source/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSCTestRunnerUtils.h
new file mode 100644
index 000000000..93a199df4
--- /dev/null
+++ b/Source/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSCTestRunnerUtils.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/API/JSCTestRunnerUtils.h>
diff --git a/Source/JavaScriptCore/GNUmakefile.am b/Source/JavaScriptCore/GNUmakefile.am
index 96a23f288..1c68b7621 100644
--- a/Source/JavaScriptCore/GNUmakefile.am
+++ b/Source/JavaScriptCore/GNUmakefile.am
@@ -200,3 +200,13 @@ CLEANFILES += \
DISTCLEANFILES += \
$(top_builddir)/Source/JavaScriptCore/javascriptcoregtk-@WEBKITGTK_API_VERSION@.pc
+
+if ENABLE_INTROSPECTION
+# The GIR file is generated via autoconf, as we don't need to run the scanner against non-GObject libraries.
+JavaScriptCore-@WEBKITGTK_API_VERSION@.typelib: JavaScriptCore-@WEBKITGTK_API_VERSION@.gir $(G_IR_COMPILER)
+ $(AM_V_GEN)$(G_IR_COMPILER) --includedir $(WebKit) --includedir $(top_builddir) $< -o $@
+
+gir_DATA += JavaScriptCore-@WEBKITGTK_API_VERSION@.gir
+typelibs_DATA += JavaScriptCore-@WEBKITGTK_API_VERSION@.typelib
+CLEANFILES += JavaScriptCore-@WEBKITGTK_API_VERSION@.gir JavaScriptCore-@WEBKITGTK_API_VERSION@.typelib
+endif
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index 701d80fae..b1f38ccc5 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -24,18 +24,17 @@ javascriptcore_built_nosources += \
DerivedSources/JavaScriptCore/NumberConstructor.lut.h \
DerivedSources/JavaScriptCore/NumberPrototype.lut.h \
DerivedSources/JavaScriptCore/ObjectConstructor.lut.h \
- DerivedSources/JavaScriptCore/ObjectPrototype.lut.h \
DerivedSources/JavaScriptCore/RegExpConstructor.lut.h \
DerivedSources/JavaScriptCore/RegExpObject.lut.h \
DerivedSources/JavaScriptCore/RegExpPrototype.lut.h \
DerivedSources/JavaScriptCore/StringConstructor.lut.h \
- DerivedSources/JavaScriptCore/StringPrototype.lut.h \
DerivedSources/JavaScriptCore/LLIntDesiredOffsets.h \
DerivedSources/JavaScriptCore/LLIntAssembly.h
javascriptcore_sources += \
Source/JavaScriptCore/API/APICast.h \
Source/JavaScriptCore/API/APIShims.h \
+ Source/JavaScriptCore/API/JSAPIWrapperObject.h \
Source/JavaScriptCore/API/JSBase.cpp \
Source/JavaScriptCore/API/JSBasePrivate.h \
Source/JavaScriptCore/API/JSCallbackConstructor.cpp \
@@ -52,9 +51,13 @@ javascriptcore_sources += \
Source/JavaScriptCore/API/JSObjectRef.cpp \
Source/JavaScriptCore/API/JSObjectRefPrivate.h \
Source/JavaScriptCore/API/JSRetainPtr.h \
+ Source/JavaScriptCore/API/JSScriptRef.cpp \
+ Source/JavaScriptCore/API/JSScriptRefPrivate.h \
Source/JavaScriptCore/API/JSStringRef.cpp \
+ Source/JavaScriptCore/API/JSStringRefPrivate.h \
Source/JavaScriptCore/API/JSValueRef.cpp \
Source/JavaScriptCore/API/JSWeakObjectMapRefInternal.h \
+ Source/JavaScriptCore/API/ObjCCallbackFunction.h \
Source/JavaScriptCore/API/OpaqueJSString.cpp \
Source/JavaScriptCore/API/OpaqueJSString.h \
Source/JavaScriptCore/assembler/AbstractMacroAssembler.h \
@@ -74,7 +77,6 @@ javascriptcore_sources += \
Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h \
Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h \
Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h \
- Source/JavaScriptCore/assembler/MacroAssemblerSH4.cpp \
Source/JavaScriptCore/assembler/MacroAssemblerSH4.h \
Source/JavaScriptCore/assembler/MacroAssemblerX86.h \
Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h \
@@ -103,13 +105,14 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/CodeBlockWithJITType.h \
Source/JavaScriptCore/bytecode/CodeOrigin.cpp \
Source/JavaScriptCore/bytecode/CodeOrigin.h \
- Source/JavaScriptCore/bytecode/Comment.h \
Source/JavaScriptCore/bytecode/DataFormat.h \
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/ExitKind.cpp \
+ Source/JavaScriptCore/bytecode/ExitKind.h \
Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h \
Source/JavaScriptCore/bytecode/GetByIdStatus.cpp \
Source/JavaScriptCore/bytecode/GetByIdStatus.h \
@@ -123,16 +126,22 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecode/LineInfo.h \
Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp \
Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h \
+ Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h \
Source/JavaScriptCore/bytecode/Opcode.cpp \
Source/JavaScriptCore/bytecode/Opcode.h \
Source/JavaScriptCore/bytecode/Operands.h \
+ Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h \
Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp \
Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h \
+ Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp \
+ Source/JavaScriptCore/bytecode/PreciseJumpTargets.h \
Source/JavaScriptCore/bytecode/SpeculatedType.cpp \
Source/JavaScriptCore/bytecode/SpeculatedType.h \
Source/JavaScriptCore/bytecode/PutByIdStatus.cpp \
Source/JavaScriptCore/bytecode/PutByIdStatus.h \
Source/JavaScriptCore/bytecode/PutKind.h \
+ Source/JavaScriptCore/bytecode/ReduceWhitespace.cpp \
+ Source/JavaScriptCore/bytecode/ReduceWhitespace.h \
Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp \
Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h \
Source/JavaScriptCore/bytecode/ResolveOperation.h \
@@ -158,19 +167,26 @@ javascriptcore_sources += \
Source/JavaScriptCore/bytecompiler/LabelScope.h \
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp \
Source/JavaScriptCore/bytecompiler/RegisterID.h \
+ Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h \
+ Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h \
Source/JavaScriptCore/dfg/DFGAbstractState.cpp \
Source/JavaScriptCore/dfg/DFGAbstractState.h \
Source/JavaScriptCore/dfg/DFGAbstractValue.h \
+ Source/JavaScriptCore/dfg/DFGAdjacencyList.h \
+ Source/JavaScriptCore/dfg/DFGAllocator.h \
Source/JavaScriptCore/dfg/DFGArgumentPosition.h \
Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp \
Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.h \
Source/JavaScriptCore/dfg/DFGArrayMode.cpp \
Source/JavaScriptCore/dfg/DFGArrayMode.h \
+ Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h \
Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp \
Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h \
+ Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h \
Source/JavaScriptCore/dfg/DFGBasicBlock.h \
+ Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h \
Source/JavaScriptCore/dfg/DFGBranchDirection.h \
- Source/JavaScriptCore/dfg/DFGByteCodeCache.h \
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp \
Source/JavaScriptCore/dfg/DFGByteCodeParser.h \
Source/JavaScriptCore/dfg/DFGCCallHelpers.h \
@@ -181,13 +197,16 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGCapabilities.h \
Source/JavaScriptCore/dfg/DFGCFAPhase.cpp \
Source/JavaScriptCore/dfg/DFGCFAPhase.h \
+ Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.h \
+ Source/JavaScriptCore/dfg/DFGCommon.cpp \
Source/JavaScriptCore/dfg/DFGCommon.h \
- Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.cpp \
- Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h \
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp \
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.h \
Source/JavaScriptCore/dfg/DFGCSEPhase.cpp \
Source/JavaScriptCore/dfg/DFGCSEPhase.h \
+ Source/JavaScriptCore/dfg/DFGDCEPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGDCEPhase.h \
Source/JavaScriptCore/dfg/DFGDisassembler.cpp \
Source/JavaScriptCore/dfg/DFGDisassembler.h \
Source/JavaScriptCore/dfg/DFGDominators.cpp \
@@ -195,6 +214,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGDoubleFormatState.h \
Source/JavaScriptCore/dfg/DFGDriver.cpp \
Source/JavaScriptCore/dfg/DFGDriver.h \
+ Source/JavaScriptCore/dfg/DFGEdge.cpp \
+ Source/JavaScriptCore/dfg/DFGEdge.h \
Source/JavaScriptCore/dfg/DFGFPRInfo.h \
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp \
Source/JavaScriptCore/dfg/DFGFixupPhase.h \
@@ -205,15 +226,18 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGInsertionSet.h \
Source/JavaScriptCore/dfg/DFGJITCompiler.cpp \
Source/JavaScriptCore/dfg/DFGJITCompiler.h \
+ Source/JavaScriptCore/dfg/DFGLongLivedState.cpp \
+ Source/JavaScriptCore/dfg/DFGLongLivedState.h \
Source/JavaScriptCore/dfg/DFGMinifiedGraph.h \
+ Source/JavaScriptCore/dfg/DFGMinifiedID.h \
Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp \
Source/JavaScriptCore/dfg/DFGMinifiedNode.h \
+ Source/JavaScriptCore/dfg/DFGNode.cpp \
Source/JavaScriptCore/dfg/DFGNode.h \
+ Source/JavaScriptCore/dfg/DFGNodeAllocator.h \
Source/JavaScriptCore/dfg/DFGNodeFlags.cpp \
Source/JavaScriptCore/dfg/DFGNodeFlags.h \
- Source/JavaScriptCore/dfg/DFGAdjacencyList.h \
Source/JavaScriptCore/dfg/DFGNodeType.h \
- Source/JavaScriptCore/dfg/DFGEdge.h \
Source/JavaScriptCore/dfg/DFGOperations.cpp \
Source/JavaScriptCore/dfg/DFGOperations.h \
Source/JavaScriptCore/dfg/DFGOSREntry.cpp \
@@ -224,10 +248,15 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h \
Source/JavaScriptCore/dfg/DFGOSRExit.h \
Source/JavaScriptCore/dfg/DFGOSRExit.cpp \
+ Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h \
+ Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.cpp \
+ Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.h \
Source/JavaScriptCore/dfg/DFGPhase.cpp \
Source/JavaScriptCore/dfg/DFGPhase.h \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h \
+ Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.h \
Source/JavaScriptCore/dfg/DFGRegisterBank.h \
Source/JavaScriptCore/dfg/DFGRegisterSet.h \
Source/JavaScriptCore/dfg/DFGRepatch.cpp \
@@ -241,10 +270,14 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \
Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h \
- Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp \
- Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h \
+ Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.h \
Source/JavaScriptCore/dfg/DFGThunks.cpp \
Source/JavaScriptCore/dfg/DFGThunks.h \
+ Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGUnificationPhase.h \
+ Source/JavaScriptCore/dfg/DFGUseKind.cpp \
+ Source/JavaScriptCore/dfg/DFGUseKind.h \
Source/JavaScriptCore/dfg/DFGValueRecoveryOverride.h \
Source/JavaScriptCore/dfg/DFGValueSource.cpp \
Source/JavaScriptCore/dfg/DFGValueSource.h \
@@ -257,33 +290,37 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGVariableAccessData.h \
Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp \
Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.h \
+ Source/JavaScriptCore/dfg/DFGVariadicFunction.h \
Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp \
Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.h \
Source/JavaScriptCore/disassembler/Disassembler.cpp \
Source/JavaScriptCore/disassembler/Disassembler.h \
Source/JavaScriptCore/heap/CopiedAllocator.h \
Source/JavaScriptCore/heap/CopiedBlock.h \
+ Source/JavaScriptCore/heap/CopiedBlockInlines.h \
Source/JavaScriptCore/heap/CopiedSpace.cpp \
Source/JavaScriptCore/heap/CopiedSpace.h \
Source/JavaScriptCore/heap/CopiedSpaceInlines.h \
- Source/JavaScriptCore/heap/CopyVisitor.h \
- Source/JavaScriptCore/heap/CopyVisitorInlines.h \
- Source/JavaScriptCore/heap/CopyVisitor.cpp \
- Source/JavaScriptCore/heap/CardSet.h \
+ Source/JavaScriptCore/heap/CopyVisitor.h \
+ Source/JavaScriptCore/heap/CopyVisitorInlines.h \
+ Source/JavaScriptCore/heap/CopyVisitor.cpp \
+ Source/JavaScriptCore/heap/CopyWorkList.h \
Source/JavaScriptCore/heap/ConservativeRoots.cpp \
Source/JavaScriptCore/heap/ConservativeRoots.h \
Source/JavaScriptCore/heap/DFGCodeBlocks.cpp \
Source/JavaScriptCore/heap/DFGCodeBlocks.h \
Source/JavaScriptCore/heap/GCAssertions.h \
Source/JavaScriptCore/heap/Handle.h \
+ Source/JavaScriptCore/heap/HandleBlock.h \
+ Source/JavaScriptCore/heap/HandleBlockInlines.h \
Source/JavaScriptCore/heap/HandleSet.cpp \
Source/JavaScriptCore/heap/HandleSet.h \
Source/JavaScriptCore/heap/HeapBlock.h \
- Source/JavaScriptCore/heap/HeapTimer.h \
- Source/JavaScriptCore/heap/HeapTimer.cpp \
+ Source/JavaScriptCore/heap/HeapTimer.h \
+ Source/JavaScriptCore/heap/HeapTimer.cpp \
Source/JavaScriptCore/heap/IncrementalSweeper.h \
Source/JavaScriptCore/heap/IncrementalSweeper.cpp \
- Source/JavaScriptCore/heap/SlotVisitor.cpp \
+ Source/JavaScriptCore/heap/SlotVisitor.cpp \
Source/JavaScriptCore/heap/SlotVisitor.h \
Source/JavaScriptCore/heap/SlotVisitorInlines.h \
Source/JavaScriptCore/heap/HandleStack.cpp \
@@ -291,14 +328,14 @@ javascriptcore_sources += \
Source/JavaScriptCore/heap/HandleTypes.h \
Source/JavaScriptCore/heap/BlockAllocator.cpp \
Source/JavaScriptCore/heap/BlockAllocator.h \
- Source/JavaScriptCore/heap/GCThreadSharedData.cpp \
- Source/JavaScriptCore/heap/GCThreadSharedData.h \
- Source/JavaScriptCore/heap/GCThread.cpp \
- Source/JavaScriptCore/heap/GCThread.h \
+ Source/JavaScriptCore/heap/GCThreadSharedData.cpp \
+ Source/JavaScriptCore/heap/GCThreadSharedData.h \
+ Source/JavaScriptCore/heap/GCThread.cpp \
+ Source/JavaScriptCore/heap/GCThread.h \
Source/JavaScriptCore/heap/Heap.cpp \
Source/JavaScriptCore/heap/Heap.h \
- Source/JavaScriptCore/heap/HeapStatistics.cpp \
- Source/JavaScriptCore/heap/HeapStatistics.h \
+ Source/JavaScriptCore/heap/HeapStatistics.cpp \
+ Source/JavaScriptCore/heap/HeapStatistics.h \
Source/JavaScriptCore/heap/JITStubRoutineSet.cpp \
Source/JavaScriptCore/heap/JITStubRoutineSet.h \
Source/JavaScriptCore/heap/ListableHandler.h \
@@ -308,7 +345,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/heap/MachineStackMarker.h \
Source/JavaScriptCore/heap/MarkStack.cpp \
Source/JavaScriptCore/heap/MarkStack.h \
- Source/JavaScriptCore/heap/MarkStackInlines.h \
+ Source/JavaScriptCore/heap/MarkStackInlines.h \
Source/JavaScriptCore/heap/HeapRootVisitor.h \
Source/JavaScriptCore/heap/MarkedAllocator.cpp \
Source/JavaScriptCore/heap/MarkedAllocator.h \
@@ -319,17 +356,22 @@ javascriptcore_sources += \
Source/JavaScriptCore/heap/MarkedSpace.cpp \
Source/JavaScriptCore/heap/MarkedSpace.h \
Source/JavaScriptCore/heap/PassWeak.h \
+ Source/JavaScriptCore/heap/Region.h \
Source/JavaScriptCore/heap/Strong.h \
Source/JavaScriptCore/heap/StrongInlines.h \
+ Source/JavaScriptCore/heap/SuperRegion.cpp \
+ Source/JavaScriptCore/heap/SuperRegion.h \
Source/JavaScriptCore/heap/UnconditionalFinalizer.h \
Source/JavaScriptCore/heap/VTableSpectrum.cpp \
Source/JavaScriptCore/heap/VTableSpectrum.h \
+ Source/JavaScriptCore/heap/Weak.cpp \
Source/JavaScriptCore/heap/Weak.h \
Source/JavaScriptCore/heap/WeakBlock.cpp \
Source/JavaScriptCore/heap/WeakBlock.h \
Source/JavaScriptCore/heap/WeakHandleOwner.cpp \
Source/JavaScriptCore/heap/WeakHandleOwner.h \
Source/JavaScriptCore/heap/WeakImpl.h \
+ Source/JavaScriptCore/heap/WeakInlines.h \
Source/JavaScriptCore/heap/WeakSet.cpp \
Source/JavaScriptCore/heap/WeakSet.h \
Source/JavaScriptCore/heap/WeakSetInlines.h \
@@ -396,6 +438,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/jit/ClosureCallStubRoutine.h \
Source/JavaScriptCore/jit/ExecutableAllocator.cpp \
Source/JavaScriptCore/jit/ExecutableAllocator.h \
+ Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp \
Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp \
Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h \
Source/JavaScriptCore/jit/HostCallReturnValue.cpp \
@@ -424,13 +467,17 @@ javascriptcore_sources += \
Source/JavaScriptCore/jit/JITStubRoutine.h \
Source/JavaScriptCore/jit/JITStubs.cpp \
Source/JavaScriptCore/jit/JITStubs.h \
+ Source/JavaScriptCore/jit/JITThunks.cpp \
+ Source/JavaScriptCore/jit/JITThunks.h \
Source/JavaScriptCore/jit/JITWriteBarrier.h \
Source/JavaScriptCore/jit/JSInterfaceJIT.h \
Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp \
Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h \
Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
+ Source/JavaScriptCore/jit/ThunkGenerator.h \
Source/JavaScriptCore/jit/ThunkGenerators.cpp \
Source/JavaScriptCore/jit/ThunkGenerators.h \
+ Source/JavaScriptCore/jit/UnusedPointer.h \
Source/JavaScriptCore/llint/LLIntCommon.h \
Source/JavaScriptCore/llint/LLIntCLoop.cpp \
Source/JavaScriptCore/llint/LLIntCLoop.h \
@@ -449,7 +496,6 @@ javascriptcore_sources += \
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 \
Source/JavaScriptCore/parser/Lexer.cpp \
Source/JavaScriptCore/parser/Lexer.h \
@@ -459,26 +505,53 @@ javascriptcore_sources += \
Source/JavaScriptCore/parser/Nodes.h \
Source/JavaScriptCore/parser/ParserArena.cpp \
Source/JavaScriptCore/parser/ParserArena.h \
+ Source/JavaScriptCore/parser/ParserError.h \
Source/JavaScriptCore/parser/ParserTokens.h \
Source/JavaScriptCore/parser/Parser.cpp \
Source/JavaScriptCore/parser/Parser.h \
Source/JavaScriptCore/parser/ParserModes.h \
Source/JavaScriptCore/parser/ResultType.h \
Source/JavaScriptCore/parser/SourceCode.h \
+ Source/JavaScriptCore/parser/SourceProvider.cpp \
Source/JavaScriptCore/parser/SourceProvider.h \
Source/JavaScriptCore/parser/SourceProviderCache.cpp \
Source/JavaScriptCore/parser/SourceProviderCache.h \
Source/JavaScriptCore/parser/SourceProviderCacheItem.h \
Source/JavaScriptCore/parser/SyntaxChecker.h \
Source/JavaScriptCore/profiler/CallIdentifier.h \
+ Source/JavaScriptCore/profiler/ProfilerBytecode.cpp \
+ Source/JavaScriptCore/profiler/ProfilerBytecode.h \
+ Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp \
+ Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h \
+ Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp \
+ Source/JavaScriptCore/profiler/ProfilerBytecodes.h \
+ Source/JavaScriptCore/profiler/ProfilerCompilation.cpp \
+ Source/JavaScriptCore/profiler/ProfilerCompilation.h \
+ Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp \
+ Source/JavaScriptCore/profiler/ProfilerCompilationKind.h \
+ Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp \
+ Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h \
+ Source/JavaScriptCore/profiler/ProfilerDatabase.cpp \
+ Source/JavaScriptCore/profiler/ProfilerDatabase.h \
+ Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h \
+ Source/JavaScriptCore/profiler/ProfilerOrigin.cpp \
+ Source/JavaScriptCore/profiler/ProfilerOrigin.h \
+ Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp \
+ Source/JavaScriptCore/profiler/ProfilerOriginStack.h \
+ Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp \
+ Source/JavaScriptCore/profiler/ProfilerOSRExit.h \
+ Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp \
+ Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h \
+ Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp \
+ Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h \
Source/JavaScriptCore/profiler/Profile.cpp \
Source/JavaScriptCore/profiler/ProfileGenerator.cpp \
Source/JavaScriptCore/profiler/ProfileGenerator.h \
Source/JavaScriptCore/profiler/Profile.h \
Source/JavaScriptCore/profiler/ProfileNode.cpp \
Source/JavaScriptCore/profiler/ProfileNode.h \
- Source/JavaScriptCore/profiler/Profiler.cpp \
- Source/JavaScriptCore/profiler/Profiler.h \
+ Source/JavaScriptCore/profiler/LegacyProfiler.cpp \
+ Source/JavaScriptCore/profiler/LegacyProfiler.h \
Source/JavaScriptCore/runtime/ArgList.cpp \
Source/JavaScriptCore/runtime/ArgList.h \
Source/JavaScriptCore/runtime/Arguments.cpp \
@@ -538,6 +611,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/ExecutionHarness.h \
Source/JavaScriptCore/runtime/FunctionConstructor.cpp \
Source/JavaScriptCore/runtime/FunctionConstructor.h \
+ Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp \
+ Source/JavaScriptCore/runtime/FunctionExecutableDump.h \
Source/JavaScriptCore/runtime/FunctionPrototype.cpp \
Source/JavaScriptCore/runtime/FunctionPrototype.h \
Source/JavaScriptCore/runtime/GCActivityCallback.cpp \
@@ -564,15 +639,16 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/JSCell.cpp \
Source/JavaScriptCore/runtime/JSCell.h \
Source/JavaScriptCore/runtime/JSDateMath.cpp \
+ Source/JavaScriptCore/runtime/JSCellInlines.h \
Source/JavaScriptCore/runtime/JSDateMath.h \
- Source/JavaScriptCore/runtime/JSDestructibleObject.h \
+ Source/JavaScriptCore/runtime/JSDestructibleObject.h \
Source/JavaScriptCore/runtime/JSFunction.cpp \
Source/JavaScriptCore/runtime/JSFunction.h \
Source/JavaScriptCore/runtime/JSBoundFunction.cpp \
Source/JavaScriptCore/runtime/JSBoundFunction.h \
Source/JavaScriptCore/runtime/JSExportMacros.h \
- Source/JavaScriptCore/runtime/JSGlobalData.cpp \
- Source/JavaScriptCore/runtime/JSGlobalData.h \
+ Source/JavaScriptCore/runtime/VM.cpp \
+ Source/JavaScriptCore/runtime/VM.h \
Source/JavaScriptCore/runtime/JSGlobalObject.cpp \
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp \
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h \
@@ -605,9 +681,9 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/JSSymbolTableObject.h \
Source/JavaScriptCore/runtime/JSType.h \
Source/JavaScriptCore/runtime/JSTypeInfo.h \
- Source/JavaScriptCore/runtime/JSValue.cpp \
- Source/JavaScriptCore/runtime/JSValue.h \
- Source/JavaScriptCore/runtime/JSValueInlines.h \
+ Source/JavaScriptCore/runtime/JSCJSValue.cpp \
+ Source/JavaScriptCore/runtime/JSCJSValue.h \
+ Source/JavaScriptCore/runtime/JSCJSValueInlines.h \
Source/JavaScriptCore/runtime/JSVariableObject.cpp \
Source/JavaScriptCore/runtime/JSVariableObject.h \
Source/JavaScriptCore/runtime/JSWithScope.h \
@@ -656,6 +732,9 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/PropertyOffset.h \
Source/JavaScriptCore/runtime/PropertySlot.cpp \
Source/JavaScriptCore/runtime/PropertySlot.h \
+ Source/JavaScriptCore/runtime/PropertyTable.cpp \
+ Source/JavaScriptCore/runtime/PrototypeMap.cpp \
+ Source/JavaScriptCore/runtime/PrototypeMap.h \
Source/JavaScriptCore/runtime/PropertyStorage.h \
Source/JavaScriptCore/runtime/Protect.h \
Source/JavaScriptCore/runtime/PutDirectIndexMode.h \
@@ -696,15 +775,20 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/StructureChain.h \
Source/JavaScriptCore/runtime/Structure.cpp \
Source/JavaScriptCore/runtime/Structure.h \
+ Source/JavaScriptCore/runtime/StructureInlines.h \
+ Source/JavaScriptCore/runtime/StructureRareData.cpp \
+ Source/JavaScriptCore/runtime/StructureRareData.h \
+ Source/JavaScriptCore/runtime/StructureRareDataInlines.h \
Source/JavaScriptCore/runtime/StructureTransitionTable.h \
Source/JavaScriptCore/runtime/SymbolTable.cpp \
Source/JavaScriptCore/runtime/SymbolTable.h \
- Source/JavaScriptCore/runtime/Terminator.h \
- Source/JavaScriptCore/runtime/TimeoutChecker.cpp \
- Source/JavaScriptCore/runtime/TimeoutChecker.h \
Source/JavaScriptCore/runtime/Tracing.h \
Source/JavaScriptCore/runtime/TypedArrayDescriptor.h \
Source/JavaScriptCore/runtime/Uint16WithFraction.h \
+ Source/JavaScriptCore/runtime/VMStackBounds.h \
+ Source/JavaScriptCore/runtime/Watchdog.cpp \
+ Source/JavaScriptCore/runtime/Watchdog.h \
+ Source/JavaScriptCore/runtime/WatchdogNone.cpp \
Source/JavaScriptCore/runtime/WeakGCMap.h \
Source/JavaScriptCore/runtime/WeakRandom.h \
Source/JavaScriptCore/runtime/WriteBarrier.h \
@@ -727,19 +811,13 @@ javascriptcore_sources += \
Source/JavaScriptCore/yarr/YarrSyntaxChecker.cpp \
Source/JavaScriptCore/yarr/YarrSyntaxChecker.h
-if TARGET_WIN32
-else
-javascriptcore_sources += \
- Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
-endif
-
llint_nosources += \
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm \
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm \
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
offlineasm_nosources += \
- Source/JavaScriptCore/offlineasm/armv7.rb \
+ Source/JavaScriptCore/offlineasm/arm.rb \
Source/JavaScriptCore/offlineasm/asm.rb \
Source/JavaScriptCore/offlineasm/ast.rb \
Source/JavaScriptCore/offlineasm/backends.rb \
@@ -747,6 +825,7 @@ offlineasm_nosources += \
Source/JavaScriptCore/offlineasm/config.rb \
Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb \
Source/JavaScriptCore/offlineasm/instructions.rb \
+ Source/JavaScriptCore/offlineasm/mips.rb \
Source/JavaScriptCore/offlineasm/offsets.rb \
Source/JavaScriptCore/offlineasm/opt.rb \
Source/JavaScriptCore/offlineasm/parser.rb \
@@ -754,6 +833,7 @@ offlineasm_nosources += \
Source/JavaScriptCore/offlineasm/risc.rb \
Source/JavaScriptCore/offlineasm/self_hash.rb \
Source/JavaScriptCore/offlineasm/settings.rb \
+ Source/JavaScriptCore/offlineasm/sh4.rb \
Source/JavaScriptCore/offlineasm/transform.rb \
Source/JavaScriptCore/offlineasm/x86.rb
diff --git a/Source/JavaScriptCore/Info.plist b/Source/JavaScriptCore/Info.plist
index 3c0bf46cf..35b597c71 100644
--- a/Source/JavaScriptCore/Info.plist
+++ b/Source/JavaScriptCore/Info.plist
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>${BUNDLE_VERSION}, Copyright 2003-2012 Apple Inc.; Copyright 1999-2001 Harri Porten &lt;porten@kde.org&gt;; Copyright 2001 Peter Kelly &lt;pmk@post.com&gt;; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string>
+ <string>${BUNDLE_VERSION}, Copyright 2003-2013 Apple Inc.; Copyright 1999-2001 Harri Porten &lt;porten@kde.org&gt;; Copyright 2001 Peter Kelly &lt;pmk@post.com&gt;; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string>
<key>CFBundleIdentifier</key>
<string>com.apple.${PRODUCT_NAME}</string>
<key>CFBundleInfoDictionaryVersion</key>
diff --git a/Source/JavaScriptCore/JSCTypedArrayStubs.h b/Source/JavaScriptCore/JSCTypedArrayStubs.h
index 91481fab0..fef67305e 100644
--- a/Source/JavaScriptCore/JSCTypedArrayStubs.h
+++ b/Source/JavaScriptCore/JSCTypedArrayStubs.h
@@ -28,6 +28,7 @@
#include "JSDestructibleObject.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include <wtf/Float32Array.h>
#include <wtf/Float64Array.h>
#include <wtf/Forward.h>
@@ -47,8 +48,8 @@ public: \
typedef JSDestructibleObject Base; \
static JS##name##Array* create(JSC::Structure* structure, JSGlobalObject* globalObject, PassRefPtr<name##Array> impl) \
{ \
- JS##name##Array* ptr = new (NotNull, JSC::allocateCell<JS##name##Array>(globalObject->globalData().heap)) JS##name##Array(structure, globalObject, impl); \
- ptr->finishCreation(globalObject->globalData()); \
+ JS##name##Array* ptr = new (NotNull, JSC::allocateCell<JS##name##Array>(globalObject->vm().heap)) JS##name##Array(structure, globalObject, impl); \
+ ptr->finishCreation(globalObject->vm()); \
return ptr; \
}\
\
@@ -59,9 +60,9 @@ public: \
static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool);\
static const JSC::ClassInfo s_info;\
\
- static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\
{\
- return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);\
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);\
}\
\
static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\
@@ -73,7 +74,7 @@ public: \
RefPtr<name##Array> m_impl;\
protected:\
JS##name##Array(JSC::Structure*, JSGlobalObject*, PassRefPtr<name##Array>);\
- void finishCreation(JSC::JSGlobalData&);\
+ void finishCreation(JSC::VM&);\
static const unsigned StructureFlags = JSC::OverridesGetPropertyNames | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | Base::StructureFlags; \
JSC::JSValue getByIndex(JSC::ExecState*, unsigned index);\
void indexSetter(JSC::ExecState*, unsigned index, JSC::JSValue);\
@@ -82,19 +83,19 @@ protected:\
const ClassInfo JS##name##Array::s_info = { #name "Array" , &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JS##name##Array) };\
\
JS##name##Array::JS##name##Array(Structure* structure, JSGlobalObject* globalObject, PassRefPtr<name##Array> impl)\
- : Base(globalObject->globalData(), structure)\
+ : Base(globalObject->vm(), structure)\
, m_impl(impl)\
{\
}\
\
-void JS##name##Array::finishCreation(JSGlobalData& globalData)\
+void JS##name##Array::finishCreation(VM& vm)\
{\
- Base::finishCreation(globalData);\
+ Base::finishCreation(vm);\
TypedArrayDescriptor descriptor(&JS##name##Array::s_info, OBJECT_OFFSETOF(JS##name##Array, m_storage), OBJECT_OFFSETOF(JS##name##Array, m_storageLength));\
- globalData.registerTypedArrayDescriptor(m_impl.get(), descriptor);\
+ vm.registerTypedArrayDescriptor(m_impl.get(), descriptor);\
m_storage = m_impl->data();\
m_storageLength = m_impl->length();\
- putDirect(globalData, globalData.propertyNames->length, jsNumber(m_storageLength), DontDelete | ReadOnly | DontEnum); \
+ putDirect(vm, vm.propertyNames->length, jsNumber(m_storageLength), DontDelete | ReadOnly | DontEnum); \
ASSERT(inherits(&s_info));\
}\
\
@@ -173,7 +174,7 @@ JSValue JS##name##Array::getByIndex(ExecState*, unsigned index)\
{\
ASSERT_GC_OBJECT_INHERITS(this, &s_info);\
type result = m_impl->item(index);\
- if (isnan((double)result))\
+ if (std::isnan((double)result))\
return jsNaN();\
return JSValue(result);\
}\
@@ -183,7 +184,7 @@ static EncodedJSValue JSC_HOST_CALL constructJS##name##Array(ExecState* callFram
int32_t length = callFrame->argument(0).toInt32(callFrame); \
if (length < 0) \
return JSValue::encode(jsUndefined()); \
- Structure* structure = JS##name##Array::createStructure(callFrame->globalData(), callFrame->lexicalGlobalObject(), callFrame->lexicalGlobalObject()->objectPrototype()); \
+ Structure* structure = JS##name##Array::createStructure(callFrame->vm(), callFrame->lexicalGlobalObject(), callFrame->lexicalGlobalObject()->objectPrototype()); \
RefPtr<name##Array> buffer = name##Array::create(length); \
if (!buffer) \
return throwVMError(callFrame, createRangeError(callFrame, "ArrayBuffer size is not a small enough positive integer.")); \
diff --git a/Source/JavaScriptCore/JavaScriptCore.gir.in b/Source/JavaScriptCore/JavaScriptCore.gir.in
new file mode 100644
index 000000000..6f8dcc128
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.gir.in
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<repository version="1.2"
+ xmlns="http://www.gtk.org/introspection/core/1.0"
+ xmlns:c="http://www.gtk.org/introspection/c/1.0">
+ <namespace name="JavaScriptCore" version="@WEBKITGTK_API_VERSION@"
+ shared-library="javascriptcoregtk-@WEBKITGTK_API_VERSION@"
+ c:identifier-prefixes="JS"
+ c:symbol-prefixes="JS">
+ <record name="GlobalContext" c:type="JSGlobalContextRef" foreign="1"/>
+ <record name="Value" c:type="JSValueRef" foreign="1"/>
+ </namespace>
+</repository>
diff --git a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp b/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
deleted file mode 100644
index 4f7a205e7..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# Copyright (C) 2009, 2012 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-{
- 'includes': [
- '../../WebKit/chromium/WinPrecompile.gypi',
- '../../WebKit/chromium/features.gypi',
- '../JavaScriptCore.gypi',
- ],
- 'variables': {
- # Location of the chromium src directory.
- 'conditions': [
- ['inside_chromium_build==0', {
- # Webkit is being built outside of the full chromium project.
- 'chromium_src_dir': '../../WebKit/chromium',
- },{
- # WebKit is checked out in src/chromium/third_party/WebKit
- 'chromium_src_dir': '../../../../..',
- }],
- ],
- },
- 'conditions': [
- ['os_posix == 1 and OS != "mac" and gcc_version>=46', {
- 'target_defaults': {
- # Disable warnings about c++0x compatibility, as some names (such as nullptr) conflict
- # with upcoming c++0x types.
- 'cflags_cc': ['-Wno-c++0x-compat'],
- },
- }],
- ],
- 'targets': [
- {
- 'target_name': 'yarr',
- 'type': 'static_library',
- 'dependencies': [
- '../../WTF/WTF.gyp/WTF.gyp:wtf',
- ],
- 'variables': { 'optimize': 'max' },
- 'actions': [
- {
- 'action_name': 'retgen',
- 'inputs': [
- '../create_regex_tables',
- ],
- 'arguments': [
- '--no-tables',
- ],
- 'outputs': [
- '<(INTERMEDIATE_DIR)/RegExpJitTables.h',
- ],
- 'action': ['python', '<@(_inputs)', '<@(_arguments)', '<@(_outputs)'],
- },
- ],
- 'include_dirs': [
- '<(INTERMEDIATE_DIR)',
- '..',
- '../runtime',
- ],
- 'sources': [
- '<@(javascriptcore_yarr_files)',
- ],
- 'export_dependent_settings': [
- '../../WTF/WTF.gyp/WTF.gyp:wtf',
- ],
- },
- ], # targets
-}
diff --git a/Source/JavaScriptCore/JavaScriptCore.gypi b/Source/JavaScriptCore/JavaScriptCore.gypi
deleted file mode 100644
index 1f1802bde..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.gypi
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- 'variables': {
- 'project_dir': ['.'],
- 'javascriptcore_yarr_files': [
- 'yarr/YarrCanonicalizeUCS2.cpp',
- 'yarr/YarrInterpreter.cpp',
- 'yarr/YarrPattern.cpp',
- 'yarr/YarrSyntaxChecker.cpp',
- ],
- 'javascriptcore_derived_source_files': [
- '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/RegExpJitTables.h',
- ],
- }
-}
diff --git a/Source/JavaScriptCore/JavaScriptCore.order b/Source/JavaScriptCore/JavaScriptCore.order
index 6a1946684..0c2b29c87 100644
--- a/Source/JavaScriptCore/JavaScriptCore.order
+++ b/Source/JavaScriptCore/JavaScriptCore.order
@@ -23,7 +23,7 @@ __ZN3JSCL23initializeThreadingOnceEv
__ZN3WTF10StringImpl5emptyEv
__ZN3WTF13WTFThreadDataC1Ev
__ZN3WTF11StackBounds10initializeEv
-__ZN3JSC12JSGlobalData10storeVPtrsEv
+__ZN3JSC12VM10storeVPtrsEv
__ZN3JSC7JSArrayC1ENS_6JSCell20VPtrStealingHackTypeE
__ZN3JSC10JSFunctionC1ENS_6JSCell20VPtrStealingHackTypeE
__ZN3WTF15initializeDatesEv
@@ -119,65 +119,65 @@ __ZN3WTF12AtomicString6removeEPNS_10StringImplE
_JSGlobalContextCreate
__ZN3JSC6JSLock4lockENS_14JSLockBehaviorE
__ZN3JSCL17createJSLockCountEv
-__ZN3JSC12JSGlobalData14sharedInstanceEv
-__ZN3JSC12JSGlobalDataC2ENS0_14GlobalDataTypeENS_8HeapTypeE
+__ZN3JSC12VM14sharedInstanceEv
+__ZN3JSC12VMC2ENS0_14VMTypeENS_8HeapTypeE
__ZN3JSC21createIdentifierTableEv
-__ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
-__ZN3JSC17CommonIdentifiersC2EPNS_12JSGlobalDataE
-__ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
+__ZN3JSC17CommonIdentifiersC1EPNS_12VME
+__ZN3JSC17CommonIdentifiersC2EPNS_12VME
+__ZN3JSC10Identifier3addEPNS_12VMEPKc
__ZN3JSC15IdentifierTable3addIPKcNS_27IdentifierCStringTranslatorEEESt4pairIN3WTF29HashTableConstIteratorAdapterINS6_9HashTableIPNS6_10StringImplESA_NS6_17IdentityExtractorISA_EENS6_10StringHashENS6_10HashTraitsISA_EESF_EESA_EEbET_
__ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_10StringHashENS_10HashTraitsIS2_EES7_E6expandEv
__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrINS_10StringImplEEEENS_18PairFirstExtractorIS7_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSD_IS6_EEEESE_E6expandEv
__ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_10StringHashENS_10HashTraitsIS2_EES7_E4findIS2_NS_22IdentityHashTranslatorIS2_S2_S5_EEEENS_17HashTableIteratorIS2_S2_S4_S5_S7_S7_EERKT_
-__ZN3JSC10IdentifierC1EPNS_12JSGlobalDataEPKc
+__ZN3JSC10IdentifierC1EPNS_12VMEPKc
__ZN3JSC12SmallStringsC1Ev
__ZN3JSC19ExecutableAllocator17intializePageSizeEv
__ZNK3JSC19ExecutableAllocator7isValidEv
__ZN3WTF11OSAllocator18reserveUncommittedEmNS0_5UsageEbb
__ZN3JSC14ExecutablePool11systemAllocEm
__ZN3WTF11OSAllocator6commitEPvmbb
-__ZN3JSC5LexerC1EPNS_12JSGlobalDataE
+__ZN3JSC5LexerC1EPNS_12VME
__ZN3JSC11ParserArenaC1Ev
__ZN3JSC11ParserArenaC2Ev
__ZN3JSC14TimeoutCheckerC1Ev
-__ZN3JSC4HeapC1EPNS_12JSGlobalDataE
-__ZN3JSC4HeapC2EPNS_12JSGlobalDataE
-__ZN3JSC11MarkedSpaceC1EPNS_12JSGlobalDataE
+__ZN3JSC4HeapC1EPNS_12VME
+__ZN3JSC4HeapC2EPNS_12VME
+__ZN3JSC11MarkedSpaceC1EPNS_12VME
__ZN3JSC25DefaultGCActivityCallbackC1EPNS_4HeapE
__ZN3JSC25DefaultGCActivityCallback17commonConstructorEPNS_4HeapEP11__CFRunLoop
__ZN3JSC14MachineThreadsC1EPNS_4HeapE
__ZN3JSC9MarkStack18initializePagesizeEv
__ZN3WTF11OSAllocator16reserveAndCommitEmNS0_5UsageEbb
-__ZN3JSC10HandleHeapC1EPNS_12JSGlobalDataE
+__ZN3JSC10HandleHeapC1EPNS_12VME
__ZN3WTF10BlockStackIN3JSC10HandleHeap4NodeEE4growEv
__ZN3WTF6VectorIPN3JSC10HandleHeap4NodeELm0EE15reserveCapacityEm
__ZN3JSC11HandleStackC1Ev
__ZN3WTF10BlockStackIN3JSC7JSValueEE4growEv
__ZN3WTF6VectorIPN3JSC7JSValueELm0EE15reserveCapacityEm
__ZN3JSC25DefaultGCActivityCallbackclEv
-__ZN3JSC11RegExpCacheC1EPNS_12JSGlobalDataE
-__ZN3JSC11InterpreterC1ERNS_12JSGlobalDataE
+__ZN3JSC11RegExpCacheC1EPNS_12VME
+__ZN3JSC11InterpreterC1ERNS_12VME
__ZN3JSC10HandleHeap12writeBarrierEPNS_7JSValueERKS1_
__ZN3JSC12JSStack23addToCommittedByteCountEl
__ZN3JSC11MarkedSpace21allocateFromSizeClassERNS0_9SizeClassE
__ZN3JSC11MarkedSpace13allocateBlockERNS0_9SizeClassE
-__ZN3JSC11MarkedBlock6createEPNS_12JSGlobalDataEm
+__ZN3JSC11MarkedBlock6createEPNS_12VMEm
__ZN3WTF21PageAllocationAligned8allocateEmmNS_11OSAllocator5UsageEbb
__ZN3WTF9HashTableIPN3JSC11MarkedBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
__ZN3JSC6JSCellD1Ev
-__ZN3JSC9StructureC1ERNS_12JSGlobalDataE
-__ZN3JSC6StrongINS_9StructureEE3setERNS_12JSGlobalDataEPS1_
-__ZN3JSC9Structure6createERNS_12JSGlobalDataENS_7JSValueERKNS_8TypeInfoEjPKNS_9ClassInfoE
-__ZN3JSC9StructureC1ERNS_12JSGlobalDataENS_7JSValueERKNS_8TypeInfoEjPKNS_9ClassInfoE
+__ZN3JSC9StructureC1ERNS_12VME
+__ZN3JSC6StrongINS_9StructureEE3setERNS_12VMEPS1_
+__ZN3JSC9Structure6createERNS_12VMENS_7JSValueERKNS_8TypeInfoEjPKNS_9ClassInfoE
+__ZN3JSC9StructureC1ERNS_12VMENS_7JSValueERKNS_8TypeInfoEjPKNS_9ClassInfoE
__ZN3WTF13wtfThreadDataEv
__ZN3JSC27startProfilerServerIfNeededEv
+[ProfilerServer sharedProfileServer]
-[ProfilerServer init]
-__ZN3JSC9JITThunksC1EPNS_12JSGlobalDataE
-__ZN3JSC9JITThunksC2EPNS_12JSGlobalDataE
-__ZN3JSC3JITC1EPNS_12JSGlobalDataEPNS_9CodeBlockE
-__ZN3JSC3JITC2EPNS_12JSGlobalDataEPNS_9CodeBlockE
-__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEPN3WTF6RefPtrINS_14ExecutablePoolEEEPNS_12JSGlobalDataEPNS_19TrampolineStructureE
+__ZN3JSC9JITThunksC1EPNS_12VME
+__ZN3JSC9JITThunksC2EPNS_12VME
+__ZN3JSC3JITC1EPNS_12VMEPNS_9CodeBlockE
+__ZN3JSC3JITC2EPNS_12VMEPNS_9CodeBlockE
+__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEPN3WTF6RefPtrINS_14ExecutablePoolEEEPNS_12VMEPNS_19TrampolineStructureE
__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common15ResultConditionENS_12X86Registers10RegisterIDES4_
__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDE
__ZN3JSC12X86Assembler3jCCENS0_9ConditionE
@@ -192,7 +192,7 @@ __ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common15Resu
__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDENS_12X86Registers10RegisterIDE
__ZN3WTF6VectorIcLm128EE14expandCapacityEm
__ZN3WTF6VectorIcLm128EE4growEm
-__ZN3JSC3JIT27privateCompileCTINativeCallEPNS_12JSGlobalDataEb
+__ZN3JSC3JIT27privateCompileCTINativeCallEPNS_12VMEb
__ZNK3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE4Jump4linkEPS2_
__ZN3WTF10RefCountedIN3JSC14ExecutablePoolEE5derefEv
__ZN3JSC14MachineThreads29makeUsableFromMultipleThreadsEv
@@ -200,7 +200,7 @@ _JSGlobalContextCreateInGroup
__ZN3JSC4Heap16activityCallbackEv
__ZN3JSC25DefaultGCActivityCallback11synchronizeEv
__ZN3JSC14TimeoutChecker5resetEv
-__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
+__ZN3JSC14JSGlobalObjectnwEmPNS_12VME
__ZN3WTF12randomNumberEv
__ZN3WTF29cryptographicallyRandomNumberEv
__ZN3WTF35cryptographicallyRandomValuesFromOSEPhm
@@ -208,53 +208,52 @@ __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject5resetENS_7JSValueE
__ZN3JSC17FunctionPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC17FunctionPrototypeC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_9StructureERKNS_10IdentifierE
+__ZN3JSC16InternalFunctionC2EPNS_12VMEPNS_14JSGlobalObjectEPNS_9StructureERKNS_10IdentifierE
__ZN3JSC24JSObjectWithGlobalObjectC2EPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC7UStringC1EPKc
-__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
+__ZN3JSC12SmallStrings17createEmptyStringEPNS_12VME
__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
-__ZN3JSC9Structure3getERNS_12JSGlobalDataEPN3WTF10StringImplERjRPNS_6JSCellE
-__ZN3JSC9Structure21addPropertyTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
+__ZN3JSC9Structure3getERNS_12VMEPN3WTF10StringImplERjRPNS_6JSCellE
+__ZN3JSC9Structure21addPropertyTransitionERNS_12VMEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
__ZN3JSC9Structure17createPropertyMapEj
__ZN3WTF14deleteOwnedPtrIN3JSC13PropertyTableEEEvPT_
-__ZN3JSC9Structure16putSpecificValueERNS_12JSGlobalDataERKNS_10IdentifierEjPNS_6JSCellE
-__ZN3JSC24StructureTransitionTable3addERNS_12JSGlobalDataEPNS_9StructureE
-__ZN3JSC9Structure28addPropertyWithoutTransitionERNS_12JSGlobalDataERKNS_10IdentifierEjPNS_6JSCellE
+__ZN3JSC9Structure16putSpecificValueERNS_12VMERKNS_10IdentifierEjPNS_6JSCellE
+__ZN3JSC24StructureTransitionTable3addERNS_12VMEPNS_9StructureE
+__ZN3JSC9Structure28addPropertyWithoutTransitionERNS_12VMERKNS_10IdentifierEjPNS_6JSCellE
__ZN3JSC8JSObject23allocatePropertyStorageEmm
__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEPPNS_10JSFunctionES9_
__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPFPvS2_E
__ZN3JSC10JSFunctionC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPFPvS2_E
-__ZN3JSC12JSGlobalData15getHostFunctionEPFPvPNS_9ExecStateEE
-__ZN3JSC9JITThunks16hostFunctionStubEPNS_12JSGlobalDataEPFPvPNS_9ExecStateEE
+__ZN3JSC12VM15getHostFunctionEPFPvPNS_9ExecStateEE
+__ZN3JSC9JITThunks16hostFunctionStubEPNS_12VMEPFPvPNS_9ExecStateEE
__ZN3WTF7HashMapIPFPvPN3JSC9ExecStateEENS2_4WeakINS2_16NativeExecutableEEENS_7PtrHashIS6_EENS_10HashTraitsIS6_EENSC_IS9_EEE3addERKS6_RKS9_
__ZN3WTF9HashTableIPFPvPN3JSC9ExecStateEESt4pairIS6_NS2_4WeakINS2_16NativeExecutableEEEENS_18PairFirstExtractorISB_EENS_7PtrHashIS6_EENS_14PairHashTraitsINS_10HashTraitsIS6_EENSH_ISA_EEEESI_E6expandEv
-__ZN3JSC3JIT27privateCompileCTINativeCallEN3WTF10PassRefPtrINS_14ExecutablePoolEEEPNS_12JSGlobalDataEPFPvPNS_9ExecStateEE
-__ZN3JSC16NativeExecutable6createERNS_12JSGlobalDataENS_21MacroAssemblerCodePtrEPFPvPNS_9ExecStateEES3_S8_
+__ZN3JSC3JIT27privateCompileCTINativeCallEN3WTF10PassRefPtrINS_14ExecutablePoolEEEPNS_12VMEPFPvPNS_9ExecStateEE
+__ZN3JSC16NativeExecutable6createERNS_12VMENS_21MacroAssemblerCodePtrEPFPvPNS_9ExecStateEES3_S8_
__ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_10JSFunctionEj
__ZN3JSC10JSFunction4nameEPNS_9ExecStateE
__ZN3JSC15ObjectPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC8JSObject17createInheritorIDERNS_12JSGlobalDataE
__ZN3JSC14ArrayPrototypeC1EPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC7JSArrayC2ERNS_12VMEPNS_9StructureE
__ZN3JSC15StringPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC15StringPrototypeC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC12StringObjectC2EPNS_9ExecStateEPNS_9StructureE
__ZN3JSC16BooleanPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC13BooleanObjectC2ERNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC13BooleanObjectC2ERNS_12VMEPNS_9StructureE
__ZN3JSC15NumberPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC12NumberObjectC2ERNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC12NumberObjectC2ERNS_12VMEPNS_9StructureE
__ZN3JSC13DatePrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC12DateInstanceC2EPNS_9ExecStateEPNS_9StructureE
__ZN3JSC12nonInlineNaNEv
__ZN3JSC15RegExpPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE
-__ZN3JSC6RegExp7compileEPNS_12JSGlobalDataE
+__ZN3JSC6RegExp6createEPNS_12VMERKNS_7UStringENS_11RegExpFlagsE
+__ZN3JSC6RegExp7compileEPNS_12VME
__ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc
__ZN3JSC4Yarr11YarrPattern7compileERKNS_7UStringE
__ZN3WTF6VectorIPN3JSC4Yarr18PatternAlternativeELm0EE14expandCapacityEm
__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE5parseEv
-__ZN3JSC4Yarr10jitCompileERNS0_11YarrPatternEPNS_12JSGlobalDataERNS0_13YarrCodeBlockE
+__ZN3JSC4Yarr10jitCompileERNS0_11YarrPatternEPNS_12VMERNS0_13YarrCodeBlockE
__ZN3JSC4Yarr13YarrGenerator13opCompileBodyEPNS0_18PatternDisjunctionE
__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EED1Ev
__ZN3JSC4Yarr13YarrGenerator20opCompileAlternativeEPNS0_18PatternAlternativeE
@@ -270,7 +269,7 @@ __ZN3WTF15deleteAllValuesIPN3JSC4Yarr18PatternDisjunctionELm4EEEvRKNS_6VectorIT_
__ZN3WTF15deleteAllValuesIPN3JSC4Yarr14CharacterClassELm0EEEvRKNS_6VectorIT_XT0_EEE
__ZN3JSC14ErrorPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE
-__ZN3JSC13ErrorInstanceC2EPNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC13ErrorInstanceC2EPNS_12VMEPNS_9StructureE
__ZN3JSC17ObjectConstructorC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEPNS_15ObjectPrototypeE
__ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEPNS_15ObjectPrototypeE
__ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
@@ -304,8 +303,8 @@ __ZN3JSC19SmallStringsStorageC2Ev
__ZN3JSC10JSONObjectC1EPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC14JSGlobalObject16addStaticGlobalsEPNS0_18GlobalPropertyInfoEi
__ZN3WTF7HashMapINS_6RefPtrINS_10StringImplEEEN3JSC16SymbolTableEntryENS4_17IdentifierRepHashENS_10HashTraitsIS3_EENS4_26SymbolTableIndexHashTraitsEE3addEPS2_RKS5_
-__ZN3JSC9Structure25changePrototypeTransitionERNS_12JSGlobalDataEPS0_NS_7JSValueE
-__ZN3JSC9Structure17copyPropertyTableERNS_12JSGlobalDataEPS0_
+__ZN3JSC9Structure25changePrototypeTransitionERNS_12VMEPS0_NS_7JSValueE
+__ZN3JSC9Structure17copyPropertyTableERNS_12VMEPS0_
__ZN3JSC14JSGlobalObject10globalExecEv
_JSGlobalContextRetain
__ZN3JSC14MachineThreads16addCurrentThreadEv
@@ -318,7 +317,7 @@ __ZNK14OpaqueJSString7ustringEv
__ZN3JSC7UStringC1EPKtj
__ZN3JSC13LiteralParser5Lexer3lexERNS1_18LiteralParserTokenE
__ZN3JSC13LiteralParser5parseENS0_11ParserStateE
-__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC7JSArrayC1ERNS_12VMEPNS_9StructureE
__ZN3WTF13StringBuilder6appendEPKtj
__ZN3WTF13StringBuilder19appendUninitializedEj
__ZN3WTF13StringBuilder14allocateBufferEPKtj
@@ -341,8 +340,8 @@ _JSContextGetGlobalObject
__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
_JSStringCreateWithUTF8CString
_JSObjectGetProperty
-__ZNK14OpaqueJSString10identifierEPN3JSC12JSGlobalDataE
-__ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
+__ZNK14OpaqueJSString10identifierEPN3JSC12VME
+__ZN3JSC10Identifier3addEPNS_12VMEPKti
__ZN3JSC14JSGlobalObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
_JSValueIsInstanceOfConstructor
__ZN3JSC16ArrayConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
@@ -361,10 +360,10 @@ __ZN3JSC4Heap9unprotectENS_7JSValueE
__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EERKT_
__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
__ZN3JSC10HandleHeap4growEv
-__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
+__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12VMEh
__ZN3JSC37DefaultGCActivityCallbackPlatformData7triggerEP16__CFRunLoopTimerPv
__ZN3JSC4Heap17collectAllGarbageEv
-__ZN3JSC12JSGlobalData23recompileAllJSFunctionsEv
+__ZN3JSC12VM23recompileAllJSFunctionsEv
__ZN3JSC4Heap5resetENS0_11SweepToggleE
__ZN3JSC4Heap9markRootsEv
__ZN3JSC14MachineThreads23gatherConservativeRootsERNS_17ConservativeRootsEPv
@@ -440,20 +439,20 @@ __ZN3WTF6strtodEPKcPPc
__ZN3WTF10StringImpl22containsOnlyWhitespaceEv
__ZN3WTF10StringImpl11reverseFindEPS0_j
__ZN3WTF17equalIgnoringCaseEPNS_10StringImplES1_
-__ZN3JSC12JSGlobalData12createLeakedENS_8HeapTypeE
-__ZN3JSC24JSObjectWithGlobalObjectC2ERNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_9StructureE
+__ZN3JSC12VM12createLeakedENS_8HeapTypeE
+__ZN3JSC24JSObjectWithGlobalObjectC2ERNS_12VMEPNS_14JSGlobalObjectEPNS_9StructureE
__ZN3JSC8evaluateEPNS_9ExecStateEPNS_14ScopeChainNodeERKNS_10SourceCodeENS_7JSValueE
__ZN3JSC17ProgramExecutableC1EPNS_9ExecStateERKNS_10SourceCodeE
__ZN3JSC11Interpreter7executeEPNS_17ProgramExecutableEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectE
-__ZN3JSC24DynamicGlobalObjectScopeC1ERNS_12JSGlobalDataEPNS_14JSGlobalObjectE
+__ZN3JSC24DynamicGlobalObjectScopeC1ERNS_12VMEPNS_14JSGlobalObjectE
__ZN3JSC19ExecutableAllocator19underMemoryPressureEv
-__ZN3JSC12JSGlobalData14resetDateCacheEv
+__ZN3JSC12VM14resetDateCacheEv
__ZN3JSC17ProgramExecutable15compileInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE
__ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE
-__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPNS_18FunctionParametersENS_18JSParserStrictnessENS_12JSParserModeEPiPNS_7UStringE
+__ZN3JSC6Parser5parseEPNS_12VMEPNS_18FunctionParametersENS_18JSParserStrictnessENS_12JSParserModeEPiPNS_7UStringE
__ZN3JSC5Lexer7setCodeERKNS_10SourceCodeERNS_11ParserArenaE
-__ZN3JSC7jsParseEPNS_12JSGlobalDataEPNS_18FunctionParametersENS_18JSParserStrictnessENS_12JSParserModeEPKNS_10SourceCodeE
-__ZN3JSC8JSParserC2EPNS_5LexerEPNS_12JSGlobalDataEPNS_18FunctionParametersEbbPNS_14SourceProviderE
+__ZN3JSC7jsParseEPNS_12VMEPNS_18FunctionParametersENS_18JSParserStrictnessENS_12JSParserModeEPKNS_10SourceCodeE
+__ZN3JSC8JSParserC2EPNS_5LexerEPNS_12VMEPNS_18FunctionParametersEbbPNS_14SourceProviderE
__ZN3JSC8JSParser9pushScopeEv
__ZN3JSC8JSParser4nextENS_5Lexer7LexTypeE
__ZN3JSC5Lexer3lexEPNS_11JSTokenDataEPNS_11JSTokenInfoENS0_7LexTypeEb
@@ -465,11 +464,10 @@ __ZN3JSC8JSParser14parseStatementINS_10ASTBuilderEEENT_9StatementERS3_RPKNS_10Id
__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEEEPNS3_INS5_IPNS_16FunctionBodyNodeELm0EEEEEjiiRNS4_7HashSetINS4_6RefPtrINS4_10StringImplEEENS_17IdentifierRepHashENS4_10HashTraitsISM_EEEE
__ZN3JSC11ParserArenaD1Ev
__ZN3JSC5Lexer5clearEv
-__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji
-__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS9_IPNS_16FunctionBodyNodeELm0EEERNS8_7HashSetINS8_6RefPtrINS8_10StringImplEEENS_17IdentifierRepHashENS8_10HashTraitsISO_EEEEji
+__ZN3JSC11ProgramNode6createEPNS_12VMEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji
+__ZN3JSC9ScopeNodeC2EPNS_12VMERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS9_IPNS_16FunctionBodyNodeELm0EEERNS8_7HashSetINS8_6RefPtrINS8_10StringImplEEENS_17IdentifierRepHashENS8_10HashTraitsISO_EEEEji
__ZN3JSC11ParserArena14derefWithArenaEN3WTF10PassRefPtrINS_21ParserArenaRefCountedEEE
__ZN3JSC11ParserArena10removeLastEv
-__ZN3JSC13StatementNode6setLocEii
__ZN3JSC11ParserArena5resetEv
__ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
__ZN3JSC9CodeBlockC2EPNS_16ScriptExecutableENS_8CodeTypeEPNS_14JSGlobalObjectEN3WTF10PassRefPtrINS_14SourceProviderEEEjPNS6_7HashMapINS6_6RefPtrINS6_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS6_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEb
@@ -516,7 +514,7 @@ __ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12JSStackE
__ZN3JSC12JSStack15setGlobalObjectEPNS_14JSGlobalObjectE
_ctiTrampoline
__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE6appendIS2_EEvRKT_
-__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
+__ZNK3JSC9HashTable11createTableEPNS_12VME
__ZN3JSC8JSParser31parseExpressionOrLabelStatementINS_10ASTBuilderEEENT_9StatementERS3_
__ZN3JSC5Lexer16nextTokenIsColonEv
__ZN3JSC8JSParser15parseExpressionINS_10ASTBuilderEEENT_10ExpressionERS3_
@@ -562,9 +560,9 @@ __ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC11makeUStringIPKcNS_7UStringEEES3_T_T0_
__ZN3WTF13tryMakeStringIPKcN3JSC7UStringEEENS_10PassRefPtrINS_10StringImplEEET_T0_
__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC13ErrorInstance6createEPNS_12JSGlobalDataEPNS_9StructureERKNS_7UStringE
-__ZN3JSC13ErrorInstanceC2EPNS_12JSGlobalDataEPNS_9StructureERKNS_7UStringE
-__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataENS_16ReturnAddressPtrERS2_
+__ZN3JSC13ErrorInstance6createEPNS_12VMEPNS_9StructureERKNS_7UStringE
+__ZN3JSC13ErrorInstanceC2EPNS_12VMEPNS_9StructureERKNS_7UStringE
+__ZN3JSCL23returnToThrowTrampolineEPNS_12VMENS_16ReturnAddressPtrERS2_
_ctiVMThrowTrampoline
_cti_vm_throw
__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEj
@@ -613,14 +611,14 @@ __ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
__ZN3JSC3JIT17emit_op_new_arrayEPNS_11InstructionE
_cti_op_new_array
-__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureERKNS_7ArgListE
+__ZN3JSC7JSArrayC1ERNS_12VMEPNS_9StructureERKNS_7ArgListE
__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE0ELb0ENS_10ASTBuilderEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_
__ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE0ENS_13SyntaxCheckerEEENT0_14SourceElementsERS4_
__ZN3JSC8JSParser14parseStatementINS_13SyntaxCheckerEEENT_9StatementERS3_RPKNS_10IdentifierE
__ZN3JSC8JSParser15parseExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_
__ZN3JSC8JSParser25parseAssignmentExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_
__ZN3JSC8JSParser21parseMemberExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEb
+__ZN3JSC16FunctionBodyNode6createEPNS_12VMEb
__ZN3JSC8JSParser5ScopeD1Ev
__ZN3JSC5Lexer10sourceCodeEiii
__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeERKNS_10IdentifierE
@@ -630,7 +628,7 @@ __ZNK3JSC14ExpressionNode10isLocationEv
__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
-__ZN3JSC18FunctionExecutableC1EPNS_12JSGlobalDataERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii
+__ZN3JSC18FunctionExecutableC1EPNS_12VMERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii
__ZN3WTF6VectorIN3JSC12WriteBarrierINS1_18FunctionExecutableEEELm0EE14expandCapacityEm
__ZN3JSC17BytecodeGenerator8emitCallEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj
__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_RNS_13CallArgumentsEjjj
@@ -647,7 +645,7 @@ __ZN3JSC18FunctionExecutable22compileForCallInternalEPNS_9ExecStateEPNS_14ScopeC
__ZN3JSC6Parser5parseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE
__ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE1ENS_10ASTBuilderEEENT0_14SourceElementsERS4_
__ZN3JSC8JSParser19parseThrowStatementINS_10ASTBuilderEEENT_9StatementERS3_
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPS0_Lm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISK_EEEERKNS_10SourceCodeEji
+__ZN3JSC16FunctionBodyNode6createEPNS_12VMEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPS0_Lm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISK_EEEERKNS_10SourceCodeEji
__ZN3JSC17BytecodeGeneratorC1EPNS_16FunctionBodyNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EEC1Ev
@@ -663,7 +661,7 @@ __ZN3JSC11JITStubCall11addArgumentEjNS_12X86Registers10RegisterIDE
__ZN3JSC3JIT11emit_op_retEPNS_11InstructionE
_cti_op_throw
__ZNK3JSC8JSString8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE
-__ZN3JSC12StringObjectC1ERNS_12JSGlobalDataEPNS_9StructureEPNS_8JSStringE
+__ZN3JSC12StringObjectC1ERNS_12VMEPNS_9StructureEPNS_8JSStringE
__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
@@ -705,7 +703,7 @@ __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE4initEPNS_9ExecStateE
__ZN13OpaqueJSClass9prototypeEPN3JSC9ExecStateE
__ZN13OpaqueJSClass11contextDataEPN3JSC9ExecStateE
__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6expandEv
-__ZN24OpaqueJSClassContextDataC2ERN3JSC12JSGlobalDataEP13OpaqueJSClass
+__ZN24OpaqueJSClassContextDataC2ERN3JSC12VMEP13OpaqueJSClass
_JSClassRelease
_JSObjectSetProperty
__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
@@ -719,7 +717,6 @@ __ZNK3JSC14ExpressionNode13isResolveNodeEv
__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
-__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator8newLabelEv
__ZNK3JSC14ExpressionNode26hasConditionContextCodegenEv
__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
@@ -776,7 +773,7 @@ __ZN3WTF6VectorINS_6RefPtrINS_10StringImplEEELm0EE14expandCapacityEm
__ZN3JSC19SourceProviderCache3addEiN3WTF10PassOwnPtrINS_23SourceProviderCacheItemEEEj
__ZN3WTF9HashTableIiSt4pairIiPN3JSC23SourceProviderCacheItemEENS_18PairFirstExtractorIS5_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIiEENSB_IS4_EEEESC_E6expandEv
__ZN3WTF6VectorIPN3JSC16FunctionBodyNodeELm0EE15reserveCapacityEm
-__ZN3JSC8JSObject12removeDirectERNS_12JSGlobalDataERKNS_10IdentifierE
+__ZN3JSC8JSObject12removeDirectERNS_12VMERKNS_10IdentifierE
__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E13isEmptyBucketERKS7_
__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E6expandEv
__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E6rehashEi
@@ -794,7 +791,7 @@ __ZNK3JSC21UStringSourceProvider4dataEv
__ZN3JSC8JSParser16declareParameterEPKNS_10IdentifierE
__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC9Structure22materializePropertyMapERNS_12JSGlobalDataE
+__ZN3JSC9Structure22materializePropertyMapERNS_12VME
__ZNK3JSC11ResolveNode10isLocationEv
__ZNK3JSC11ResolveNode13isResolveNodeEv
__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierEi
@@ -892,15 +889,15 @@ __ZN3JSC3JIT11emit_op_jmpEPNS_11InstructionE
__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE
__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_13TrustedImmPtrE
__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii
-__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE
+__ZN3JSC3JIT15emit_op_incEPNS_11InstructionE
__ZN3JSC3JIT16emitTimeoutCheckEv
__ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE
__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC9JITThunks7ctiStubEPNS_12JSGlobalDataEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE
-__ZN3WTF9HashTableIPFN3JSC21MacroAssemblerCodePtrEPNS1_12JSGlobalDataEPNS1_14ExecutablePoolEESt4pairIS8_S2_ENS_18PairFirstExtractorISA_EENS_7PtrHashIS8_EENS_14PairHashTraitsINS_10HashTraitsIS8_EENSG_IS2_EEEESH_E6expandEv
-__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC9JITThunks7ctiStubEPNS_12VMEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE
+__ZN3WTF9HashTableIPFN3JSC21MacroAssemblerCodePtrEPNS1_12VMEPNS1_14ExecutablePoolEESt4pairIS8_S2_ENS_18PairFirstExtractorISA_EENS_7PtrHashIS8_EENS_14PairHashTraitsINS_10HashTraitsIS8_EENSG_IS2_EEEESH_E6expandEv
+__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12VMEPNS_14ExecutablePoolE
__ZN3JSC21roundUpAllocationSizeEmm
-__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT19emitSlow_op_incEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC12X86Assembler7movq_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE
__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_
@@ -983,7 +980,7 @@ __ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12JSStackEPNS_8RegisterEii
__ZN3JSC14EvalExecutableC1EPNS_9ExecStateERKNS_10SourceCodeEb
__ZN3JSC14EvalExecutable15compileInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE
__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE
-__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji
+__ZN3JSC8EvalNode6createEPNS_12VMEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji
__ZN3JSC14ScopeChainNode10localDepthEv
__ZN3JSC17BytecodeGeneratorC1EPNS_8EvalNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
@@ -1048,13 +1045,13 @@ __ZN3JSC9JITThunks15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAdd
__ZN3JSC3JIT33privateCompilePatchGetArrayLengthENS_16ReturnAddressPtrE
__ZNK3JSC8JSObject24getPropertySpecificValueEPNS_9ExecStateERKNS_10IdentifierERPNS_6JSCellE
__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_11FunctionPtrE
-__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12JSGlobalDataE
-__ZN3JSC3JIT20patchMethodCallProtoERNS_12JSGlobalDataEPNS_9CodeBlockERNS_18MethodCallLinkInfoEPNS_10JSFunctionEPNS_9StructureEPNS_8JSObjectENS_16ReturnAddressPtrE
+__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12VME
+__ZN3JSC3JIT20patchMethodCallProtoERNS_12VMEPNS_9CodeBlockERNS_18MethodCallLinkInfoEPNS_10JSFunctionEPNS_9StructureEPNS_8JSObjectENS_16ReturnAddressPtrE
__ZN3JSC9JITThunks15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_15PutPropertySlotEPNS_17StructureStubInfoEb
_cti_op_get_by_id_generic
_cti_op_put_by_id_generic
-__ZN3JSC14StructureChainC1ERNS_12JSGlobalDataEPNS_9StructureES4_
-__ZN3JSC14StructureChainC2ERNS_12JSGlobalDataEPNS_9StructureES4_
+__ZN3JSC14StructureChainC1ERNS_12VMEPNS_9StructureES4_
+__ZN3JSC14StructureChainC2ERNS_12VMEPNS_9StructureES4_
__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmRKNS_10IdentifierERKNS_12PropertySlotEmNS_16ReturnAddressPtrEPNS_9ExecStateE
__ZN3JSC3JIT13testPrototypeENS_7JSValueERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListE
__ZN3JSC3JIT22compileGetDirectOffsetEPNS_8JSObjectENS_12X86Registers10RegisterIDEm
@@ -1119,7 +1116,7 @@ __ZN3JSC23MacroAssemblerX86Common4moveENS_12X86Registers10RegisterIDES2_
__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateE
__ZNK3JSC17RegExpConstructor14arrayOfMatchesEPNS_9ExecStateE
__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
-__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureEjNS_17ArrayCreationModeE
+__ZN3JSC7JSArrayC2ERNS_12VMEPNS_9StructureEjNS_17ArrayCreationModeE
__ZN3JSC7JSArray15setSubclassDataEPv
__ZN3JSC18RegExpMatchesArrayD1Ev
__ZNK3JSC7JSArray12subclassDataEv
@@ -1149,7 +1146,7 @@ __ZN3WTF10StringImpl4findEPFbtEj
__ZN3WTF10StringImpl4findEPKcj
__ZN3WTF6String26fromUTF8WithLatin1FallbackEPKcm
__ZN3WTF10fastStrDupEPKc
-__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPN3WTF10StringImplE
+__ZN3JSC10Identifier11addSlowCaseEPNS_12VMEPN3WTF10StringImplE
_JSStringRetain
___initializeScavenger_block_invoke_1
__ZN3WTF23waitForThreadCompletionEj
@@ -1158,7 +1155,7 @@ _JSObjectCopyPropertyNames
__ZN3JSC8JSObject16copyBackingStoreEPNS_6JSCellERNS_11CopyVisitorE
__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3JSC9Structure16getPropertyNamesERNS_12JSGlobalDataERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC9Structure16getPropertyNamesERNS_12VMERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC9ExecState20objectPrototypeTableEPS0_
_JSPropertyNameArrayGetCount
_JSPropertyNameArrayRelease
@@ -1204,7 +1201,7 @@ __ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateE
-__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
+__ZN3JSC11jsSubstringEPNS_12VMERKNS_7UStringEjj
__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE
__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE
__ZN3JSC10ASTBuilder11makeSubNodeEPNS_14ExpressionNodeES2_b
@@ -1272,7 +1269,6 @@ __ZN3JSC3JIT17emit_op_nstricteqEPNS_11InstructionE
__ZN3JSC3JIT21emitSlow_op_nstricteqEPNS_11InstructionERPNS_13SlowCaseEntryE
_cti_op_nstricteq
__ZN3JSC14LogicalNotNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b
-__ZN3JSC3JIT18emit_op_jmp_scopesEPNS_11InstructionE
_cti_op_negate
__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateE
__ZN3WTF15ThreadConditionD1Ev
@@ -1306,8 +1302,8 @@ __ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE
__ZN3JSC12hasErrorInfoEPNS_9ExecStateEPNS_8JSObjectE
__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEj
__ZN3JSC12addErrorInfoEPNS_9ExecStateEPNS_8JSObjectEiRKNS_10SourceCodeE
-__ZN3JSC12addErrorInfoEPNS_12JSGlobalDataEPNS_8JSObjectEiRKNS_10SourceCodeE
-__ZN3JSC8JSObject17putWithAttributesEPNS_12JSGlobalDataERKNS_10IdentifierENS_7JSValueEj
+__ZN3JSC12addErrorInfoEPNS_12VMEPNS_8JSObjectEiRKNS_10SourceCodeE
+__ZN3JSC8JSObject17putWithAttributesEPNS_12VMERKNS_10IdentifierENS_7JSValueEj
_cti_op_push_new_scope
__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
@@ -1363,21 +1359,21 @@ __ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE
_cti_op_load_varargs
__ZN3WTF13tryFastCallocEmm
__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE
-__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE
-__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE
-_cti_op_pre_dec
+__ZN3JSC3JIT15emit_op_decEPNS_11InstructionE
+__ZN3JSC3JIT19emitSlow_op_decEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_dec
__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j
__ZN3JSC5Lexer19getUnicodeCharacterEv
__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateE
-__ZN3JSC12JSGlobalData15getHostFunctionEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrEPS0_PNS_14ExecutablePoolEE
-__ZN3JSC9JITThunks16hostFunctionStubEPNS_12JSGlobalDataEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE
-__ZN3JSC18sqrtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC12VM15getHostFunctionEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrEPS0_PNS_14ExecutablePoolEE
+__ZN3JSC9JITThunks16hostFunctionStubEPNS_12VMEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE
+__ZN3JSC18sqrtThunkGeneratorEPNS_12VMEPNS_14ExecutablePoolE
__ZN3JSC19SpecializedThunkJIT8finalizeENS_21MacroAssemblerCodePtrE
__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPNS_16NativeExecutableE
__ZN3JSC10JSFunctionC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPNS_16NativeExecutableE
__ZN3JSC3JIT11emit_op_notEPNS_11InstructionE
__ZN3JSC3JIT15emitSlow_op_notEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC17powThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC17powThunkGeneratorEPNS_12VMEPNS_14ExecutablePoolE
__ZN3JSC12X86Assembler7cmpl_imEiiNS_12X86Registers10RegisterIDE
__ZN3JSC23MacroAssemblerX86Common26branchConvertDoubleToInt32ENS_12X86Registers13XMMRegisterIDENS1_10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListES2_
__ZN3JSC19SpecializedThunkJIT11returnInt32ENS_12X86Registers10RegisterIDE
@@ -1391,8 +1387,8 @@ _cti_op_del_by_id
__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC17ObjectConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC9Structure27despecifyFunctionTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierE
-__ZN3JSC13PropertyTableC2ERNS_12JSGlobalDataEPNS_6JSCellERKS0_
+__ZN3JSC9Structure27despecifyFunctionTransitionERNS_12VMEPS0_RKNS_10IdentifierE
+__ZN3JSC13PropertyTableC2ERNS_12VMEPNS_6JSCellERKS0_
__ZNK3WTF6String6toUIntEPb
__ZN3WTF10StringImpl6toUIntEPb
__ZN3WTF16charactersToUIntEPKtmPb
@@ -1437,9 +1433,7 @@ __ZN3WTF10StringImpl7replaceEtPS0_
__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_16ReturnAddressPtrEb
_cti_op_put_by_id_fail
__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_
-__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE
-__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSCL23createPrototypePropertyERNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_10JSFunctionE
+__ZN3JSCL23createPrototypePropertyERNS_12VMEPNS_14JSGlobalObjectEPNS_10JSFunctionE
__ZNK3JSC8NullNode6isNullEv
__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE
_cti_op_convert_this
@@ -1473,7 +1467,6 @@ __ZN3WTF22charactersToUIntStrictEPKtmPbi
__ZNK3WTF6String5upperEv
__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueE
-_cti_op_jmp_scopes
__ZNK3WTF6String6latin1Ev
__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_RKNS_10IdentifierERKNS_12PropertySlotEmPNS_9ExecStateE
__ZN3JSC3JIT15emit_op_eq_nullEPNS_11InstructionE
@@ -1482,7 +1475,7 @@ __ZN3WTF7Unicode18equalUTF16WithUTF8EPKtS2_PKcS4_
__ZN3WTF11emptyStringEv
__ZN3WTF6String6numberEj
__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureEjNS_17ArrayCreationModeE
+__ZN3JSC7JSArrayC1ERNS_12VMEPNS_9StructureEjNS_17ArrayCreationModeE
__ZN3JSC10Identifier4fromEPNS_9ExecStateEj
__ZN3JSC3JIT22compileGetDirectOffsetENS_12X86Registers10RegisterIDES2_PNS_9StructureEm
__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE15reserveCapacityEm
@@ -1498,8 +1491,8 @@ __ZN3JSC4Yarr13YarrGenerator29generateAssertionWordBoundaryEm
__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_12X86Registers10RegisterIDES3_ii
__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateE
__ZN3JSC17StringConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC26fromCharCodeThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
-__ZN3JSCL12charToStringERNS_19SpecializedThunkJITEPNS_12JSGlobalDataENS_12X86Registers10RegisterIDES5_S5_
+__ZN3JSC26fromCharCodeThunkGeneratorEPNS_12VMEPNS_14ExecutablePoolE
+__ZN3JSCL12charToStringERNS_19SpecializedThunkJITEPNS_12VMENS_12X86Registers10RegisterIDES5_S5_
__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateE
__ZNK3JSC8JSObject14isGlobalObjectEv
__ZNK3WTF6String16removeCharactersEPFbtE
@@ -1522,12 +1515,12 @@ __ZN3JSC3JIT18emit_op_get_pnamesEPNS_11InstructionE
__ZN3JSC3JIT20emit_op_get_by_pnameEPNS_11InstructionE
__ZN3JSC3JIT18emit_op_next_pnameEPNS_11InstructionE
__ZN3JSC3JIT24emitSlow_op_get_by_pnameEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC9Structure22toDictionaryTransitionERNS_12JSGlobalDataEPS0_NS0_14DictionaryKindE
+__ZN3JSC9Structure22toDictionaryTransitionERNS_12VMEPS0_NS0_14DictionaryKindE
_cti_op_get_pnames
__ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateEPNS_8JSObjectE
__ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm
_cti_has_property
-__ZN3JSC9Structure26flattenDictionaryStructureERNS_12JSGlobalDataEPNS_8JSObjectE
+__ZN3JSC9Structure26flattenDictionaryStructureERNS_12VMEPNS_8JSObjectE
_JSValueIsObjectOfClass
__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
_JSValueCreateJSONString
@@ -1602,7 +1595,7 @@ __ZN3JSC11Stringifier18appendQuotedStringERNS_14UStringBuilderERKNS_7UStringE
__ZN3JSC7UStringC1EPKcj
_JSObjectGetPrivateProperty
_JSObjectSetPrivateProperty
-__ZN3JSC20JSCallbackObjectData18setPrivatePropertyERNS_12JSGlobalDataEPNS_6JSCellERKNS_10IdentifierENS_7JSValueE
+__ZN3JSC20JSCallbackObjectData18setPrivatePropertyERNS_12VMEPNS_6JSCellERKNS_10IdentifierENS_7JSValueE
__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC12WriteBarrierINS5_7UnknownEEEENS_18PairFirstExtractorIS9_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSE_IS8_EEEESF_E6rehashEi
_JSObjectDeletePrivateProperty
__ZN3JSC4Yarr18PatternDisjunction17addNewAlternativeEv
@@ -1622,14 +1615,10 @@ __ZN3WTF6VectorItLm64EE18tryReserveCapacityEm
__ZN3JSC16globalFuncEscapeEPNS_9ExecStateE
__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_
-__ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE
-__ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC3JIT22emit_op_loop_if_lesseqEPNS_11InstructionE
-__ZN3JSC3JIT26emitSlow_op_loop_if_lesseqEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE
__ZN3JSC9ExecState19arrayPrototypeTableEPS0_
-__ZN3JSC20charAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC20charAtThunkGeneratorEPNS_12VMEPNS_14ExecutablePoolE
__ZN3JSCL14stringCharLoadERNS_19SpecializedThunkJITE
__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateE
__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEm
@@ -1671,7 +1660,7 @@ __ZN3JSC3JIT14emit_op_rshiftEPNS_11InstructionE
__ZN3JSC3JIT18emitSlow_op_rshiftEPNS_11InstructionERPNS_13SlowCaseEntryE
_cti_op_put_by_id_transition_realloc
__ZNK3WTF6String5splitEtbRNS_6VectorIS0_Lm0EEE
-__ZN3JSC24charCodeAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC24charCodeAtThunkGeneratorEPNS_12VMEPNS_14ExecutablePoolE
_cti_op_get_by_val_string
__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
__ZN3JSCL21callStringConstructorEPNS_9ExecStateE
@@ -1681,10 +1670,10 @@ __ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10Identifier
__ZN3JSC13jsAddSlowCaseEPNS_9ExecStateENS_7JSValueES2_
__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
_cti_op_get_by_id_getter_stub
-__ZN3JSC9Structure24removePropertyTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierERm
+__ZN3JSC9Structure24removePropertyTransitionERNS_12VMEPS0_RKNS_10IdentifierERm
__ZN3JSC9Structure6removeERKNS_10IdentifierE
__ZN3WTF6VectorIjLm0EE14expandCapacityEm
-__ZN3JSC9Structure31removePropertyWithoutTransitionERNS_12JSGlobalDataERKNS_10IdentifierE
+__ZN3JSC9Structure31removePropertyWithoutTransitionERNS_12VMERKNS_10IdentifierE
__ZN3JSC12GetterSetter13visitChildrenERNS_9MarkStackE
__ZN3JSC9Arguments13visitChildrenERNS_9MarkStackE
__ZN3JSC14JSGlobalObject17WeakMapsFinalizer8finalizeENS_6HandleINS_7UnknownEEEPv
@@ -1707,13 +1696,13 @@ __ZN3JSC8JSParser21parseDoWhileStatementINS_13SyntaxCheckerEEENT_9StatementERS3_
__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateE
__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateE
__ZN3JSC17ProgramExecutable13visitChildrenERNS_9MarkStackE
-__ZN3JSC12JSGlobalData18createContextGroupENS_8HeapTypeE
-__ZN3JSC12JSGlobalData22clearBuiltinStructuresEv
+__ZN3JSC12VM18createContextGroupENS_8HeapTypeE
+__ZN3JSC12VM22clearBuiltinStructuresEv
__ZN3JSC4Heap7destroyEv
__ZN3JSC9JITThunks22clearHostFunctionStubsEv
__ZN3JSC11MarkedSpace7destroyEv
-__ZN3JSC12JSGlobalDataD1Ev
-__ZN3JSC12JSGlobalDataD2Ev
+__ZN3JSC12VMD1Ev
+__ZN3JSC12VMD2Ev
__ZN3JSC12JSStackD1Ev
__ZN3JSC12JSStackD2Ev
__ZNK3JSC9HashTable11deleteTableEv
@@ -1732,12 +1721,12 @@ __ZN3JSC25DefaultGCActivityCallbackD0Ev
__ZN3JSC9JITThunksD1Ev
__ZN3JSC12SmallStringsD1Ev
__ZN13OpaqueJSClass26createNoAutomaticPrototypeEPK17JSClassDefinition
-__ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEEC2ERNS_12JSGlobalDataEP13OpaqueJSClassPNS_9StructureE
+__ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEEC2ERNS_12VMEP13OpaqueJSClassPNS_9StructureE
__ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEE4initEPNS_9ExecStateE
__ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN13OpaqueJSClass12staticValuesEPN3JSC9ExecStateE
__ZN13OpaqueJSClass15staticFunctionsEPN3JSC9ExecStateE
-__ZN3JSC14JSGlobalObject14resetPrototypeERNS_12JSGlobalDataENS_7JSValueE
+__ZN3JSC14JSGlobalObject14resetPrototypeERNS_12VMENS_7JSValueE
_JSReportExtraMemoryCost
_JSValueIsObject
_JSValueMakeNull
@@ -1786,7 +1775,6 @@ __ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateE
__ZNK3JSC12DateInstance26calculateGregorianDateTimeEPNS_9ExecStateE
__ZN3JSC21msToGregorianDateTimeEPNS_9ExecStateEdbRNS_17GregorianDateTimeE
__ZN3JSCL12getDSTOffsetEPNS_9ExecStateEdd
-__ZN3WTF18calculateDSTOffsetEdd
__ZN3WTF18dateToDaysFrom1970Eiii
__ZN3JSC10formatDateERKNS_17GregorianDateTimeERA100_c
__ZN3JSC10formatTimeERKNS_17GregorianDateTimeERA100_c
@@ -1825,9 +1813,9 @@ __ZNK3JSC18PropertyDescriptor8writableEv
__ZNK3JSC18PropertyDescriptor10enumerableEv
__ZNK3JSC18PropertyDescriptor12configurableEv
__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
-__ZN3JSC3JIT19emit_op_to_jsnumberEPNS_11InstructionE
-__ZN3JSC3JIT23emitSlow_op_to_jsnumberEPNS_11InstructionERPNS_13SlowCaseEntryE
-_cti_op_to_jsnumber
+__ZN3JSC3JIT19emit_op_to_numberEPNS_11InstructionE
+__ZN3JSC3JIT23emitSlow_op_to_numberEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_to_number
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toNumberEPNS_9ExecStateE
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE9classNameEv
__ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toStringEPNS_9ExecStateE
@@ -1842,18 +1830,18 @@ _JSObjectHasProperty
_JSObjectGetPrototype
__ZN3JSC8JSObject15unwrappedObjectEv
__ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC12JSGlobalData6createENS_8HeapTypeE
+__ZN3JSC12VM6createENS_8HeapTypeE
__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_10JSFunctionEj
-__ZN3JSC12JSGlobalData13startSamplingEv
+__ZN3JSC12VM13startSamplingEv
__ZN3JSC11Interpreter13startSamplingEv
__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateE
__ZN3JSC21gregorianDateTimeToMSEPNS_9ExecStateERKNS_17GregorianDateTimeEdb
__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateE
-__ZN3JSC12JSGlobalData12stopSamplingEv
+__ZN3JSC12VM12stopSamplingEv
__ZN3JSC11Interpreter12stopSamplingEv
__ZN3WTF9HashTableIjSt4pairIjN3JSC12WriteBarrierINS2_7UnknownEEEENS_18PairFirstExtractorIS6_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSC_IS5_EEEESD_E6rehashEi
-__ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
+__ZN3JSC12VM14dumpSampleDataEPNS_9ExecStateE
__ZN3JSC11Interpreter14dumpSampleDataEPNS_9ExecStateE
__ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
__ZN3JSCL20callArrayConstructorEPNS_9ExecStateE
@@ -1861,15 +1849,15 @@ __ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE
__ZN3JSCL21callNumberConstructorEPNS_9ExecStateE
__ZN3JSCL28numberConstructorPosInfinityEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
_cti_op_mod
-__ZN3JSC3JIT13linkConstructEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12JSGlobalDataE
+__ZN3JSC3JIT13linkConstructEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12VME
__ZN3JSC14EvalExecutable13visitChildrenERNS_9MarkStackE
__ZN3JSC17NumberConstructor16getConstructDataERNS_13ConstructDataE
__ZN3JSCL30constructWithNumberConstructorEPNS_9ExecStateE
-__ZN3JSC12NumberObjectC1ERNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC12NumberObjectC1ERNS_12VMEPNS_9StructureE
__ZN3JSC18BooleanConstructor16getConstructDataERNS_13ConstructDataE
__ZN3JSCL31constructWithBooleanConstructorEPNS_9ExecStateE
__ZN3JSC16constructBooleanEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC13BooleanObjectC1ERNS_12JSGlobalDataEPNS_9StructureE
+__ZN3JSC13BooleanObjectC1ERNS_12VMEPNS_9StructureE
__ZN3JSC13BooleanObjectD1Ev
__ZN3JSC9ExecState21arrayConstructorTableEPS0_
__ZN3JSC17FunctionPrototype11getCallDataERNS_8CallDataE
@@ -1940,7 +1928,7 @@ __ZN3JSC15globalFuncIsNaNEPNS_9ExecStateE
_cti_op_is_object
__ZN3JSC14jsIsObjectTypeENS_7JSValueE
__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateE
-_cti_op_pre_inc
+_cti_op_inc
__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateE
__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateE
__ZN3JSC7JSArray3popEv
@@ -1980,8 +1968,6 @@ __ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
__ZN3JSC15DateConstructor11getCallDataERNS_8CallDataE
__ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
-_cti_op_post_inc
-_cti_op_post_dec
__ZN3JSC10ASTBuilder18makeBitwiseNotNodeEPNS_14ExpressionNodeE
__ZN3JSC3JIT14emit_op_bitnotEPNS_11InstructionE
__ZN3JSC3JIT18emitSlow_op_bitnotEPNS_11InstructionERPNS_13SlowCaseEntryE
@@ -2196,7 +2182,7 @@ __ZN3JSCL25arrayProtoFuncLastIndexOfEPNS_9ExecStateE
__ZN3WTF20equalIgnoringNullityEPNS_10StringImplES1_
_cti_op_get_by_id_array_fail
__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12JSGlobalData10ClientDataD2Ev
+__ZN3JSC12VM10ClientDataD2Ev
__ZN3JSC8DebuggerD2Ev
__ZN3WTF14ThreadSpecificINS_13WTFThreadDataEE7destroyEPv
__ZN3WTF13WTFThreadDataD1Ev
@@ -2213,7 +2199,7 @@ __ZNK3JSC4Heap11objectCountEv
__ZNK3JSC11MarkedSpace11objectCountEv
__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
-__ZN3JSC9Structure22getterSetterTransitionERNS_12JSGlobalDataEPS0_
+__ZN3JSC9Structure22getterSetterTransitionERNS_12VMEPS0_
__ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateE
__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateE
__ZNK3JSC7ArgList8getSliceEiRS0_
@@ -2304,7 +2290,6 @@ __ZN3JSCL35createDescriptorForThrowingPropertyEPNS_9ExecStateERNS_18PropertyDesc
__ZN3JSC20StrictEvalActivationD1Ev
__ZN3JSC27StrictModeTypeErrorFunctionD1Ev
__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
-_cti_op_loop_if_lesseq
__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E
__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E
__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDEi
@@ -2339,17 +2324,17 @@ __ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
__ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateE
__ZN3WTF6VectorIN3JSC8JSParser14ScopeLabelInfoELm2EE14expandCapacityEm
__ZN3JSCL34objectConstructorPreventExtensionsEPNS_9ExecStateE
-__ZN3JSC10JSFunction17preventExtensionsERNS_12JSGlobalDataE
-__ZN3JSC8JSObject17preventExtensionsERNS_12JSGlobalDataE
-__ZN3JSC9Structure27preventExtensionsTransitionERNS_12JSGlobalDataEPS0_
+__ZN3JSC10JSFunction17preventExtensionsERNS_12VME
+__ZN3JSC8JSObject17preventExtensionsERNS_12VME
+__ZN3JSC9Structure27preventExtensionsTransitionERNS_12VMEPS0_
__ZN3JSCL21objectConstructorSealEPNS_9ExecStateE
-__ZN3JSC8JSObject4sealERNS_12JSGlobalDataE
-__ZN3JSC9Structure8isSealedERNS_12JSGlobalDataE
-__ZN3JSC9Structure14sealTransitionERNS_12JSGlobalDataEPS0_
+__ZN3JSC8JSObject4sealERNS_12VME
+__ZN3JSC9Structure8isSealedERNS_12VME
+__ZN3JSC9Structure14sealTransitionERNS_12VMEPS0_
__ZN3JSCL23objectConstructorFreezeEPNS_9ExecStateE
-__ZN3JSC8JSObject6freezeERNS_12JSGlobalDataE
-__ZN3JSC9Structure8isFrozenERNS_12JSGlobalDataE
-__ZN3JSC9Structure16freezeTransitionERNS_12JSGlobalDataEPS0_
+__ZN3JSC8JSObject6freezeERNS_12VME
+__ZN3JSC9Structure8isFrozenERNS_12VME
+__ZN3JSC9Structure16freezeTransitionERNS_12VMEPS0_
__ZN3JSCL25objectConstructorIsSealedEPNS_9ExecStateE
__ZN3JSCL25objectConstructorIsFrozenEPNS_9ExecStateE
__ZN3JSCL29objectConstructorIsExtensibleEPNS_9ExecStateE
@@ -2364,10 +2349,8 @@ __ZNK3WTF8Collator7collateEPKtmS2_m
__ZNK3WTF8Collator14createCollatorEv
__ZN3WTF8CollatorD1Ev
__ZN3WTF8Collator15releaseCollatorEv
-__ZN3JSC3JIT30emit_op_ensure_property_existsEPNS_11InstructionE
-_cti_op_ensure_property_exists
__ZNK3JSC20StrictEvalActivation12toThisObjectEPNS_9ExecStateE
-__ZN3JSC15IdentifierArena21makeNumericIdentifierEPNS_12JSGlobalDataEd
+__ZN3JSC15IdentifierArena21makeNumericIdentifierEPNS_12VMEd
__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
__ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_7JSValueE
__ZN3WTF16codePointCompareERKNS_6StringES2_
@@ -2401,7 +2384,7 @@ __ZNK3JSC11ProfileNode25traverseNextNodePostOrderEv
__ZN3JSC11ProfileNode13stopProfilingEv
__ZN3JSC11ProfileNode11removeChildEPS0_
__ZN3JSC11ProfileNode8addChildEN3WTF10PassRefPtrIS0_EE
-__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
+__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12VME
__ZN3WTF9HashTableIPN3JSC18FunctionExecutableES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
__ZN3JSC7ProfileD0Ev
__ZN3WTF10RefCountedIN3JSC11ProfileNodeEE5derefEv
@@ -2409,7 +2392,7 @@ __ZN3JSC8Profiler11willExecuteEPNS_9ExecStateERKNS_7UStringEi
__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateERKNS_7UStringEi
__ZNK3JSC16ProfileGenerator5titleEv
__ZN3JSC8Profiler13stopProfilingEPNS_14JSGlobalObjectE
-__ZN3JSC34createTerminatedExecutionExceptionEPNS_12JSGlobalDataE
+__ZN3JSC34createTerminatedExecutionExceptionEPNS_12VME
__ZNK3JSC24TerminatedExecutionError13exceptionTypeEv
__ZN3JSC24TerminatedExecutionErrorD1Ev
__ZN3WTF5Mutex7tryLockEv
@@ -2418,7 +2401,7 @@ __ZN3WTF5yieldEv
__ZN3WTF8CollatorC1EPKc
__ZN3WTF8Collator18setOrderLowerFirstEb
__ZN3JSC10JSONObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
-__ZN3JSC9Structure27despecifyDictionaryFunctionERNS_12JSGlobalDataERKNS_10IdentifierE
+__ZN3JSC9Structure27despecifyDictionaryFunctionERNS_12VMERKNS_10IdentifierE
__ZN3JSC17ObjectConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
__ZN3JSC15ObjectPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
__ZN3JSC17StringConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
diff --git a/Source/JavaScriptCore/JavaScriptCore.pri b/Source/JavaScriptCore/JavaScriptCore.pri
index 629a4838c..b636e587c 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pri
+++ b/Source/JavaScriptCore/JavaScriptCore.pri
@@ -33,7 +33,7 @@ INCLUDEPATH += \
$$JAVASCRIPTCORE_GENERATED_SOURCES_DIR
# Pick up the right version of LLIntAssembly.h
-macx:INCLUDEPATH+=$$JAVASCRIPTCORE_GENERATED_SOURCES_DIR/$$targetSubDir()
+macx: INCLUDEPATH += $$JAVASCRIPTCORE_GENERATED_SOURCES_DIR/$$targetSubDir()
win32-*: LIBS += -lwinmm
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
deleted file mode 100644
index a87ecc9dd..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.make
+++ /dev/null
@@ -1,41 +0,0 @@
-!IF defined(BUILDSTYLE) && "$(BUILDSTYLE)"=="DEBUG"
-BUILDSTYLE=Debug_All
-!ELSE
-BUILDSTYLE=Release_PGO
-!ENDIF
-
-install:
- set OFFICIAL_BUILD=1
- set WebKitLibrariesDir=$(SRCROOT)\AppleInternal
- set WebKitOutputDir=$(OBJROOT)
- set ConfigurationBuildDir=$(OBJROOT)\$(BUILDSTYLE)
- set WebKitVSPropsRedirectionDir=$(SRCROOT)\AppleInternal\tools\vsprops\OpenSource\1\2\3\4\
- -mkdir "%ConfigurationBuildDir%\include\private"
- xcopy "%WebKitLibrariesDir%\include\private\*" "%ConfigurationBuildDir%\include\private" /e/v/i/h/y
-!IF "$(BUILDSTYLE)"=="Release_PGO"
- devenv "JavaScriptCoreSubmit.sln" /clean $(BUILDSTYLE)
- devenv "JavaScriptCoreSubmit.sln" /build $(BUILDSTYLE)
- set PATH=$(SYSTEMDRIVE)\cygwin\bin;$(PATH)
- xcopy "$(SRCROOT)\AppleInternal\tests\SunSpider\*" "%ConfigurationBuildDir%\tests\SunSpider" /e/v/i/h/y
- cd "%ConfigurationBuildDir%\tests\SunSpider"
- perl sunspider --shell ../../bin/jsc.exe --runs 3
- del "%ConfigurationBuildDir%\bin\JavaScriptCore.dll"
- cd "$(SRCROOT)\JavaScriptCore.vcproj"
- devenv "JavaScriptCoreSubmit.sln" /build Release_PGO_Optimize
-!ELSE
- devenv "JavaScriptCoreSubmit.sln" /clean $(BUILDSTYLE)
- devenv "JavaScriptCoreSubmit.sln" /build $(BUILDSTYLE)
-!ENDIF
- -xcopy "%ConfigurationBuildDir%\bin\JavaScriptCore.dll" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\JavaScriptCore_debug.dll" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\JavaScriptCore.pdb" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\JavaScriptCore_debug.pdb" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\jsc.exe" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\jsc_debug.exe" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\jsc.pdb" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- -xcopy "%ConfigurationBuildDir%\bin\jsc_debug.pdb" "$(DSTROOT)\AppleInternal\bin\" /e/v/i/h/y
- xcopy "%ConfigurationBuildDir%\include\*" "$(DSTROOT)\AppleInternal\include\" /e/v/i/h/y
- xcopy "%ConfigurationBuildDir%\lib\*" "$(DSTROOT)\AppleInternal\lib\" /e/v/i/h/y
- xcopy "%ConfigurationBuildDir%\bin\JavaScriptCore.resources\*" "$(DSTROOT)\AppleInternal\bin\JavaScriptCore.resources" /e/v/i/h/y
- -mkdir "$(DSTROOT)\AppleInternal\Sources\JavaScriptCore"
- xcopy "%ConfigurationBuildDir%\obj\JavaScriptCore\DerivedSources\*" "$(DSTROOT)\AppleInternal\Sources\JavaScriptCore" /e/v/i/h/y
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
deleted file mode 100644
index 6f4236e03..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
+++ /dev/null
@@ -1,170 +0,0 @@
-
-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
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A} = {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}
- {9221744B-5715-4F56-9590-42F7AB23DD8B} = {9221744B-5715-4F56-9590-42F7AB23DD8B}
- {D595E3F6-24F2-4C60-935C-95D50C6B3E96} = {D595E3F6-24F2-4C60-935C-95D50C6B3E96}
- {877150A0-41B3-4730-9D98-1B8298098B14} = {877150A0-41B3-4730-9D98-1B8298098B14}
- 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\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}") = "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\WTF.vcproj\WTFGenerated.vcproj", "{5AE5F5E4-782D-4F63-B4D7-3977B52B9950}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LLIntDesiredOffsets", "LLIntDesiredOffsets\LLIntDesiredOffsets.vcproj", "{877150A0-41B3-4730-9D98-1B8298098B14}"
- ProjectSection(ProjectDependencies) = postProject
- {5AE5F5E4-782D-4F63-B4D7-3977B52B9950} = {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}
- {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}") = "LLIntOffsetsExtractor", "LLIntOffsetsExtractor\LLIntOffsetsExtractor.vcproj", "{D595E3F6-24F2-4C60-935C-95D50C6B3E96}"
- ProjectSection(ProjectDependencies) = postProject
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A} = {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
- {877150A0-41B3-4730-9D98-1B8298098B14} = {877150A0-41B3-4730-9D98-1B8298098B14}
- {5AE5F5E4-782D-4F63-B4D7-3977B52B9950} = {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LLIntAssembly", "LLIntAssembly\LLIntAssembly.vcproj", "{9221744B-5715-4F56-9590-42F7AB23DD8B}"
- ProjectSection(ProjectDependencies) = postProject
- {D595E3F6-24F2-4C60-935C-95D50C6B3E96} = {D595E3F6-24F2-4C60-935C-95D50C6B3E96}
- {5AE5F5E4-782D-4F63-B4D7-3977B52B9950} = {5AE5F5E4-782D-4F63-B4D7-3977B52B9950}
- {877150A0-41B3-4730-9D98-1B8298098B14} = {877150A0-41B3-4730-9D98-1B8298098B14}
- {AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A} = {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}
- EndProjectSection
-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
- EndGlobalSection
- 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
- {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
- {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
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.ActiveCfg = Release|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.Build.0 = Release|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Debug_All|Win32.ActiveCfg = Debug_All|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Debug_All|Win32.Build.0 = Debug_All|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Debug_Cairo_CFLite|Win32.ActiveCfg = Debug_Cairo_CFLite|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Debug_Cairo_CFLite|Win32.Build.0 = Debug_Cairo_CFLite|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Debug|Win32.ActiveCfg = Debug|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Debug|Win32.Build.0 = Debug|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Production|Win32.ActiveCfg = Production|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Production|Win32.Build.0 = Production|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release_Cairo_CFLite|Win32.ActiveCfg = Release_Cairo_CFLite|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release_Cairo_CFLite|Win32.Build.0 = Release_Cairo_CFLite|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release_PGO_Optimize|Win32.ActiveCfg = Release_PGO|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release_PGO_Optimize|Win32.Build.0 = Release_PGO|Win32
- {14C94979-1ED3-4E1D-9B55-A80FCF4677D0}.Release_PGO|Win32.ActiveCfg = Release_PGO|Win32
- {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
- EndGlobalSection
-EndGlobal
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
deleted file mode 100755
index 422aac464..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ /dev/null
@@ -1,439 +0,0 @@
-EXPORTS
-
- ??0ArrayBufferView@WTF@@IAE@V?$PassRefPtr@VArrayBuffer@WTF@@@1@I@Z
- ??0BooleanObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@@Z
- ??0Collator@WTF@@QAE@PBD@Z
- ??0CString@WTF@@QAE@PBD@Z
- ??0CString@WTF@@QAE@PBDI@Z
- ??0DateInstance@JSC@@IAE@PAVExecState@1@PAVStructure@1@@Z
- ??0DefaultGCActivityCallback@JSC@@QAE@PAVHeap@1@@Z
- ??0DropAllLocks@JSLock@JSC@@QAE@PAVExecState@2@@Z
- ??0DropAllLocks@JSLock@JSC@@QAE@PAVJSGlobalData@2@@Z
- ??0DynamicGlobalObjectScope@JSC@@QAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@@Z
- ??0ErrorHandlingMode@Interpreter@JSC@@QAE@PAVExecState@2@@Z
- ??1ErrorHandlingMode@Interpreter@JSC@@QAE@XZ
- ??0InstrumentedPointerBase@MemoryInstrumentation@WTF@@QAE@PAVMemoryObjectInfo@2@@Z
- ??0InternalFunction@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@@Z
- ??0JSGlobalObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@PBUGlobalObjectMethodTable@1@@Z
- ??0JSLockHolder@JSC@@QAE@AAVJSGlobalData@1@@Z
- ??0JSLockHolder@JSC@@QAE@PAVExecState@1@@Z
- ??0JSLockHolder@JSC@@QAE@PAVJSGlobalData@1@@Z
- ??0MD5@WTF@@QAE@XZ
- ??0MediaTime@WTF@@QAE@_JHI@Z
- ??0MemoryInstrumentation@WTF@@QAE@PAVMemoryInstrumentationClient@1@@Z
- ??0Mutex@WTF@@QAE@XZ
- ??0ParallelEnvironment@WTF@@QAE@P6AXPAX@ZIH@Z
- ??0RefCountedLeakCounter@WTF@@QAE@PBD@Z
- ??0RegExpObject@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@PAVRegExp@1@@Z
- ??0SHA1@WTF@@QAE@XZ
- ??0StringObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@@Z
- ??0Structure@JSC@@AAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@VJSValue@1@ABVTypeInfo@1@PBUClassInfo@1@EH@Z
- ??0ThreadCondition@WTF@@QAE@XZ
- ??0WTFThreadData@WTF@@QAE@XZ
- ??0YarrPattern@Yarr@JSC@@QAE@ABVString@WTF@@_N1PAPBD@Z
- ??1ArrayBufferView@WTF@@UAE@XZ
- ??1ClientData@JSGlobalData@JSC@@UAE@XZ
- ??1Collator@WTF@@QAE@XZ
- ??1Debugger@JSC@@UAE@XZ
- ??1DropAllLocks@JSLock@JSC@@QAE@XZ
- ??1JSGlobalData@JSC@@QAE@XZ
- ??1JSGlobalObject@JSC@@QAE@XZ
- ??1JSLockHolder@JSC@@QAE@XZ
- ??1MediaTime@WTF@@QAE@XZ
- ??1MemoryInstrumentation@WTF@@UAE@XZ
- ??1Mutex@WTF@@QAE@XZ
- ??1RefCountedLeakCounter@WTF@@QAE@XZ
- ??1SourceProviderCache@JSC@@QAE@XZ
- ??1ThreadCondition@WTF@@QAE@XZ
- ??1WeakHandleOwner@JSC@@UAE@XZ
- ??1WTFThreadData@WTF@@QAE@XZ
- ??8MediaTime@WTF@@QBE_NABV01@@Z
- ??8WTF@@YA_NABVCString@0@0@Z
- ??GMediaTime@WTF@@QBE?AV01@ABV01@@Z
- ??HMediaTime@WTF@@QBE?AV01@ABV01@@Z
- ??MMediaTime@WTF@@QBE_NABV01@@Z
- ??OMediaTime@WTF@@QBE_NABV01@@Z
- ?abs@WTF@@YA?AVMediaTime@1@ABV21@@Z
- ?absoluteTimeToWaitTimeoutInterval@WTF@@YAKN@Z
- ?activityCallback@Heap@JSC@@QAEPAVGCActivityCallback@2@XZ
- ?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z
- ?addFromLiteralData@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBDI@Z
- ?add@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
- ?add@Identifier@JSC@@SA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PBD@Z
- ?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WTF@@@Z
- ?addBytes@MD5@WTF@@QAEXPBEI@Z
- ?addBytes@SHA1@WTF@@QAEXPBEI@Z
- ?addCurrentThread@MachineThreads@JSC@@QAEXXZ
- ?addFinalizer@Heap@JSC@@QAEXPAVJSCell@2@P6AX0@Z@Z
- ?addPropertyTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VPropertyName@2@IPAVJSCell@2@AAH@Z
- ?addPropertyTransitionToExistingStructure@Structure@JSC@@SAPAV12@PAV12@VPropertyName@2@IPAVJSCell@2@AAH@Z
- ?addPropertyWithoutTransition@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@IPAVJSCell@2@@Z
- ?addPrivateBuffer@MemoryClassInfo@WTF@@QAEXIPBD@Z
- ?addRawBuffer@MemoryClassInfo@WTF@@QAEXABQBXI@Z
- ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
- ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
- ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
- ?allocateSlowCase@MarkedAllocator@JSC@@AAEPAXI@Z
- ?append@StringBuilder@WTF@@QAEXPB_WI@Z
- ?append@StringBuilder@WTF@@QAEXPBEI@Z
- ?appendNumber@StringBuilder@WTF@@QAEX_J@Z
- ?appendNumber@StringBuilder@WTF@@QAEX_K@Z
- ?appendNumber@StringBuilder@WTF@@QAEXH@Z
- ?appendNumber@StringBuilder@WTF@@QAEXI@Z
- ?appendNumber@StringBuilder@WTF@@QAEXJ@Z
- ?appendNumber@StringBuilder@WTF@@QAEXK@Z
- ?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
- ?base64Decode@WTF@@YA_NABVString@1@AAV?$Vector@D$0A@@1@W4Base64DecodePolicy@1@@Z
- ?base64Encode@WTF@@YA?AVString@1@PBDIW4Base64EncodePolicy@1@@Z
- ?base64Encode@WTF@@YAXPBDIAAV?$Vector@D$0A@@1@W4Base64EncodePolicy@1@@Z
- ?broadcast@ThreadCondition@WTF@@QAEXXZ
- ?bufferLengthForStringDecimal@DecimalNumber@WTF@@QBEIXZ
- ?bufferLengthForStringExponential@DecimalNumber@WTF@@QBEIXZ
- ?byteCompile@Yarr@JSC@@YA?AV?$PassOwnPtr@UBytecodePattern@Yarr@JSC@@@WTF@@AAUYarrPattern@12@PAVBumpPointerAllocator@4@@Z
- ?byteSize@SourceProviderCache@JSC@@QBEIXZ
- ?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVString@WTF@@XZ
- ?calculateDSTOffset@WTF@@YANNN@Z
- ?calculateStringHashAndLengthFromUTF8MaskingTop8Bits@Unicode@WTF@@YAIPBD0AAI1@Z
- ?calculateUTCOffset@WTF@@YAHXZ
- ?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z
- ?callHostFunctionAsConstructor@JSC@@YI_JPAVExecState@1@@Z
- ?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
- ?callOnMainThreadAndWait@WTF@@YAXP6AXPAX@Z0@Z
- ?callReportObjectInfo@MemoryInstrumentation@WTF@@CAXPAVMemoryObjectInfo@2@PBXPBDI@Z
- ?cancelCallOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
- ?canShrink@StringBuilder@WTF@@QBE_NXZ
- ?capacity@Heap@JSC@@QAEIXZ
- ?changePrototypeTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VJSValue@2@@Z
- ?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@@Z
- ?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@@Z
- ?checksum@MD5@WTF@@QAEXAAV?$Vector@E$0BA@@2@@Z
- ?checkSyntax@JSC@@YA_NPAVExecState@1@ABVSourceCode@1@PAVJSValue@1@@Z
- ?className@JSObject@JSC@@SA?AVString@WTF@@PBV12@@Z
- ?className@JSProxy@JSC@@KA?AVString@WTF@@PBVJSObject@2@@Z
- ?clear@SourceProviderCache@JSC@@QAEXXZ
- ?clearRareData@JSGlobalObject@JSC@@CAXPAVJSCell@2@@Z
- ?collate@Collator@WTF@@QBE?AW4Result@12@PB_WI0I@Z
- ?collectAllGarbage@Heap@JSC@@QAEXXZ
- ?computeHash@SHA1@WTF@@QAEXAAV?$Vector@E$0BE@@2@@Z
- ?configurable@PropertyDescriptor@JSC@@QBE_NXZ
- ?construct@JSC@@YAPAVJSObject@1@PAVExecState@1@VJSValue@1@W4ConstructType@1@ABTConstructData@1@ABVArgList@1@@Z
- ?constructEmptyObject@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?constructFunctionSkippingEvalEnabledCheck@JSC@@YAPAVJSObject@1@PAVExecState@1@PAVJSGlobalObject@1@ABVArgList@1@ABVIdentifier@1@ABVString@WTF@@ABVTextPosition@8@@Z
- ?constructNumber@JSC@@YAPAVNumberObject@1@PAVExecState@1@PAVJSGlobalObject@1@VJSValue@1@@Z
- ?constructString@JSC@@YAPAVStringObject@1@PAVExecState@1@PAVJSGlobalObject@1@VJSValue@1@@Z
- ?convertDoubleToContiguousWhilePerformingSetIndex@JSObject@JSC@@AAEXAAVJSGlobalData@2@IVJSValue@2@@Z
- ?convertInt32ToDoubleOrContiguousWhilePerformingSetIndex@JSObject@JSC@@AAEXAAVJSGlobalData@2@IVJSValue@2@@Z
- ?convertLatin1ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBEPBEPAPADPAD@Z
- ?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z
- ?convertUTF8ToUTF16@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBDPBDPAPA_WPA_WPA_N_N@Z
- ?copyBackingStore@JSObject@JSC@@SAXPAVJSCell@2@AAVCopyVisitor@2@@Z
- ?create@JSFunction@JSC@@SAPAV12@PAVExecState@2@PAVJSGlobalObject@2@HABVString@WTF@@P6I_J0@ZW4Intrinsic@2@3@Z
- ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4HeapType@2@@Z
- ?create@OpaqueJSString@@SA?AV?$PassRefPtr@UOpaqueJSString@@@WTF@@ABVString@3@@Z
- ?create@RegExp@JSC@@SAPAV12@AAVJSGlobalData@2@ABVString@WTF@@W4RegExpFlags@2@@Z
- ?createEmptyString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@@Z
- ?createError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z
- ?createInterruptedExecutionException@JSC@@YAPAVJSObject@1@PAVJSGlobalData@1@@Z
- ?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4HeapType@2@@Z
- ?createNotEnoughArgumentsError@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?createRangeError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z
- ?createReferenceError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z
- ?createSingleCharacterString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@E@Z
- ?createStackOverflowError@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?createSyntaxError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z
- ?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z
- ?createThread@WTF@@YAIP6APAXPAX@Z0@Z
- ?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z
- ?createThread@WTF@@YAIP6AXPAX@Z0PBD@Z
- ?createTypeError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z
- ?createWithDouble@MediaTime@WTF@@SA?AV12@NH@Z
- ?createWithFloat@MediaTime@WTF@@SA?AV12@MH@Z
- ?cryptographicallyRandomNumber@WTF@@YAIXZ
- ?cryptographicallyRandomValues@WTF@@YAXPAXI@Z
- ?currentThread@WTF@@YAIXZ
- ?currentTime@WTF@@YANXZ
- ?customHasInstance@JSCell@JSC@@KA_NPAVJSObject@2@PAVExecState@2@VJSValue@2@@Z
- ?data@CString@WTF@@QBEPBDXZ
- ?dataLogF@WTF@@YAXPBDZZ
- ?dateToDaysFrom1970@WTF@@YANHHH@Z
- ?dayInMonthFromDayInYear@WTF@@YAHH_N@Z
- ?dayInYear@WTF@@YAHNH@Z
- ?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
- ?defaultValue@JSObject@JSC@@SA?AVJSValue@2@PBV12@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
- ?defineOwnProperty@JSGlobalObject@JSC@@SA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@_N@Z
- ?defineOwnProperty@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@_N@Z
- ?defineOwnProperty@JSProxy@JSC@@KA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@_N@Z
- ?deleteAllCompiledCode@Heap@JSC@@QAEXXZ
- ?deleteOwnedPtr@WTF@@YAXPAUHBITMAP__@@@Z
- ?deleteOwnedPtr@WTF@@YAXPAUHBRUSH__@@@Z
- ?deleteOwnedPtr@WTF@@YAXPAUHDC__@@@Z
- ?deleteOwnedPtr@WTF@@YAXPAUHFONT__@@@Z
- ?deleteOwnedPtr@WTF@@YAXPAUHRGN__@@@Z
- ?deleteProperty@JSObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@@Z
- ?deleteProperty@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@@Z
- ?deleteProperty@JSSymbolTableObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@@Z
- ?deletePropertyByIndex@JSObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@I@Z
- ?deletePropertyByIndex@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@I@Z
- ?deleteTable@HashTable@JSC@@QBEXXZ
- ?description@JSValue@JSC@@QBEPADXZ
- ?despecifyDictionaryFunction@Structure@JSC@@QAEXAAVJSGlobalData@2@VPropertyName@2@@Z
- ?despecifyFunctionTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VPropertyName@2@@Z
- ?destroy@JSCell@JSC@@KAXPAV12@@Z
- ?destroy@JSGlobalObject@JSC@@SAXPAVJSCell@2@@Z
- ?destroy@OutOfLineBits@BitVector@WTF@@SAXPAV123@@Z
- ?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z
- ?detachThread@WTF@@YAXI@Z
- ?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
- ?displayName@JSFunction@JSC@@QAE?AVString@WTF@@PAVExecState@2@@Z
- ?dtoa@WTF@@YAXQADNAA_NAAHAAI@Z
- ?dumpAllOptions@Options@JSC@@SAXPAU_iobuf@@@Z
- ?dumpCallFrame@Interpreter@JSC@@QAEXPAVExecState@2@@Z
- ?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
- ?EcmaScriptConverter@DoubleToStringConverter@double_conversion@WTF@@SAABV123@XZ
- ?empty@StringImpl@WTF@@SAPAV12@XZ
- ?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
- ?equalUTF16WithUTF8@Unicode@WTF@@YA_NPB_W0PBD1@Z
- ?evaluate@DebuggerCallFrame@JSC@@QBE?AVJSValue@2@ABVString@WTF@@AAV32@@Z
- ?evaluate@JSC@@YA?AVJSValue@1@PAVExecState@1@ABVSourceCode@1@V21@PAV21@@Z
- ?exclude@Profile@JSC@@QAEXPBVProfileNode@2@@Z
- ?execute@ParallelEnvironment@WTF@@QAEXPAX@Z
- ?expand@MarkStackArray@JSC@@AAEXXZ
- ?fastCalloc@WTF@@YAPAXII@Z
- ?fastFree@WTF@@YAXPAX@Z
- ?fastMalloc@WTF@@YAPAXI@Z
- ?fastMallocMatchFailed@Internal@WTF@@YAXPAX@Z
- ?fastMallocSize@WTF@@YAIPBX@Z
- ?fastMallocStatistics@WTF@@YA?AUFastMallocStatistics@1@XZ
- ?fastRealloc@WTF@@YAPAXPAXI@Z
- ?fastStrDup@WTF@@YAPADPBD@Z
- ?fastZeroedMalloc@WTF@@YAPAXI@Z
- ?fillGetterPropertySlot@JSObject@JSC@@AAEXAAVPropertySlot@2@H@Z
- ?finalize@WeakHandleOwner@JSC@@UAEXV?$Handle@W4Unknown@JSC@@@2@PAX@Z
- ?findAllocator@WeakSet@JSC@@AAEPAUFreeCell@WeakBlock@2@XZ
- ?finishCreation@BooleanObject@JSC@@IAEXAAVJSGlobalData@2@@Z
- ?finishCreation@DateInstance@JSC@@IAEXAAVJSGlobalData@2@N@Z
- ?finishCreation@InternalFunction@JSC@@IAEXAAVJSGlobalData@2@ABVString@WTF@@@Z
- ?finishCreation@RegExpObject@JSC@@IAEXPAVJSGlobalObject@2@@Z
- ?finishCreation@StringObject@JSC@@IAEXAAVJSGlobalData@2@PAVJSString@2@@Z
- ?focus@Profile@JSC@@QAEXPBVProfileNode@2@@Z
- ?freeFatEntrySlow@SymbolTableEntry@JSC@@AAEXXZ
- ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@H@Z
- ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@I@Z
- ?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z
- ?get@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z
- ?getCalculatedDisplayName@JSC@@YA?AVString@WTF@@PAVExecState@1@PAVJSObject@1@@Z
- ?getCallableObjectSlow@JSC@@YAPAVJSCell@1@PAV21@@Z
- ?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z
- ?getConstructData@JSCell@JSC@@SA?AW4ConstructType@2@PAV12@AATConstructData@2@@Z
- ?getObject@JSCell@JSC@@QAEPAVJSObject@2@XZ
- ?getObjectType@MemoryInstrumentation@WTF@@CAPBDPAVMemoryObjectInfo@2@@Z
- ?getOwnNonIndexPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
- ?getOwnNonIndexPropertyNames@JSSymbolTableObject@JSC@@SAXPAVJSObject@2@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
- ?getOwnPropertyDescriptor@JSGlobalObject@JSC@@SA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z
- ?getOwnPropertyDescriptor@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z
- ?getOwnPropertyDescriptor@JSProxy@JSC@@KA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z
- ?getOwnPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
- ?getOwnPropertyNames@JSProxy@JSC@@KAXPAVJSObject@2@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
- ?getOwnPropertySlot@JSGlobalObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@AAVPropertySlot@2@@Z
- ?getOwnPropertySlot@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@AAVPropertySlot@2@@Z
- ?getOwnPropertySlotByIndex@JSObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@IAAVPropertySlot@2@@Z
- ?getOwnPropertySlotByIndex@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@IAAVPropertySlot@2@@Z
- ?getOwnPropertySlotSlow@JSObject@JSC@@AAE_NPAVExecState@2@VPropertyName@2@AAVPropertySlot@2@@Z
- ?getPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
- ?getPropertyNames@JSProxy@JSC@@KAXPAVJSObject@2@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z
- ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z
- ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@AAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z
- ?getString@JSCell@JSC@@QBE?AVString@WTF@@PAVExecState@2@@Z
- ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVString@WTF@@@Z
- ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
- ?globalExec@JSGlobalObject@JSC@@QAEPAVExecState@2@XZ
- ?globalObjectCount@Heap@JSC@@QAEIXZ
- ?grow@HandleSet@JSC@@AAEXXZ
- ?growOutOfLineStorage@JSObject@JSC@@QAEPAVButterfly@2@AAVJSGlobalData@2@II@Z
- ?hashSlowCase@StringImpl@WTF@@ABEIXZ
- ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
- ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@VPropertyName@2@@Z
- ?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z
- ?increment@RefCountedLeakCounter@WTF@@QAEXXZ
- ?indefiniteTime@MediaTime@WTF@@SAABV12@XZ
- ?init@AtomicString@WTF@@SAXXZ
- ?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z
- ?init@MemoryClassInfo@WTF@@AAEXPBXPBDI@Z
- ?initialize@double_conversion@WTF@@YAXXZ
- ?initializeMainThread@WTF@@YAXXZ
- ?initializeThreading@JSC@@YAXXZ
- ?initializeThreading@WTF@@YAXXZ
- ?interpret@Yarr@JSC@@YAIPAUBytecodePattern@12@ABVString@WTF@@IPAI@Z
- ?invalidTime@MediaTime@WTF@@SAABV12@XZ
- ?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
- ?isBusy@Heap@JSC@@QAE_NXZ
- ?isDataDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
- ?isHostFunctionNonInline@JSFunction@JSC@@ABE_NXZ
- ?isMainThread@WTF@@YA_NXZ
- ?isReachableFromOpaqueRoots@WeakHandleOwner@JSC@@UAE_NV?$Handle@W4Unknown@JSC@@@2@PAXAAVSlotVisitor@2@@Z
- ?isTerminatedExecutionException@JSC@@YA_NVJSValue@1@@Z
- ?isValidAllocation@Heap@JSC@@AAE_NI@Z
- ?isValidCallee@JSValue@JSC@@QAE_NXZ
- ?length@CString@WTF@@QBEIXZ
- ?lock@JSLock@JSC@@QAEXXZ
- ?lock@Mutex@WTF@@QAEXXZ
- ?lockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
- ?match@RegExp@JSC@@QAEHAAVJSGlobalData@2@ABVString@WTF@@IAAV?$Vector@H$0CA@@5@@Z
- ?materializePropertyMap@Structure@JSC@@AAEXAAVJSGlobalData@2@@Z
- ?monotonicallyIncreasingTime@WTF@@YANXZ
- ?monthFromDayInYear@WTF@@YAHH_N@Z
- ?msToYear@WTF@@YAHN@Z
- ?name@JSFunction@JSC@@QAE?AVString@WTF@@PAVExecState@2@@Z
- ?negativeInfiniteTime@MediaTime@WTF@@SAABV12@XZ
- ?neuter@ArrayBufferView@WTF@@MAEXXZ
- ?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z
- ?notifyWriteSlow@SymbolTableEntry@JSC@@AAEXXZ
- ?notifyWriteSlow@WatchpointSet@JSC@@QAEXXZ
- ?nullptr@@3Vnullptr_t@std@@A
- ?numberToFixedPrecisionString@WTF@@YAPBDNIQAD_N@Z
- ?numberToFixedWidthString@WTF@@YAPBDNIQAD@Z
- ?numberToString@WTF@@YAPBDNQAD@Z
- ?objectAtScope@JSScope@JSC@@SAPAVJSObject@2@PAV12@@Z
- ?objectCount@Heap@JSC@@QAEIXZ
- ?objectProtoFuncToString@JSC@@YI_JPAVExecState@1@@Z
- ?objectTypeCounts@Heap@JSC@@QAE?AV?$PassOwnPtr@V?$HashCountedSet@PBDU?$PtrHash@PBD@WTF@@U?$HashTraits@PBD@2@@WTF@@@WTF@@XZ
- ?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z
- ?parseDoubleFromLongString@Internal@WTF@@YANPB_WIAAI@Z
- ?positiveInfiniteTime@MediaTime@WTF@@SAABV12@XZ
- ?process@InstrumentedPointerBase@MemoryInstrumentation@WTF@@QAEXPAV23@@Z
- ?profiler@Profiler@JSC@@SAPAV12@XZ
- ?protect@Heap@JSC@@QAEXVJSValue@2@@Z
- ?protectedGlobalObjectCount@Heap@JSC@@QAEIXZ
- ?protectedObjectCount@Heap@JSC@@QAEIXZ
- ?protectedObjectTypeCounts@Heap@JSC@@QAE?AV?$PassOwnPtr@V?$HashCountedSet@PBDU?$PtrHash@PBD@WTF@@U?$HashTraits@PBD@2@@WTF@@@WTF@@XZ
- ?put@JSGlobalObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z
- ?put@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z
- ?put@JSProxy@JSC@@KAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z
- ?putByIndex@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@_N@Z
- ?putByIndex@JSProxy@JSC@@KAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@_N@Z
- ?putDirectIndexBeyondVectorLength@JSObject@JSC@@AAE_NPAVExecState@2@IVJSValue@2@IW4PutDirectIndexMode@2@@Z
- ?putDirectMayBeIndex@JSObject@JSC@@QAEXPAVExecState@2@VPropertyName@2@VJSValue@2@@Z
- ?putDirectVirtual@JSGlobalObject@JSC@@SAXPAVJSObject@2@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z
- ?putDirectVirtual@JSObject@JSC@@SAXPAV12@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z
- ?putDirectVirtual@JSProxy@JSC@@KAXPAVJSObject@2@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z
- ?randomNumber@WTF@@YANXZ
- ?recompileAllJSFunctions@Debugger@JSC@@QAEXPAVJSGlobalData@2@@Z
- ?regExpFlags@JSC@@YA?AW4RegExpFlags@1@ABVString@WTF@@@Z
- ?reifyString@StringBuilder@WTF@@ABEXXZ
- ?releaseDecommitted@OSAllocator@WTF@@SAXPAXI@Z
- ?releaseExecutableMemory@JSGlobalData@JSC@@QAEXXZ
- ?removeBlock@MarkedAllocator@JSC@@QAEXPAVMarkedBlock@2@@Z
- ?removeDirect@JSObject@JSC@@QAE_NAAVJSGlobalData@2@VPropertyName@2@@Z
- ?reportAbandonedObjectGraph@Heap@JSC@@QAEXXZ
- ?reportExtraMemoryCostSlowCase@Heap@JSC@@AAEXI@Z
- ?reportSuccess@HeapStatistics@JSC@@SAXXZ
- ?reserveAndCommit@OSAllocator@WTF@@SAPAXIW4Usage@12@_N11@Z
- ?reserveCapacity@StringBuilder@WTF@@QAEXI@Z
- ?reset@ParserArena@JSC@@QAEXXZ
- ?reset@TimeoutChecker@JSC@@QAEXXZ
- ?resetDateCache@JSGlobalData@JSC@@QAEXXZ
- ?resize@StringBuilder@WTF@@QAEXI@Z
- ?resizeOutOfLine@BitVector@WTF@@AAEXI@Z
- ?resolveRope@JSRopeString@JSC@@ABEXPAVExecState@2@@Z
- ?restoreAll@Profile@JSC@@QAEXXZ
- ?retrieveCallerFromVMCode@Interpreter@JSC@@QBE?AVJSValue@2@PAVExecState@2@PAVJSFunction@2@@Z
- ?retrieveLastCaller@Interpreter@JSC@@QBEXPAVExecState@2@AAH1AAVString@WTF@@AAVJSValue@2@@Z
- ?setConfigurable@PropertyDescriptor@JSC@@QAEX_N@Z
- ?setDescriptor@PropertyDescriptor@JSC@@QAEXVJSValue@2@I@Z
- ?setEnumerable@PropertyDescriptor@JSC@@QAEX_N@Z
- ?setGarbageCollectionTimerEnabled@Heap@JSC@@QAEX_N@Z
- ?setGetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z
- ?setGlobalThis@JSGlobalObject@JSC@@IAEXAAVJSGlobalData@2@PAVJSObject@2@@Z
- ?setIndexQuicklyToUndecided@JSObject@JSC@@AAEXAAVJSGlobalData@2@IVJSValue@2@@Z
- ?setLoc@StatementNode@JSC@@QAEXHH@Z
- ?setMainThreadCallbacksPaused@WTF@@YAX_N@Z
- ?setOption@Options@JSC@@SA_NPBD@Z
- ?setOrderLowerFirst@Collator@WTF@@QAEX_N@Z
- ?setPrototype@JSObject@JSC@@QAEXAAVJSGlobalData@2@VJSValue@2@@Z
- ?setSetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z
- ?setTarget@JSProxy@JSC@@IAEXAAVJSGlobalData@2@PAVJSGlobalObject@2@@Z
- ?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
- ?setToCurrentLocalTime@GregorianDateTime@WTF@@QAEXXZ
- ?setUndefined@PropertyDescriptor@JSC@@QAEXXZ
- ?setUpStaticFunctionSlot@JSC@@YA_NPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@VPropertyName@1@AAVPropertySlot@1@@Z
- ?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z
- ?shrinkToFit@StringBuilder@WTF@@QAEXXZ
- ?signal@ThreadCondition@WTF@@QAEXXZ
- ?singleCharacterStringRep@SmallStrings@JSC@@QAEPAVStringImpl@WTF@@E@Z
- ?size@Heap@JSC@@QAEIXZ
- ?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z
- ?slowValidateCell@JSC@@YAXPAVJSCell@1@@Z
- ?slowValidateCell@JSC@@YAXPAVJSGlobalObject@1@@Z
- ?sourceCode@JSFunction@JSC@@QBEPBVSourceCode@2@XZ
- ?startProfiling@Profiler@JSC@@QAEXPAVExecState@2@ABVString@WTF@@@Z
- ?startSampling@JSGlobalData@JSC@@QAEXXZ
- ?stopProfiling@Profiler@JSC@@QAE?AV?$PassRefPtr@VProfile@JSC@@@WTF@@PAVExecState@2@ABVString@4@@Z
- ?stopSampling@JSGlobalData@JSC@@QAEXXZ
- ?string@OpaqueJSString@@QBE?AVString@WTF@@XZ
- ?StringToDouble@StringToDoubleConverter@double_conversion@WTF@@SANPBDIPAI@Z
- ?suggestedNewOutOfLineStorageCapacity@Structure@JSC@@QAEIXZ
- ?sweeper@Heap@JSC@@QAEPAVIncrementalSweeper@2@XZ
- ?synthesizePrototype@JSValue@JSC@@QBEPAVJSObject@2@PAVExecState@2@@Z
- ?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ
- ?throwError@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@@Z
- ?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@PAV21@@Z
- ?throwSyntaxError@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?throwTypeError@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
- ?throwTypeError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z
- ?timedWait@ThreadCondition@WTF@@QAE_NAAVMutex@2@N@Z
- ?tlsKeyCount@WTF@@YAAAJXZ
- ?tlsKeys@WTF@@YAPAKXZ
- ?toBoolean@JSString@JSC@@QBE_NXZ
- ?toDouble@MediaTime@WTF@@QBENXZ
- ?ToExponential@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
- ?ToFixed@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
- ?toFloat@MediaTime@WTF@@QBEMXZ
- ?toInt32@JSC@@YAHN@Z
- ?toInteger@JSValue@JSC@@QBENPAVExecState@2@@Z
- ?toNumberSlowCase@JSValue@JSC@@ABENPAVExecState@2@@Z
- ?toObject@JSCell@JSC@@QBEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
- ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
- ?ToPrecision@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z
- ?ToShortest@DoubleToStringConverter@double_conversion@WTF@@QBE_NNPAVStringBuilder@23@@Z
- ?toString@JSObject@JSC@@QBEPAVJSString@2@PAVExecState@2@@Z
- ?toStringDecimal@DecimalNumber@WTF@@QBEIPAEI@Z
- ?toStringExponential@DecimalNumber@WTF@@QBEIPAEI@Z
- ?toStringSlowCase@JSValue@JSC@@ABEPAVJSString@2@PAVExecState@2@@Z
- ?toThisObject@JSGlobalObject@JSC@@KAPAVJSObject@2@PAVJSCell@2@PAVExecState@2@@Z
- ?toThisObject@JSObject@JSC@@SAPAV12@PAVJSCell@2@PAVExecState@2@@Z
- ?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
- ?toWTFStringSlowCase@JSValue@JSC@@ABE?AVString@WTF@@PAVExecState@2@@Z
- ?transfer@ArrayBuffer@WTF@@QAE_NAAVArrayBufferContents@2@AAV?$Vector@V?$RefPtr@VArrayBufferView@WTF@@@WTF@@$0A@@2@@Z
- ?tryAllocateSlowCase@CopiedSpace@JSC@@AAE?AVCheckedBoolean@@IPAPAX@Z
- ?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z
- ?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z
- ?tryFastRealloc@WTF@@YA?AUTryMallocReturnValue@1@PAXI@Z
- ?tryLock@Mutex@WTF@@QAE_NXZ
- ?type@DebuggerCallFrame@JSC@@QBE?AW4Type@12@XZ
- ?unlock@JSLock@JSC@@QAEXXZ
- ?unlock@Mutex@WTF@@QAEXXZ
- ?unlockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
- ?unprotect@Heap@JSC@@QAE_NVJSValue@2@@Z
- ?updateIndexingType@ArrayAllocationProfile@JSC@@QAEXXZ
- ?validate@SlotVisitor@JSC@@CAXPAVJSCell@2@@Z
- ?visitChildren@JSGlobalObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z
- ?visitChildren@JSObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z
- ?visitChildren@JSProxy@JSC@@KAXPAVJSCell@2@AAVSlotVisitor@2@@Z
- ?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
- ?waitForThreadCompletion@WTF@@YAHI@Z
- ?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
- ?writable@PropertyDescriptor@JSC@@QBE_NXZ
- ?writeBarrier@HandleSet@JSC@@QAEXPAVJSValue@2@ABV32@@Z
- ?yield@WTF@@YAXXZ
- ?zeroTime@MediaTime@WTF@@SAABV12@XZ
- WTFGetBacktrace
- WTFInvokeCrashHook
- WTFLog
- WTFLogAlways
- WTFLogVerbose
- WTFReportArgumentAssertionFailure
- WTFReportAssertionFailure
- WTFReportAssertionFailureWithMessage
- WTFReportBacktrace
- WTFReportError
- WTFSetCrashHook
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
deleted file mode 100644
index e8eda62f9..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ /dev/null
@@ -1,2668 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCore"
- ProjectGUID="{011D10F1-B656-4A1B-A0C3-3842F02122C5}"
- RootNamespace="JavaScriptCore"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreDebug.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreRelease.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreReleasePGO.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="2"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreDebugCairoCFLite.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreReleaseCairoCFLite.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreDebugAll.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreProduction.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_PGO_Optimize|Win32"
- ConfigurationType="2"
- InheritedPropertySheets=".\JavaScriptCoreReleasePGOOptimize.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="4"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="runtime"
- >
- <File
- RelativePath="..\..\runtime\Reject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArrayStorage.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\IndexingType.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\IndexingType.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyStorage.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PutDirectIndexMode.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ButterflyInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Butterfly.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\IndexingHeaderInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SparseArrayValueMap.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArrayConventions.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\IndexingHeader.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SparseArrayValueMap.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArgList.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArgList.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Arguments.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Arguments.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArrayConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArrayConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArrayPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ArrayPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BatchedTransitionOptimizer.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BooleanConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BooleanConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BooleanObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BooleanObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BooleanPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\BooleanPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CallData.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CallData.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ClassInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CodeCache.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CodeCache.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CodeSpecializationKind.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CodeSpecializationKind.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CommonIdentifiers.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CommonIdentifiers.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\CommonSlowPaths.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Completion.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Completion.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ConstructData.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ConstructData.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateConversion.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateConversion.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateInstance.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateInstance.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DateInstanceCache.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DatePrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\DatePrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Error.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Error.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ErrorConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ErrorConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ErrorInstance.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ErrorInstance.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ErrorPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ErrorPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ExceptionHelpers.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\ExceptionHelpers.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Executable.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Executable.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\FunctionConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\FunctionConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\FunctionPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\FunctionPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\GCActivityCallback.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\GCActivityCallback.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\GetterSetter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\GetterSetter.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Identifier.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Identifier.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\InitializeThreading.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\InitializeThreading.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\InternalFunction.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\InternalFunction.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSActivation.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSActivation.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSArray.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSArray.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSBoundFunction.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSBoundFunction.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSCell.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSCell.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSDateMath.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSDateMath.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSDestructibleObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSFunction.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSFunction.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSGlobalData.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSGlobalData.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSGlobalObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSGlobalObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSGlobalObjectFunctions.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSGlobalObjectFunctions.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSProxy.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSProxy.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSLock.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSLock.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSNotAnObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSNotAnObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSONObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSONObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSPropertyNameIterator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSPropertyNameIterator.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSSegmentedVariableObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSSegmentedVariableObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSWithScope.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSWithScope.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSNameScope.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSNameScope.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSScope.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSScope.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSString.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSString.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSStringJoiner.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSStringJoiner.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSSymbolTableObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSSymbolTableObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSType.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSTypeInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSValue.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSValue.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSValueInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSVariableObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSVariableObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSWrapperObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSWrapperObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\LiteralParser.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\LiteralParser.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Lookup.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Lookup.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\MathObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\MathObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NameConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NameConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NameInstance.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NameInstance.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NamePrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NamePrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NativeErrorConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NativeErrorConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NativeErrorPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NativeErrorPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumberConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumberConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumberObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumberObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumberPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumberPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\NumericStrings.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ObjectConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ObjectConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ObjectPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ObjectPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Operations.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Operations.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Options.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Options.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyDescriptor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyDescriptor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyMapHashTable.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyNameArray.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyNameArray.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertyOffset.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertySlot.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\PropertySlot.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Protect.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExp.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExp.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpCache.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpCache.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpCachedResult.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpCachedResult.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpKey.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpMatchesArray.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpMatchesArray.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\RegExpPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SamplingCounter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SamplingCounter.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SmallStrings.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SmallStrings.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StrictEvalActivation.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StrictEvalActivation.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringObject.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringPrototype.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringPrototype.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringRecursionChecker.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StringRecursionChecker.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Structure.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Structure.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StructureChain.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StructureChain.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\StructureTransitionTable.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SymbolTable.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\SymbolTable.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\Terminator.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\TimeoutChecker.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\TimeoutChecker.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\TypedArrayDescriptor.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\WeakGCMap.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\WeakRandom.h"
- >
- </File>
- </Filter>
- <Filter
- Name="API"
- >
- <File
- RelativePath="..\..\API\APICast.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JavaScript.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JavaScriptCore.h"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSAPIValueWrapper.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSAPIValueWrapper.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSBase.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSBase.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSBasePrivate.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackFunction.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackFunction.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackObject.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSCallbackObjectFunctions.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSClassRef.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSClassRef.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSContextRef.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSContextRef.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSContextRefPrivate.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSObjectRef.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSObjectRef.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSRetainPtr.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSStringRef.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSStringRef.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSStringRefBSTR.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSStringRefBSTR.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSStringRefCF.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSStringRefCF.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSValueRef.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSValueRef.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSWeakObjectMapRefInternal.h"
- >
- </File>
- <File
- RelativePath="..\..\API\JSWeakObjectMapRefPrivate.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\JSWeakObjectMapRefPrivate.h"
- >
- </File>
- <File
- RelativePath="..\..\API\OpaqueJSString.cpp"
- >
- </File>
- <File
- RelativePath="..\..\API\OpaqueJSString.h"
- >
- </File>
- <File
- RelativePath="..\..\API\WebKitAvailability.h"
- >
- </File>
- </Filter>
- <Filter
- Name="profiler"
- >
- <File
- RelativePath="..\..\profiler\CallIdentifier.h"
- >
- </File>
- <File
- RelativePath="..\..\profiler\Profile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\profiler\Profile.h"
- >
- </File>
- <File
- RelativePath="..\..\profiler\ProfileGenerator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\profiler\ProfileGenerator.h"
- >
- </File>
- <File
- RelativePath="..\..\profiler\ProfileNode.cpp"
- >
- </File>
- <File
- RelativePath="..\..\profiler\ProfileNode.h"
- >
- </File>
- <File
- RelativePath="..\..\profiler\Profiler.cpp"
- >
- </File>
- <File
- RelativePath="..\..\profiler\Profiler.h"
- >
- </File>
- </Filter>
- <Filter
- Name="tools"
- >
- <File
- RelativePath="..\..\tools\CodeProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\tools\CodeProfile.h"
- >
- </File>
- <File
- RelativePath="..\..\tools\CodeProfiling.cpp"
- >
- </File>
- <File
- RelativePath="..\..\tools\CodeProfiling.h"
- >
- </File>
- <File
- RelativePath="..\..\tools\ProfileTreeNode.h"
- >
- </File>
- <File
- RelativePath="..\..\tools\TieredMMapArray.h"
- >
- </File>
- </Filter>
- <Filter
- Name="bytecode"
- >
- <File
- RelativePath="..\..\bytecode\ArrayAllocationProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ArrayAllocationProfile.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ArrayProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ArrayProfile.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ByValInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CallLinkInfo.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CallLinkInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CallLinkStatus.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CallLinkStatus.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CallReturnOffsetToBytecodeOffset.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeBlock.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeBlock.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeBlockHash.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeBlockHash.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeBlockWithJITType.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeOrigin.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeOrigin.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeType.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\CodeType.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\Comment.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\EvalCodeCache.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ExecutionCounter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ExpressionRangeInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\GetByIdStatus.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\GetByIdStatus.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\GlobalResolveInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\HandlerInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\Instruction.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\JumpTable.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\JumpTable.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\LazyOperandValueProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\LazyOperandValueProfile.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\LineInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\MethodOfGettingAValueProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\MethodOfGettingAValueProfile.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\Opcode.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\Opcode.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\PolymorphicPutByIdList.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\SpecialPointer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\SpecialPointer.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\SpeculatedType.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\SpeculatedType.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\PutByIdStatus.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\PutByIdStatus.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\SamplingTool.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\SamplingTool.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\StructureStubClearingWatchpoint.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\StructureStubClearingWatchpoint.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\StructureStubInfo.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\StructureStubInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\UnlinkedCodeBlock.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\UnlinkedCodeBlock.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\ValueProfile.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\Watchpoint.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecode\Watchpoint.h"
- >
- </File>
- </Filter>
- <Filter
- Name="debugger"
- >
- <File
- RelativePath="..\..\debugger\Debugger.cpp"
- >
- </File>
- <File
- RelativePath="..\..\debugger\Debugger.h"
- >
- </File>
- <File
- RelativePath="..\..\debugger\DebuggerActivation.cpp"
- >
- </File>
- <File
- RelativePath="..\..\debugger\DebuggerActivation.h"
- >
- </File>
- <File
- RelativePath="..\..\debugger\DebuggerCallFrame.cpp"
- >
- </File>
- <File
- RelativePath="..\..\debugger\DebuggerCallFrame.h"
- >
- </File>
- </Filter>
- <Filter
- Name="assembler"
- >
- <File
- RelativePath="..\..\assembler\AbstractMacroAssembler.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\AssemblerBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\CodeLocation.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\LinkBuffer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\assembler\LinkBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\MacroAssembler.cpp"
- >
- </File>
- <File
- RelativePath="..\..\assembler\MacroAssembler.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\MacroAssemblerX86.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\MacroAssemblerX86Common.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\RepatchBuffer.h"
- >
- </File>
- <File
- RelativePath="..\..\assembler\X86Assembler.h"
- >
- </File>
- </Filter>
- <Filter
- Name="dfg"
- >
- <File
- RelativePath="..\..\dfg\DFGDriver.h"
- >
- </File>
- <File
- RelativePath="..\..\dfg\DFGIntrinsic.h"
- >
- </File>
- <File
- RelativePath="..\..\dfg\DFGOSREntry.h"
- >
- </File>
- </Filter>
- <Filter
- Name="yarr"
- >
- <File
- RelativePath="..\..\yarr\Yarr.h"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrCanonicalizeUCS2.cpp"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrCanonicalizeUCS2.h"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrInterpreter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrInterpreter.h"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrJIT.cpp"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrJIT.h"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrParser.h"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrPattern.cpp"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrPattern.h"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrSyntaxChecker.cpp"
- >
- </File>
- <File
- RelativePath="..\..\yarr\YarrSyntaxChecker.h"
- >
- </File>
- </Filter>
- <Filter
- Name="jit"
- >
- <File
- RelativePath="..\..\jit\ClosureCallStubRoutine.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\ClosureCallStubRoutine.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\ExecutableAllocator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\ExecutableAllocator.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\HostCallReturnValue.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\GCAwareJITStubRoutine.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\GCAwareJITStubRoutine.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JIT.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JIT.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITArithmetic.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITArithmetic32_64.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITCall.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITCall32_64.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITCode.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITCode.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITDisassembler.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITDisassembler.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITExceptions.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITExceptions.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITOpcodes.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITOpcodes32_64.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITPropertyAccess.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITPropertyAccess32_64.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITStubCall.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITStubRoutine.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITStubRoutine.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITStubs.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JITStubs.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JumpReplacementWatchpoint.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\JumpReplacementWatchpoint.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\JSInterfaceJIT.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\SpecializedThunkJIT.h"
- >
- </File>
- <File
- RelativePath="..\..\jit\ThunkGenerators.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jit\ThunkGenerators.h"
- >
- </File>
- </Filter>
- <Filter
- Name="llint"
- >
- <File
- RelativePath="..\..\llint\LLIntCLoop.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntCLoop.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntCommon.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntData.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntData.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntEntrypoints.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntEntrypoints.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntExceptions.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntExceptions.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntOfflineAsmConfig.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntOpcode.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntSlowPaths.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntSlowPaths.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntThunks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LLIntThunks.h"
- >
- </File>
- <File
- RelativePath="..\..\llint\LowLevelInterpreter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\llint\LowLevelInterpreter.h"
- >
- </File>
- </Filter>
- <Filter
- Name="disassembler"
- >
- <File
- RelativePath="..\..\disassembler\Disassembler.cpp"
- >
- </File>
- <File
- RelativePath="..\..\disassembler\Disassembler.h"
- >
- </File>
- </Filter>
- <Filter
- Name="interpreter"
- >
- <File
- RelativePath="..\..\interpreter\AbstractPC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\AbstractPC.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\CachedCall.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\CallFrame.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\CallFrame.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\CallFrameClosure.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\Interpreter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\Interpreter.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\JSStack.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\JSStack.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\Register.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\VMInspector.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\VMInspector.h"
- >
- </File>
- </Filter>
- <Filter
- Name="bytecompiler"
- >
- <File
- RelativePath="..\..\bytecompiler\BytecodeGenerator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecompiler\BytecodeGenerator.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecompiler\Label.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecompiler\LabelScope.h"
- >
- </File>
- <File
- RelativePath="..\..\bytecompiler\NodesCodegen.cpp"
- >
- </File>
- <File
- RelativePath="..\..\bytecompiler\RegisterID.h"
- >
- </File>
- </Filter>
- <Filter
- Name="parser"
- >
- <File
- RelativePath="..\..\parser\ASTBuilder.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\Lexer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\parser\Lexer.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\NodeConstructors.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\NodeInfo.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\Nodes.cpp"
- >
- </File>
- <File
- RelativePath="..\..\parser\Nodes.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\Parser.cpp"
- >
- </File>
- <File
- RelativePath="..\..\parser\Parser.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\ParserModes.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\ParserArena.cpp"
- >
- </File>
- <File
- RelativePath="..\..\parser\ParserArena.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\ResultType.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\SourceCode.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\SourceProvider.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\SourceProviderCache.cpp"
- >
- </File>
- <File
- RelativePath="..\..\parser\SourceProviderCache.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\SourceProviderCacheItem.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\SyntaxChecker.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Derived Sources"
- >
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\DatePrototype.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\lexer.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\MathObject.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\NamePrototype.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\NumberConstructor.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\RegExpConstructor.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\RegExpObject.lut.h"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\obj\$(ProjectName)\DerivedSources\StringPrototype.lut.h"
- >
- </File>
- </Filter>
- <Filter
- Name="heap"
- >
- <File
- RelativePath="..\..\heap\ConservativeRoots.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\ConservativeRoots.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopiedAllocator.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopiedBlock.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopiedSpace.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopiedSpace.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopiedSpaceInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopyVisitor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopyVisitor.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\CopyVisitorInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\DFGCodeBlocks.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\DFGCodeBlocks.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\GCAssertions.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\Handle.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\HandleSet.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\HandleSet.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\HeapTimer.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\HeapTimer.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\JITStubRoutineSet.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\JITStubRoutineSet.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\IncrementalSweeper.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\IncrementalSweeper.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakBlock.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakBlock.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakSet.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakSet.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakSetInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakImpl.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakHandleOwner.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\WeakHandleOwner.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\HandleStack.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\HandleStack.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\BlockAllocator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\BlockAllocator.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\GCThread.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\GCThread.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\GCThreadSharedData.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\GCThreadSharedData.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\Heap.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\Heap.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\HeapBlock.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\HeapRootVisitor.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\HeapStatistics.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\HeapStatistics.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\Local.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\LocalScope.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\MachineStackMarker.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\MachineStackMarker.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkedAllocator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkedAllocator.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkedBlock.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkedBlock.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkedSpace.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkedSpace.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkStack.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkStack.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\MarkStackInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\SlotVisitor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\Strong.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\StrongInlines.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\VTableSpectrum.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\VTableSpectrum.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\Weak.h"
- >
- </File>
- <File
- RelativePath="..\..\heap\WriteBarrierSupport.cpp"
- >
- </File>
- <File
- RelativePath="..\..\heap\WriteBarrierSupport.h"
- >
- </File>
- </Filter>
- <File
- RelativePath="..\..\config.h"
- >
- </File>
- <File
- RelativePath=".\JavaScriptCore.def"
- >
- </File>
- <File
- RelativePath=".\JavaScriptCore_debug.def"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCF.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCF.vsprops
deleted file mode 100644
index fe884aa43..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCF.vsprops
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreCF"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="CoreFoundation$(LibraryConfigSuffix).lib"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCFLite.vsprops
deleted file mode 100644
index 8c9e31f47..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCFLite.vsprops
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreCFLite"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="CFLite$(WebKitConfigSuffix).lib"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
deleted file mode 100644
index 236dd7b0e..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreCommon"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../parser/;../../bytecompiler/;../../dfg/;../../disassembler;../../jit/;../../llint/;../../runtime/;../../tools/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../heap/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include\private\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
- PreprocessorDefinitions="STATICALLY_LINKED_WITH_WTF;__STD_C"
- ForcedIncludeFiles="ICUVersion.h"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="gdi32.lib oleaut32.lib winmm.lib libicuin$(LibraryConfigSuffix).lib libicuuc$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib WTF$(WebKitConfigSuffix).lib"
- OutputFile="$(OutDir)\$(ProjectName)$(WebKitDLLConfigSuffix).dll"
- AdditionalLibraryDirectories="&quot;$(IntDir)\lib&quot;"
- ModuleDefinitionFile="JavaScriptCore.def"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops
deleted file mode 100644
index 6de574be5..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebug.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops
deleted file mode 100644
index 90223be1a..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugAll.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreDebugAll"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops
deleted file mode 100644
index 4238d1572..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreDebugCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreDebugCairoCFLite"
- 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;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
deleted file mode 100644
index 394f2b8aa..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGenerated"
- ProjectGUID="{4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}"
- RootNamespace="JavaScriptCoreGenerated"
- Keyword="MakeFileProj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedDebug.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedDebugAll.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedRelease.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedProduction.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedReleaseCairoCFLite.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedDebugCairoCFLite.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- ConfigurationType="0"
- InheritedPropertySheets=".\JavaScriptCoreGeneratedReleasePGO.vsprops"
- >
- <Tool
- Name="VCNMakeTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath=".\build-generated-files.sh"
- >
- </File>
- <File
- RelativePath=".\copy-files.cmd"
- >
- </File>
- <File
- RelativePath="..\..\DerivedSources.make"
- >
- </File>
- <File
- RelativePath=".\JavaScriptCoreGenerated.make"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedCommon.vsprops
deleted file mode 100644
index eb747a0ca..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedCommon.vsprops
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedCommon"
- 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 JavaScriptCoreGenerated.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 JavaScriptCoreGenerated.make clean&#x0D;&#x0A;nmake -f JavaScriptCoreGenerated.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 JavaScriptCoreGenerated.make clean"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebug.vsprops
deleted file mode 100644
index 5bee6ea49..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebug.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugAll.vsprops
deleted file mode 100644
index 61e5c297b..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugAll.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedDebugAll"
- 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;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugCairoCFLite.vsprops
deleted file mode 100644
index 5bd330bd8..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedDebugCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedDebugCairoCFLite"
- 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;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedProduction.vsprops
deleted file mode 100644
index 6fbc585d6..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedProduction.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedProduction"
- 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;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedRelease.vsprops
deleted file mode 100644
index 5e9c39950..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedRelease.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedRelease"
- 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;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleaseCairoCFLite.vsprops
deleted file mode 100644
index d0f5b47e3..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleaseCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedReleaseCairoCFLite"
- 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;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleasePGO.vsprops
deleted file mode 100644
index 649ec1fb8..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGeneratedReleasePGO.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreGeneratedReleasePGO"
- 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;.\JavaScriptCoreGeneratedCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePGOOptimize.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePGOOptimize.vsprops
deleted file mode 100644
index 647b3ac18..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePGOOptimize.vsprops
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCorePGOOptimize"
- >
- <Tool
- Name="VCLinkerTool"
- ImportLibrary="$(WebKitOutputDir)\Release_PGO\lib\$(TargetName).lib"
- />
- <UserMacro
- Name="ConfigurationBuildDir"
- Value="$(WebKitOutputDir)\Release_PGO"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePostBuild.cmd
deleted file mode 100644
index 233c45cb5..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePostBuild.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-if exist "%WEBKITLIBRARIESDIR%\tools\VersionStamper\VersionStamper.exe" "%WEBKITLIBRARIESDIR%\tools\VersionStamper\VersionStamper.exe" --verbose "%TARGETPATH%"
-if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreLink.cmd
deleted file mode 100644
index 3ff506931..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreLink.cmd
+++ /dev/null
@@ -1,9 +0,0 @@
-mkdir 2>NUL "%IntDir%\lib"
-
-if exist "%WebKitLibrariesDir%\lib\icuuc%LibraryConfigSuffix%.lib" copy /y "%WebKitLibrariesDir%\lib\icuuc%LibraryConfigSuffix%.lib" "%IntDir%\lib\libicuuc%LibraryConfigSuffix%.lib"
-if exist "%WebKitLibrariesDir%\lib\icuin%LibraryConfigSuffix%.lib" copy /y "%WebKitLibrariesDir%\lib\icuin%LibraryConfigSuffix%.lib" "%IntDir%\lib\libicuin%LibraryConfigSuffix%.lib"
-
-if exist "%WebKitLibrariesDir%\lib\libicuuc%LibraryConfigSuffix%.lib" copy /y "%WebKitLibrariesDir%\lib\libicuuc%LibraryConfigSuffix%.lib" "%IntDir%\lib"
-if exist "%WebKitLibrariesDir%\lib\libicuin%LibraryConfigSuffix%.lib" copy /y "%WebKitLibrariesDir%\lib\libicuin%LibraryConfigSuffix%.lib" "%IntDir%\lib"
-
-cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops
deleted file mode 100644
index 0822117f5..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreProduction.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreProduction"
- 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;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops
deleted file mode 100644
index 614c7a0d9..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreRelease.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreRelease"
- 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;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops
deleted file mode 100644
index 05f1b77c9..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleaseCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreReleaseCairoCFLite"
- 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;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops
deleted file mode 100644
index c17193942..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGO.vsprops
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreReleasePGO"
- 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;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalLibraryDirectories="&quot;$(ConfigurationBuildDir)\..\Production\lib&quot;"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\..\Production\include\private&quot;"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops
deleted file mode 100644
index 0c7c2d3c7..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreReleasePGOOptimize.vsprops
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="JavaScriptCoreReleasePGOOptimize"
- 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;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;.\JavaScriptCorePGOOptimize.vsprops"
- >
- <Tool
- Name="VCLinkerTool"
- AdditionalLibraryDirectories="&quot;$(ConfigurationBuildDir)\..\Production\lib&quot;"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
deleted file mode 100644
index a706a9c51..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln
+++ /dev/null
@@ -1,80 +0,0 @@
-
-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
- {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}"
-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
-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
- EndGlobalSection
- 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
- {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
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release_PGO|Win32.Build.0 = Release_PGO|Win32
- {4FF5BA11-59EC-4C24-8F52-F235C2E7D43A}.Release|Win32.ActiveCfg = Release|Win32
- {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
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj
deleted file mode 100644
index ed6aae895..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj
+++ /dev/null
@@ -1,173 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntAssembly"
- ProjectGUID="{9221744B-5715-4F56-9590-42F7AB23DD8B}"
- RootNamespace="LLIntAssembly"
- Keyword="MakeFileProj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntAssembly.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 LLIntAssembly.make clean&#x0D;&#x0A;nmake -f LLIntAssembly.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 LLIntAssembly.make clean"
- Output="LLIntAssembly.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath=".\build-LLIntAssembly.sh"
- >
- </File>
- <File
- RelativePath=".\LLIntAssembly.make"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj
deleted file mode 100644
index 0ece351b0..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj
+++ /dev/null
@@ -1,173 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntDesiredOffsets"
- ProjectGUID="{877150A0-41B3-4730-9D98-1B8298098B14}"
- RootNamespace="LLIntDesiredOffsets"
- Keyword="MakeFileProj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="0"
- >
- <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 LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean&#x0D;&#x0A;nmake -f LLIntDesiredOffsets.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 LLIntDesiredOffsets.make clean"
- Output="LLIntDesiredOffsets.h"
- PreprocessorDefinitions=""
- IncludeSearchPath=""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath=".\build-LLIntDesiredOffsets.sh"
- >
- </File>
- <File
- RelativePath=".\LLIntDesiredOffsets.make"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj
deleted file mode 100644
index 4862b658a..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj
+++ /dev/null
@@ -1,476 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractor"
- ProjectGUID="{D595E3F6-24F2-4C60-935C-95D50C6B3E96}"
- RootNamespace="LLIntOffsetsExtractor"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorDebug.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorRelease.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorDebugCairoCFLite.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorDebugAll.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorProduction.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorReleaseCairoCFLite.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- OutputDirectory="$(ConfigurationBuildDir)\obj\LLIntOffsetsExtractor"
- IntermediateDirectory="$(ConfigurationBuildDir)\obj\$(ProjectName)"
- ConfigurationType="1"
- InheritedPropertySheets=".\LLIntOffsetsExtractorReleasePGO.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="0"
- >
- <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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\..\llint\LLIntOffsetsExtractor.cpp"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops
deleted file mode 100644
index 6340081d9..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorCommon"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include\private\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../assembler/;../../API/;../../parser/;../../heap/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;../../jit/;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
- PreprocessorDefinitions="__STD_C"
- ForcedIncludeFiles="ICUVersion.h"
- ForcedUsingFiles=""
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="libicuin$(LibraryConfigSuffix).lib libicuuc$(LibraryConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib user32.lib WTF$(WebKitConfigSuffix).lib"
- AdditionalLibraryDirectories="&quot;$(IntDir)\lib&quot;"
- SubSystem="1"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops
deleted file mode 100644
index 69c0a2738..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\LLIntOffsetsExtractorCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops
deleted file mode 100644
index e508f9160..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorDebugAll"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\LLIntOffsetsExtractorCommon.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops
deleted file mode 100644
index 33804ca90..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorDebugCairoCFLite"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\LLIntOffsetsExtractorCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops
deleted file mode 100644
index 3683199fd..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorProduction"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\LLIntOffsetsExtractorCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops
deleted file mode 100644
index b2f4e872d..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorRelease"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\LLIntOffsetsExtractorCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops
deleted file mode 100644
index 4adb12216..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorReleaseCairoCFLite"
- InheritedPropertySheets="$(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;.\LLIntOffsetsExtractorCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops
deleted file mode 100644
index 331f96af2..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="LLIntOffsetsExtractorReleasePGO"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\LLIntOffsetsExtractorCommon.vsprops"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\..\Production\include\private&quot;;&quot;$(ConfigurationBuildDir)\..\Production\include\private\wtf\text&quot;"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
deleted file mode 100644
index 5997d9f93..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
+++ /dev/null
@@ -1,473 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="jsc"
- ProjectGUID="{C59E5129-B453-49B7-A52B-1E104715F76E}"
- RootNamespace="jsc"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscDebug.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscRelease.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscDebugCairoCFLite.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscDebugAll.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscProduction.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscReleaseCairoCFLite.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\jscReleasePGO.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\AtomicString.cpp"
- >
- </File>
- <File
- RelativePath="..\..\jsc.cpp"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\StringBuilder.cpp"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\StringImpl.cpp"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\WTFString.cpp"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
deleted file mode 100644
index 9bb7fe93a..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscCommon"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include\private\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../assembler/;../../API/;../../parser/;../../heap/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;../../jit/;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
- PreprocessorDefinitions="__STD_C"
- ForcedIncludeFiles="ICUVersion.h"
- ForcedUsingFiles=""
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib libicuin$(LibraryConfigSuffix).lib libicuuc$(LibraryConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib user32.lib"
- AdditionalLibraryDirectories="&quot;$(IntDir)\lib&quot;"
- SubSystem="1"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops
deleted file mode 100644
index f2765fba4..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebug.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\jscCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops
deleted file mode 100644
index 4a2727d0d..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugAll.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscDebugAll"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\jscCommon.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops
deleted file mode 100644
index 5f0db2314..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscDebugCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscDebugCairoCFLite"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\jscCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPostBuild.cmd
deleted file mode 100644
index 4dafacbbc..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPostBuild.cmd
+++ /dev/null
@@ -1,25 +0,0 @@
-if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
-
-mkdir 2>NUL "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt46.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt46.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt46%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt46%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt44.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt44.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt44%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt44%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\libicuin%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\libicuin%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\libicuuc%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\libicuuc%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt40.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt40.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt40%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt40%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuin40%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuin40%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuuc40%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuuc40%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt42.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt42.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt42%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt42%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuin42%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuin42%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuuc42%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuuc42%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\CoreFoundation%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\CoreFoundation%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\CoreFoundation.resources" xcopy /y /d /e /i "%WEBKITLIBRARIESDIR%\bin\CoreFoundation.resources" "%CONFIGURATIONBUILDDIR%\bin\CoreFoundation.resources"
-if exist "%WEBKITLIBRARIESDIR%\bin\pthreadVC2%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\pthreadVC2%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\objc%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\objc%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\ASL%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\ASL%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\libdispatch%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\libdispatch%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-
-cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreLink.cmd
deleted file mode 100644
index 85230262d..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreLink.cmd
+++ /dev/null
@@ -1,9 +0,0 @@
-mkdir 2>NUL "%INTDIR%\lib"
-
-if exist "%WEBKITLIBRARIESDIR%\lib\icuuc%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\icuuc%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib"
-if exist "%WEBKITLIBRARIESDIR%\lib\icuin%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\icuin%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib"
-
-if exist "%WEBKITLIBRARIESDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib"
-if exist "%WEBKITLIBRARIESDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib"
-
-cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops
deleted file mode 100644
index f450e5520..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscProduction.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscProduction"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\jscCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops
deleted file mode 100644
index b3dbed9a6..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscRelease.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscRelease"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\jscCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops
deleted file mode 100644
index 29b0e5527..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleaseCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscReleaseCairoCFLite"
- InheritedPropertySheets="$(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;.\jscCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops
deleted file mode 100644
index 800a821bb..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscReleasePGO.vsprops
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="jscReleasePGO"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\jscCommon.vsprops"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\..\Production\include\private&quot;;&quot;$(ConfigurationBuildDir)\..\Production\include\private\wtf\text&quot;"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj
deleted file mode 100755
index 9362d775a..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExp.vcproj
+++ /dev/null
@@ -1,480 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExp"
- ProjectGUID="{14C94979-1ED3-4E1D-9B55-A80FCF4677D0}"
- RootNamespace="testRegExp"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpDebug.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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpRelease.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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpDebugCairoCFLite.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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpDebugAll.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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpProduction.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpReleaseCairoCFLite.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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_PGO|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testRegExpReleasePGO.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="VCLinkerTool"
- AdditionalOptions="/SAFESEH"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\AtomicString.cpp"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\StringBuilder.cpp"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\StringImpl.cpp"
- >
- </File>
- <File
- RelativePath="..\..\testRegExp.cpp"
- >
- </File>
- <File
- RelativePath="$(ConfigurationBuildDir)\include\private\wtf\text\WTFString.cpp"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpCommon.vsprops
deleted file mode 100755
index 2e8edfb49..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpCommon.vsprops
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpCommon"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(ConfigurationBuildDir)\include\private\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../assembler/;../../API/;../../parser/;../../heap/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;../../jit/;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
- PreprocessorDefinitions="__STD_C"
- ForcedIncludeFiles="ICUVersion.h"
- ForcedUsingFiles=""
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib libicuin$(LibraryConfigSuffix).lib libicuuc$(LibraryConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib user32.lib"
- AdditionalLibraryDirectories="&quot;$(IntDir)\lib&quot;"
- SubSystem="1"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebug.vsprops
deleted file mode 100755
index e71f2e7ce..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebug.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\testRegExpCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugAll.vsprops
deleted file mode 100755
index 5590713ea..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugAll.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpDebugAll"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\testRegExpCommon.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugCairoCFLite.vsprops
deleted file mode 100755
index fddb47257..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpDebugCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpDebugCairoCFLite"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\testRegExpCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPostBuild.cmd
deleted file mode 100755
index 4dafacbbc..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPostBuild.cmd
+++ /dev/null
@@ -1,25 +0,0 @@
-if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
-
-mkdir 2>NUL "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt46.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt46.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt46%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt46%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt44.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt44.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt44%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt44%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\libicuin%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\libicuin%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\libicuuc%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\libicuuc%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt40.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt40.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt40%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt40%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuin40%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuin40%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuuc40%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuuc40%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt42.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt42.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icudt42%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icudt42%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuin42%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuin42%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\icuuc42%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\icuuc42%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\CoreFoundation%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\CoreFoundation%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\CoreFoundation.resources" xcopy /y /d /e /i "%WEBKITLIBRARIESDIR%\bin\CoreFoundation.resources" "%CONFIGURATIONBUILDDIR%\bin\CoreFoundation.resources"
-if exist "%WEBKITLIBRARIESDIR%\bin\pthreadVC2%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\pthreadVC2%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\objc%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\objc%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\ASL%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\ASL%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-if exist "%WEBKITLIBRARIESDIR%\bin\libdispatch%LIBRARYCONFIGSUFFIX%.dll" xcopy /y /d "%WEBKITLIBRARIESDIR%\bin\libdispatch%LIBRARYCONFIGSUFFIX%.dll" "%CONFIGURATIONBUILDDIR%\bin"
-
-cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreLink.cmd
deleted file mode 100755
index 85230262d..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreLink.cmd
+++ /dev/null
@@ -1,9 +0,0 @@
-mkdir 2>NUL "%INTDIR%\lib"
-
-if exist "%WEBKITLIBRARIESDIR%\lib\icuuc%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\icuuc%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib"
-if exist "%WEBKITLIBRARIESDIR%\lib\icuin%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\icuin%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib"
-
-if exist "%WEBKITLIBRARIESDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib"
-if exist "%WEBKITLIBRARIESDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib"
-
-cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpProduction.vsprops
deleted file mode 100755
index d6d7a9fd2..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpProduction.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpProduction"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\testRegExpCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpRelease.vsprops
deleted file mode 100755
index d34a44e4c..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpRelease.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpRelease"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\testRegExpCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleaseCairoCFLite.vsprops
deleted file mode 100755
index 2f0199486..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleaseCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpReleaseCairoCFLite"
- InheritedPropertySheets="$(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;.\testRegExpCommon.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleasePGO.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleasePGO.vsprops
deleted file mode 100755
index 771999f24..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpReleasePGO.vsprops
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testRegExpReleasePGO"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\testRegExpCommon.vsprops"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ConfigurationBuildDir)\..\Production\include\private&quot;;&quot;$(ConfigurationBuildDir)\..\Production\include\private\wtf\text&quot;"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
deleted file mode 100644
index de9518e16..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
+++ /dev/null
@@ -1,448 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapi"
- ProjectGUID="{1AFD081F-1AC7-4A97-8EFA-6DF97761A3A2}"
- RootNamespace="testapi"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testapiDebug.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testapiRelease.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_Cairo_CFLite|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testapiDebugCairoCFLite.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release_Cairo_CFLite|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testapiReleaseCairoCFLite.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug_All|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testapiDebugAll.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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Production|Win32"
- ConfigurationType="1"
- InheritedPropertySheets=".\testapiProduction.vsprops"
- CharacterSet="1"
- WholeProgramOptimization="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="VCLinkerTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <File
- RelativePath="..\..\API\tests\testapi.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- CompileAs="2"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- CompileAs="2"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo_CFLite|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- CompileAs="2"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo_CFLite|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- CompileAs="2"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_All|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- CompileAs="2"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Production|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- CompileAs="2"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\..\API\tests\testapi.js"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops
deleted file mode 100644
index a15d04d23..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiCommon"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)\..\..\API&quot;;&quot;$(ConfigurationBuildDir)\include\WebCore\ForwardingHeaders&quot;;&quot;$(ConfigurationBuildDir)\include\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include\private\JavaScriptCore&quot;;&quot;$(ConfigurationBuildDir)\include&quot;;&quot;$(ConfigurationBuildDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;"
- PreprocessorDefinitions="NOMINMAX"
- WarningLevel="4"
- Detect64BitPortabilityProblems="true"
- ForcedIncludeFiles="ICUVersion.h"
- />
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib WTF$(WebKitConfigSuffix).lib pthreadVC2$(LibraryConfigSuffix).lib libicuin$(LibraryConfigSuffix).lib libicuuc$(LibraryConfigSuffix).lib"
- AdditionalLibraryDirectories="&quot;$(IntDir)\lib&quot;"
- SubSystem="1"
- />
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops
deleted file mode 100644
index f17de961b..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebug.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiDebug"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops
deleted file mode 100644
index 9e5f2c515..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugAll.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiDebugAll"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_all.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops
deleted file mode 100644
index 821c88574..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiDebugCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiDebugCairoCFLite"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCFLite.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreLink.cmd
deleted file mode 100644
index 85230262d..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreLink.cmd
+++ /dev/null
@@ -1,9 +0,0 @@
-mkdir 2>NUL "%INTDIR%\lib"
-
-if exist "%WEBKITLIBRARIESDIR%\lib\icuuc%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\icuuc%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib"
-if exist "%WEBKITLIBRARIESDIR%\lib\icuin%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\icuin%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib"
-
-if exist "%WEBKITLIBRARIESDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\libicuuc%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib"
-if exist "%WEBKITLIBRARIESDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib" copy /y "%WEBKITLIBRARIESDIR%\lib\libicuin%LIBRARYCONFIGSUFFIX%.lib" "%INTDIR%\lib"
-
-cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops
deleted file mode 100644
index 4dbc0c185..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiProduction.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiProduction"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops
deleted file mode 100644
index 15ad84ffd..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiRelease.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiRelease"
- InheritedPropertySheets="$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops;$(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCF.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops b/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops
deleted file mode 100644
index 692de7447..000000000
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiReleaseCairoCFLite.vsprops
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="testapiReleaseCairoCFLite"
- InheritedPropertySheets="$(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;.\testapiCommon.vsprops;..\JavaScriptCore\JavaScriptCoreCFLite.vsprops"
- >
-</VisualStudioPropertySheet>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.make b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.make
new file mode 100644
index 000000000..311dfed53
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.make
@@ -0,0 +1,30 @@
+!IF defined(BUILDSTYLE) && "$(BUILDSTYLE)"=="DEBUG"
+BUILDSTYLE=DebugSuffix
+!ELSE
+BUILDSTYLE=Production
+!ENDIF
+
+install:
+ set OFFICIAL_BUILD=1
+ set WebKit_Libraries=$(SRCROOT)\AppleInternal
+ set WebKit_OutputDir=$(OBJROOT)
+ set ProgramFilesAAS=Program Files (x86)\Common Files\Apple\Apple Application Support
+ set Path=%PATH%;$(SRCROOT)\%ProgramFilesAAS%
+ set ConfigurationBuildDir=$(OBJROOT)\$(BUILDSTYLE)
+ -mkdir "%ConfigurationBuildDir%\include\private"
+ xcopy "%WebKit_Libraries%\include\private\*" "%ConfigurationBuildDir%\include\private" /e/v/i/h/y
+ devenv "JavaScriptCore.submit.sln" /clean $(BUILDSTYLE)
+ devenv "JavaScriptCore.submit.sln" /build $(BUILDSTYLE)
+ -xcopy "%ConfigurationBuildDir%\bin32\JavaScriptCore.dll" "$(DSTROOT)\%ProgramFilesAAS%\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\JavaScriptCore_debug.dll" "$(DSTROOT)\%ProgramFilesAAS%\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\JavaScriptCore.pdb" "$(DSTROOT)\%ProgramFilesAAS%\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\JavaScriptCore_debug.pdb" "$(DSTROOT)\%ProgramFilesAAS%\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\jsc.exe" "$(DSTROOT)\AppleInternal\bin32\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\jsc_debug.exe" "$(DSTROOT)\AppleInternal\bin32\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\jsc.pdb" "$(DSTROOT)\AppleInternal\bin32\" /e/v/i/h/y
+ -xcopy "%ConfigurationBuildDir%\bin32\jsc_debug.pdb" "$(DSTROOT)\AppleInternal\bin32\" /e/v/i/h/y
+ xcopy "%ConfigurationBuildDir%\include\*" "$(DSTROOT)\AppleInternal\include\" /e/v/i/h/y
+ xcopy "%ConfigurationBuildDir%\lib32\*" "$(DSTROOT)\AppleInternal\lib32\" /e/v/i/h/y
+ xcopy "%ConfigurationBuildDir%\bin32\JavaScriptCore.resources\*" "$(DSTROOT)\%ProgramFilesAAS%\JavaScriptCore.resources" /e/v/i/h/y
+ -mkdir "$(DSTROOT)\AppleInternal\Sources32\JavaScriptCore"
+ xcopy "%ConfigurationBuildDir%\obj32\JavaScriptCore\DerivedSources\*" "$(DSTROOT)\AppleInternal\Sources32\JavaScriptCore" /e/v/i/h/y
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.resources/Info.plist
index 7de8638e2..f69d73f5a 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.resources/Info.plist
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>JavaScriptCore</string>
<key>CFBundleGetInfoString</key>
- <string>530, Copyright 2003-2010 Apple Inc.</string>
+ <string>530, Copyright 2003-2013 Apple Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.apple.JavaScriptCore</string>
<key>CFBundleInfoDictionaryVersion</key>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.submit.sln b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.submit.sln
new file mode 100644
index 000000000..296f59f7b
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.submit.sln
@@ -0,0 +1,78 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCore", "JavaScriptCore.vcxproj", "{22413D41-3A18-42B7-92A8-CEDC6CE86920}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3670D01F-95F3-45A8-B878-947EB6CF214E} = {3670D01F-95F3-45A8-B878-947EB6CF214E}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCoreGenerated", "JavaScriptCoreGenerated.vcxproj", "{3670D01F-95F3-45A8-B878-947EB6CF214E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsc", "jsc\jsc.vcxproj", "{2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920} = {22413D41-3A18-42B7-92A8-CEDC6CE86920}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExp", "testRegExp\testRegExp.vcxproj", "{BB16286B-AADC-46C1-BC0D-6C06F323E04B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3} = {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testapi", "testapi\testapi.vcxproj", "{5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}"
+ ProjectSection(ProjectDependencies) = postProject
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B} = {BB16286B-AADC-46C1-BC0D-6C06F323E04B}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ DebugSuffix|Win32 = DebugSuffix|Win32
+ Production|Win32 = Production|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.Debug|Win32.ActiveCfg = Debug|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.Debug|Win32.Build.0 = Debug|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.Production|Win32.ActiveCfg = Production|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.Production|Win32.Build.0 = Production|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.Release|Win32.ActiveCfg = Release|Win32
+ {22413D41-3A18-42B7-92A8-CEDC6CE86920}.Release|Win32.Build.0 = Release|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.Debug|Win32.Build.0 = Debug|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.Production|Win32.ActiveCfg = Production|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.Production|Win32.Build.0 = Production|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.Release|Win32.ActiveCfg = Release|Win32
+ {3670D01F-95F3-45A8-B878-947EB6CF214E}.Release|Win32.Build.0 = Release|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.Debug|Win32.Build.0 = Debug|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.Production|Win32.ActiveCfg = Production|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.Production|Win32.Build.0 = Production|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.Release|Win32.ActiveCfg = Release|Win32
+ {2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}.Release|Win32.Build.0 = Release|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.Debug|Win32.Build.0 = Debug|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.Production|Win32.ActiveCfg = Production|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.Production|Win32.Build.0 = Production|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.Release|Win32.ActiveCfg = Release|Win32
+ {BB16286B-AADC-46C1-BC0D-6C06F323E04B}.Release|Win32.Build.0 = Release|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.Debug|Win32.Build.0 = Debug|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.DebugSuffix|Win32.ActiveCfg = DebugSuffix|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.DebugSuffix|Win32.Build.0 = DebugSuffix|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.Production|Win32.ActiveCfg = Production|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.Production|Win32.Build.0 = Production|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.Release|Win32.ActiveCfg = Release|Win32
+ {5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
new file mode 100644
index 000000000..907f28582
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
@@ -0,0 +1,931 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{22413D41-3A18-42B7-92A8-CEDC6CE86920}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>JavaScriptCore2</RootNamespace>
+ <ProjectName>JavaScriptCore</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreDebugCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreDebugCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreReleaseCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreReleaseCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreProduction.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreProduction.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\API\JSBase.cpp" />
+ <ClCompile Include="..\API\JSCallbackConstructor.cpp" />
+ <ClCompile Include="..\API\JSCallbackFunction.cpp" />
+ <ClCompile Include="..\API\JSCallbackObject.cpp" />
+ <ClCompile Include="..\API\JSClassRef.cpp" />
+ <ClCompile Include="..\API\JSContextRef.cpp" />
+ <ClCompile Include="..\API\JSObjectRef.cpp" />
+ <ClCompile Include="..\API\JSScriptRef.cpp" />
+ <ClCompile Include="..\API\JSStringRef.cpp" />
+ <ClCompile Include="..\API\JSStringRefBSTR.cpp" />
+ <ClCompile Include="..\API\JSStringRefCF.cpp" />
+ <ClCompile Include="..\API\JSValueRef.cpp" />
+ <ClCompile Include="..\API\JSWeakObjectMapRefPrivate.cpp" />
+ <ClCompile Include="..\API\OpaqueJSString.cpp" />
+ <ClCompile Include="..\assembler\LinkBuffer.cpp" />
+ <ClCompile Include="..\assembler\MacroAssembler.cpp" />
+ <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp" />
+ <ClCompile Include="..\bytecode\ArrayProfile.cpp" />
+ <ClCompile Include="..\bytecode\CallLinkInfo.cpp" />
+ <ClCompile Include="..\bytecode\CallLinkStatus.cpp" />
+ <ClCompile Include="..\bytecode\CodeBlock.cpp" />
+ <ClCompile Include="..\bytecode\CodeBlockHash.cpp" />
+ <ClCompile Include="..\bytecode\CodeOrigin.cpp" />
+ <ClCompile Include="..\bytecode\CodeType.cpp" />
+ <ClCompile Include="..\bytecode\ExecutionCounter.cpp" />
+ <ClCompile Include="..\bytecode\ExitKind.cpp" />
+ <ClCompile Include="..\bytecode\GetByIdStatus.cpp" />
+ <ClCompile Include="..\bytecode\JumpTable.cpp" />
+ <ClCompile Include="..\bytecode\LazyOperandValueProfile.cpp" />
+ <ClCompile Include="..\bytecode\MethodOfGettingAValueProfile.cpp" />
+ <ClCompile Include="..\bytecode\Opcode.cpp" />
+ <ClCompile Include="..\bytecode\PolymorphicPutByIdList.cpp" />
+ <ClCompile Include="..\bytecode\PutByIdStatus.cpp" />
+ <ClCompile Include="..\bytecode\ReduceWhitespace.cpp" />
+ <ClCompile Include="..\bytecode\SamplingTool.cpp" />
+ <ClCompile Include="..\bytecode\SpecialPointer.cpp" />
+ <ClCompile Include="..\bytecode\SpeculatedType.cpp" />
+ <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp" />
+ <ClCompile Include="..\bytecode\StructureStubInfo.cpp" />
+ <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" />
+ <ClCompile Include="..\bytecode\Watchpoint.cpp" />
+ <ClCompile Include="..\bytecompiler\BytecodeGenerator.cpp" />
+ <ClCompile Include="..\bytecompiler\NodesCodegen.cpp" />
+ <ClCompile Include="..\debugger\Debugger.cpp" />
+ <ClCompile Include="..\debugger\DebuggerActivation.cpp" />
+ <ClCompile Include="..\debugger\DebuggerCallFrame.cpp" />
+ <ClCompile Include="..\disassembler\Disassembler.cpp" />
+ <ClCompile Include="..\heap\BlockAllocator.cpp" />
+ <ClCompile Include="..\heap\ConservativeRoots.cpp" />
+ <ClCompile Include="..\heap\CopiedSpace.cpp" />
+ <ClCompile Include="..\heap\CopyVisitor.cpp" />
+ <ClCompile Include="..\heap\DFGCodeBlocks.cpp" />
+ <ClCompile Include="..\heap\GCThread.cpp" />
+ <ClCompile Include="..\heap\GCThreadSharedData.cpp" />
+ <ClCompile Include="..\heap\HandleSet.cpp" />
+ <ClCompile Include="..\heap\HandleStack.cpp" />
+ <ClCompile Include="..\heap\Heap.cpp" />
+ <ClCompile Include="..\heap\HeapStatistics.cpp" />
+ <ClCompile Include="..\heap\HeapTimer.cpp" />
+ <ClCompile Include="..\heap\IncrementalSweeper.cpp" />
+ <ClCompile Include="..\heap\JITStubRoutineSet.cpp" />
+ <ClCompile Include="..\heap\MachineStackMarker.cpp" />
+ <ClCompile Include="..\heap\MarkedAllocator.cpp" />
+ <ClCompile Include="..\heap\MarkedBlock.cpp" />
+ <ClCompile Include="..\heap\MarkedSpace.cpp" />
+ <ClCompile Include="..\heap\MarkStack.cpp" />
+ <ClCompile Include="..\heap\SlotVisitor.cpp" />
+ <ClCompile Include="..\heap\SuperRegion.cpp" />
+ <ClCompile Include="..\heap\VTableSpectrum.cpp" />
+ <ClCompile Include="..\heap\Weak.cpp" />
+ <ClCompile Include="..\heap\WeakBlock.cpp" />
+ <ClCompile Include="..\heap\WeakHandleOwner.cpp" />
+ <ClCompile Include="..\heap\WeakSet.cpp" />
+ <ClCompile Include="..\heap\WriteBarrierSupport.cpp" />
+ <ClCompile Include="..\interpreter\AbstractPC.cpp" />
+ <ClCompile Include="..\interpreter\CallFrame.cpp" />
+ <ClCompile Include="..\interpreter\Interpreter.cpp" />
+ <ClCompile Include="..\interpreter\JSStack.cpp" />
+ <ClCompile Include="..\interpreter\VMInspector.cpp" />
+ <ClCompile Include="..\jit\ClosureCallStubRoutine.cpp" />
+ <ClCompile Include="..\jit\ExecutableAllocator.cpp" />
+ <ClCompile Include="..\jit\GCAwareJITStubRoutine.cpp" />
+ <ClCompile Include="..\jit\HostCallReturnValue.cpp" />
+ <ClCompile Include="..\jit\JIT.cpp" />
+ <ClCompile Include="..\jit\JITArithmetic.cpp" />
+ <ClCompile Include="..\jit\JITArithmetic32_64.cpp" />
+ <ClCompile Include="..\jit\JITCall.cpp" />
+ <ClCompile Include="..\jit\JITCall32_64.cpp" />
+ <ClCompile Include="..\jit\JITCode.cpp" />
+ <ClCompile Include="..\jit\JITDisassembler.cpp" />
+ <ClCompile Include="..\jit\JITExceptions.cpp" />
+ <ClCompile Include="..\jit\JITOpcodes.cpp" />
+ <ClCompile Include="..\jit\JITOpcodes32_64.cpp" />
+ <ClCompile Include="..\jit\JITPropertyAccess.cpp" />
+ <ClCompile Include="..\jit\JITPropertyAccess32_64.cpp" />
+ <ClCompile Include="..\jit\JITStubRoutine.cpp" />
+ <ClCompile Include="..\jit\JITStubs.cpp" />
+ <ClCompile Include="..\jit\JITThunks.cpp" />
+ <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp" />
+ <ClCompile Include="..\jit\ThunkGenerators.cpp" />
+ <ClCompile Include="..\llint\LLIntCLoop.cpp" />
+ <ClCompile Include="..\llint\LLIntData.cpp" />
+ <ClCompile Include="..\llint\LLIntEntrypoints.cpp" />
+ <ClCompile Include="..\llint\LLIntExceptions.cpp" />
+ <ClCompile Include="..\llint\LLIntOffsetsExtractor.cpp" />
+ <ClCompile Include="..\llint\LLIntSlowPaths.cpp" />
+ <ClCompile Include="..\llint\LLIntThunks.cpp" />
+ <ClCompile Include="..\llint\LowLevelInterpreter.cpp" />
+ <ClCompile Include="..\parser\Lexer.cpp" />
+ <ClCompile Include="..\parser\Nodes.cpp" />
+ <ClCompile Include="..\parser\Parser.cpp" />
+ <ClCompile Include="..\parser\ParserArena.cpp" />
+ <ClCompile Include="..\parser\SourceProvider.cpp" />
+ <ClCompile Include="..\parser\SourceProviderCache.cpp" />
+ <ClCompile Include="..\profiler\LegacyProfiler.cpp" />
+ <ClCompile Include="..\profiler\Profile.cpp" />
+ <ClCompile Include="..\profiler\ProfileGenerator.cpp" />
+ <ClCompile Include="..\profiler\ProfileNode.cpp" />
+ <ClCompile Include="..\profiler\ProfilerBytecode.cpp" />
+ <ClCompile Include="..\profiler\ProfilerBytecodes.cpp" />
+ <ClCompile Include="..\profiler\ProfilerBytecodeSequence.cpp" />
+ <ClCompile Include="..\profiler\ProfilerCompilation.cpp" />
+ <ClCompile Include="..\profiler\ProfilerCompilationKind.cpp" />
+ <ClCompile Include="..\profiler\ProfilerCompiledBytecode.cpp" />
+ <ClCompile Include="..\profiler\ProfilerDatabase.cpp" />
+ <ClCompile Include="..\profiler\ProfilerOrigin.cpp" />
+ <ClCompile Include="..\profiler\ProfilerOriginStack.cpp" />
+ <ClCompile Include="..\profiler\ProfilerOSRExit.cpp" />
+ <ClCompile Include="..\profiler\ProfilerOSRExitSite.cpp" />
+ <ClCompile Include="..\profiler\ProfilerProfiledBytecodes.cpp" />
+ <ClCompile Include="..\runtime\ArgList.cpp" />
+ <ClCompile Include="..\runtime\Arguments.cpp" />
+ <ClCompile Include="..\runtime\ArrayConstructor.cpp" />
+ <ClCompile Include="..\runtime\ArrayPrototype.cpp" />
+ <ClCompile Include="..\runtime\BooleanConstructor.cpp" />
+ <ClCompile Include="..\runtime\BooleanObject.cpp" />
+ <ClCompile Include="..\runtime\BooleanPrototype.cpp" />
+ <ClCompile Include="..\runtime\CallData.cpp" />
+ <ClCompile Include="..\runtime\CodeCache.cpp" />
+ <ClCompile Include="..\runtime\CodeSpecializationKind.cpp" />
+ <ClCompile Include="..\runtime\CommonIdentifiers.cpp" />
+ <ClCompile Include="..\runtime\Completion.cpp" />
+ <ClCompile Include="..\runtime\ConstructData.cpp" />
+ <ClCompile Include="..\runtime\DateConstructor.cpp" />
+ <ClCompile Include="..\runtime\DateConversion.cpp" />
+ <ClCompile Include="..\runtime\DateInstance.cpp" />
+ <ClCompile Include="..\runtime\DatePrototype.cpp" />
+ <ClCompile Include="..\runtime\Error.cpp" />
+ <ClCompile Include="..\runtime\ErrorConstructor.cpp" />
+ <ClCompile Include="..\runtime\ErrorInstance.cpp" />
+ <ClCompile Include="..\runtime\ErrorPrototype.cpp" />
+ <ClCompile Include="..\runtime\ExceptionHelpers.cpp" />
+ <ClCompile Include="..\runtime\Executable.cpp" />
+ <ClCompile Include="..\runtime\FunctionConstructor.cpp" />
+ <ClCompile Include="..\runtime\FunctionPrototype.cpp" />
+ <ClCompile Include="..\runtime\GCActivityCallback.cpp" />
+ <ClCompile Include="..\runtime\GetterSetter.cpp" />
+ <ClCompile Include="..\runtime\Identifier.cpp" />
+ <ClCompile Include="..\runtime\IndexingType.cpp" />
+ <ClCompile Include="..\runtime\InitializeThreading.cpp" />
+ <ClCompile Include="..\runtime\InternalFunction.cpp" />
+ <ClCompile Include="..\runtime\JSActivation.cpp" />
+ <ClCompile Include="..\runtime\JSAPIValueWrapper.cpp" />
+ <ClCompile Include="..\runtime\JSArray.cpp" />
+ <ClCompile Include="..\runtime\JSBoundFunction.cpp" />
+ <ClCompile Include="..\runtime\JSCell.cpp" />
+ <ClCompile Include="..\runtime\JSCJSValue.cpp" />
+ <ClCompile Include="..\runtime\JSDateMath.cpp" />
+ <ClCompile Include="..\runtime\JSFunction.cpp" />
+ <ClCompile Include="..\runtime\VM.cpp" />
+ <ClCompile Include="..\runtime\JSGlobalObject.cpp" />
+ <ClCompile Include="..\runtime\JSGlobalObjectFunctions.cpp" />
+ <ClCompile Include="..\runtime\JSLock.cpp" />
+ <ClCompile Include="..\runtime\JSNameScope.cpp" />
+ <ClCompile Include="..\runtime\JSNotAnObject.cpp" />
+ <ClCompile Include="..\runtime\JSObject.cpp" />
+ <ClCompile Include="..\runtime\JSONObject.cpp" />
+ <ClCompile Include="..\runtime\JSPropertyNameIterator.cpp" />
+ <ClCompile Include="..\runtime\JSProxy.cpp" />
+ <ClCompile Include="..\runtime\JSScope.cpp" />
+ <ClCompile Include="..\runtime\JSSegmentedVariableObject.cpp" />
+ <ClCompile Include="..\runtime\JSString.cpp" />
+ <ClCompile Include="..\runtime\JSStringJoiner.cpp" />
+ <ClCompile Include="..\runtime\JSSymbolTableObject.cpp" />
+ <ClCompile Include="..\runtime\JSVariableObject.cpp" />
+ <ClCompile Include="..\runtime\JSWithScope.cpp" />
+ <ClCompile Include="..\runtime\JSWrapperObject.cpp" />
+ <ClCompile Include="..\runtime\LiteralParser.cpp" />
+ <ClCompile Include="..\runtime\Lookup.cpp" />
+ <ClCompile Include="..\runtime\MathObject.cpp" />
+ <ClCompile Include="..\runtime\NameConstructor.cpp" />
+ <ClCompile Include="..\runtime\NameInstance.cpp" />
+ <ClCompile Include="..\runtime\NamePrototype.cpp" />
+ <ClCompile Include="..\runtime\NativeErrorConstructor.cpp" />
+ <ClCompile Include="..\runtime\NativeErrorPrototype.cpp" />
+ <ClCompile Include="..\runtime\NumberConstructor.cpp" />
+ <ClCompile Include="..\runtime\NumberObject.cpp" />
+ <ClCompile Include="..\runtime\NumberPrototype.cpp" />
+ <ClCompile Include="..\runtime\ObjectConstructor.cpp" />
+ <ClCompile Include="..\runtime\ObjectPrototype.cpp" />
+ <ClCompile Include="..\runtime\Operations.cpp" />
+ <ClCompile Include="..\runtime\Options.cpp" />
+ <ClCompile Include="..\runtime\PropertyDescriptor.cpp" />
+ <ClCompile Include="..\runtime\PropertyNameArray.cpp" />
+ <ClCompile Include="..\runtime\PropertySlot.cpp" />
+ <ClCompile Include="..\runtime\PropertyTable.cpp" />
+ <ClCompile Include="..\runtime\PrototypeMap.cpp" />
+ <ClCompile Include="..\runtime\RegExp.cpp" />
+ <ClCompile Include="..\runtime\RegExpCache.cpp" />
+ <ClCompile Include="..\runtime\RegExpCachedResult.cpp" />
+ <ClCompile Include="..\runtime\RegExpConstructor.cpp" />
+ <ClCompile Include="..\runtime\RegExpMatchesArray.cpp" />
+ <ClCompile Include="..\runtime\RegExpObject.cpp" />
+ <ClCompile Include="..\runtime\RegExpPrototype.cpp" />
+ <ClCompile Include="..\runtime\SamplingCounter.cpp" />
+ <ClCompile Include="..\runtime\SmallStrings.cpp" />
+ <ClCompile Include="..\runtime\SparseArrayValueMap.cpp" />
+ <ClCompile Include="..\runtime\StrictEvalActivation.cpp" />
+ <ClCompile Include="..\runtime\StringConstructor.cpp" />
+ <ClCompile Include="..\runtime\StringObject.cpp" />
+ <ClCompile Include="..\runtime\StringPrototype.cpp" />
+ <ClCompile Include="..\runtime\StringRecursionChecker.cpp" />
+ <ClCompile Include="..\runtime\Structure.cpp" />
+ <ClCompile Include="..\runtime\StructureChain.cpp" />
+ <ClCompile Include="..\runtime\StructureRareData.cpp" />
+ <ClCompile Include="..\runtime\SymbolTable.cpp" />
+ <ClCompile Include="..\runtime\Watchdog.cpp" />
+ <ClCompile Include="..\runtime\WatchdogNone.cpp" />
+ <ClCompile Include="..\tools\CodeProfile.cpp" />
+ <ClCompile Include="..\tools\CodeProfiling.cpp" />
+ <ClCompile Include="..\yarr\YarrCanonicalizeUCS2.cpp" />
+ <ClCompile Include="..\yarr\YarrInterpreter.cpp" />
+ <ClCompile Include="..\yarr\YarrJIT.cpp" />
+ <ClCompile Include="..\yarr\YarrPattern.cpp" />
+ <ClCompile Include="..\yarr\YarrSyntaxChecker.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\BooleanPrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\DatePrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ErrorPrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\HeaderDetection.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\JSGlobalObject.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\JSONObject.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\Lexer.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\LLIntAssembly.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\NumberConstructor.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\NumberPrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ObjectConstructor.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ObjectPrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\RegExpConstructor.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\RegExpJitTables.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\RegExpPrototype.lut.h" />
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\StringConstructor.lut.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\API\APICast.h" />
+ <ClInclude Include="..\API\JavaScript.h" />
+ <ClInclude Include="..\API\JavaScriptCore.h" />
+ <ClInclude Include="..\API\JSAPIWrapperObject.h" />
+ <ClInclude Include="..\API\JSBase.h" />
+ <ClInclude Include="..\API\JSBasePrivate.h" />
+ <ClInclude Include="..\API\JSCallbackConstructor.h" />
+ <ClInclude Include="..\API\JSCallbackFunction.h" />
+ <ClInclude Include="..\API\JSCallbackObject.h" />
+ <ClInclude Include="..\API\JSCallbackObjectFunctions.h" />
+ <ClInclude Include="..\API\JSClassRef.h" />
+ <ClInclude Include="..\API\JSContext.h" />
+ <ClInclude Include="..\API\JSContextInternal.h" />
+ <ClInclude Include="..\API\JSContextRef.h" />
+ <ClInclude Include="..\API\JSContextRefPrivate.h" />
+ <ClInclude Include="..\API\JSExport.h" />
+ <ClInclude Include="..\API\JSObjectRef.h" />
+ <ClInclude Include="..\API\JSObjectRefPrivate.h" />
+ <ClInclude Include="..\API\JSRetainPtr.h" />
+ <ClInclude Include="..\API\JSScriptRefPrivate.h" />
+ <ClInclude Include="..\API\JSStringRef.h" />
+ <ClInclude Include="..\API\JSStringRefBSTR.h" />
+ <ClInclude Include="..\API\JSStringRefCF.h" />
+ <ClInclude Include="..\API\JSValue.h" />
+ <ClInclude Include="..\API\JSValueInternal.h" />
+ <ClInclude Include="..\API\JSValueRef.h" />
+ <ClInclude Include="..\API\JSWeakObjectMapRefInternal.h" />
+ <ClInclude Include="..\API\JSWeakObjectMapRefPrivate.h" />
+ <ClInclude Include="..\API\JSWrapperMap.h" />
+ <ClInclude Include="..\API\OpaqueJSString.h" />
+ <ClInclude Include="..\API\WebKitAvailability.h" />
+ <ClInclude Include="..\assembler\AbstractMacroAssembler.h" />
+ <ClInclude Include="..\assembler\AssemblerBuffer.h" />
+ <ClInclude Include="..\assembler\CodeLocation.h" />
+ <ClInclude Include="..\assembler\LinkBuffer.h" />
+ <ClInclude Include="..\assembler\MacroAssembler.h" />
+ <ClInclude Include="..\assembler\MacroAssemblerX86.h" />
+ <ClInclude Include="..\assembler\MacroAssemblerX86Common.h" />
+ <ClInclude Include="..\assembler\MacroAssemblerX86_64.h" />
+ <ClInclude Include="..\assembler\RepatchBuffer.h" />
+ <ClInclude Include="..\assembler\X86Assembler.h" />
+ <ClInclude Include="..\bytecode\ArrayAllocationProfile.h" />
+ <ClInclude Include="..\bytecode\ArrayProfile.h" />
+ <ClInclude Include="..\bytecode\ByValInfo.h" />
+ <ClInclude Include="..\bytecode\CallLinkInfo.h" />
+ <ClInclude Include="..\bytecode\CallLinkStatus.h" />
+ <ClInclude Include="..\bytecode\CallReturnOffsetToBytecodeOffset.h" />
+ <ClInclude Include="..\bytecode\CodeBlock.h" />
+ <ClInclude Include="..\bytecode\CodeBlockHash.h" />
+ <ClInclude Include="..\bytecode\CodeBlockWithJITType.h" />
+ <ClInclude Include="..\bytecode\CodeOrigin.h" />
+ <ClInclude Include="..\bytecode\CodeType.h" />
+ <ClInclude Include="..\bytecode\Comment.h" />
+ <ClInclude Include="..\bytecode\DataFormat.h" />
+ <ClInclude Include="..\bytecode\EvalCodeCache.h" />
+ <ClInclude Include="..\bytecode\ExecutionCounter.h" />
+ <ClInclude Include="..\bytecode\ExitKind.h" />
+ <ClInclude Include="..\bytecode\ExpressionRangeInfo.h" />
+ <ClInclude Include="..\bytecode\GetByIdStatus.h" />
+ <ClInclude Include="..\bytecode\GlobalResolveInfo.h" />
+ <ClInclude Include="..\bytecode\HandlerInfo.h" />
+ <ClInclude Include="..\bytecode\Instruction.h" />
+ <ClInclude Include="..\bytecode\JumpTable.h" />
+ <ClInclude Include="..\bytecode\LazyOperandValueProfile.h" />
+ <ClInclude Include="..\bytecode\LineInfo.h" />
+ <ClInclude Include="..\bytecode\LLIntCallLinkInfo.h" />
+ <ClInclude Include="..\bytecode\MethodOfGettingAValueProfile.h" />
+ <ClInclude Include="..\bytecode\Opcode.h" />
+ <ClInclude Include="..\bytecode\Operands.h" />
+ <ClInclude Include="..\bytecode\PolymorphicPutByIdList.h" />
+ <ClInclude Include="..\bytecode\PutByIdStatus.h" />
+ <ClInclude Include="..\bytecode\PutKind.h" />
+ <ClInclude Include="..\bytecode\ReduceWhitespace.h" />
+ <ClInclude Include="..\bytecode\SamplingTool.h" />
+ <ClInclude Include="..\bytecode\SpecialPointer.h" />
+ <ClInclude Include="..\bytecode\SpeculatedType.h" />
+ <ClInclude Include="..\bytecode\StructureSet.h" />
+ <ClInclude Include="..\bytecode\StructureStubClearingWatchpoint.h" />
+ <ClInclude Include="..\bytecode\StructureStubInfo.h" />
+ <ClInclude Include="..\bytecode\UnlinkedCodeBlock.h" />
+ <ClInclude Include="..\bytecode\ValueProfile.h" />
+ <ClInclude Include="..\bytecode\ValueRecovery.h" />
+ <ClInclude Include="..\bytecode\VirtualRegister.h" />
+ <ClInclude Include="..\bytecode\Watchpoint.h" />
+ <ClInclude Include="..\bytecompiler\BytecodeGenerator.h" />
+ <ClInclude Include="..\bytecompiler\Label.h" />
+ <ClInclude Include="..\bytecompiler\LabelScope.h" />
+ <ClInclude Include="..\bytecompiler\RegisterID.h" />
+ <ClInclude Include="..\config.h" />
+ <ClInclude Include="..\debugger\Debugger.h" />
+ <ClInclude Include="..\debugger\DebuggerActivation.h" />
+ <ClInclude Include="..\debugger\DebuggerCallFrame.h" />
+ <ClInclude Include="..\dfg\DFGDriver.h" />
+ <ClInclude Include="..\dfg\DFGOSREntry.h" />
+ <ClInclude Include="..\disassembler\Disassembler.h" />
+ <ClInclude Include="..\heap\BlockAllocator.h" />
+ <ClInclude Include="..\heap\ConservativeRoots.h" />
+ <ClInclude Include="..\heap\CopiedAllocator.h" />
+ <ClInclude Include="..\heap\CopiedBlock.h" />
+ <ClInclude Include="..\heap\CopiedBlockInlines.h" />
+ <ClInclude Include="..\heap\CopiedSpace.h" />
+ <ClInclude Include="..\heap\CopiedSpaceInlines.h" />
+ <ClInclude Include="..\heap\CopyVisitor.h" />
+ <ClInclude Include="..\heap\CopyVisitorInlines.h" />
+ <ClInclude Include="..\heap\CopyWorkList.h" />
+ <ClInclude Include="..\heap\DFGCodeBlocks.h" />
+ <ClInclude Include="..\heap\GCAssertions.h" />
+ <ClInclude Include="..\heap\GCThread.h" />
+ <ClInclude Include="..\heap\GCThreadSharedData.h" />
+ <ClInclude Include="..\heap\Handle.h" />
+ <ClInclude Include="..\heap\HandleBlock.h" />
+ <ClInclude Include="..\heap\HandleBlockInlines.h" />
+ <ClInclude Include="..\heap\HandleSet.h" />
+ <ClInclude Include="..\heap\HandleStack.h" />
+ <ClInclude Include="..\heap\HandleTypes.h" />
+ <ClInclude Include="..\heap\Heap.h" />
+ <ClInclude Include="..\heap\HeapBlock.h" />
+ <ClInclude Include="..\heap\HeapRootVisitor.h" />
+ <ClInclude Include="..\heap\HeapStatistics.h" />
+ <ClInclude Include="..\heap\HeapTimer.h" />
+ <ClInclude Include="..\heap\IncrementalSweeper.h" />
+ <ClInclude Include="..\heap\JITStubRoutineSet.h" />
+ <ClInclude Include="..\heap\ListableHandler.h" />
+ <ClInclude Include="..\heap\Local.h" />
+ <ClInclude Include="..\heap\LocalScope.h" />
+ <ClInclude Include="..\heap\MachineStackMarker.h" />
+ <ClInclude Include="..\heap\MarkedAllocator.h" />
+ <ClInclude Include="..\heap\MarkedBlock.h" />
+ <ClInclude Include="..\heap\MarkedBlockSet.h" />
+ <ClInclude Include="..\heap\MarkedSpace.h" />
+ <ClInclude Include="..\heap\MarkStack.h" />
+ <ClInclude Include="..\heap\MarkStackInlines.h" />
+ <ClInclude Include="..\heap\PassWeak.h" />
+ <ClInclude Include="..\heap\Region.h" />
+ <ClInclude Include="..\heap\SlotVisitor.h" />
+ <ClInclude Include="..\heap\SlotVisitorInlines.h" />
+ <ClInclude Include="..\heap\Strong.h" />
+ <ClInclude Include="..\heap\StrongInlines.h" />
+ <ClInclude Include="..\heap\SuperRegion.h" />
+ <ClInclude Include="..\heap\TinyBloomFilter.h" />
+ <ClInclude Include="..\heap\UnconditionalFinalizer.h" />
+ <ClInclude Include="..\heap\VTableSpectrum.h" />
+ <ClInclude Include="..\heap\Weak.h" />
+ <ClInclude Include="..\heap\WeakBlock.h" />
+ <ClInclude Include="..\heap\WeakHandleOwner.h" />
+ <ClInclude Include="..\heap\WeakImpl.h" />
+ <ClInclude Include="..\heap\WeakReferenceHarvester.h" />
+ <ClInclude Include="..\heap\WeakSet.h" />
+ <ClInclude Include="..\heap\WeakSetInlines.h" />
+ <ClInclude Include="..\heap\WriteBarrierSupport.h" />
+ <ClInclude Include="..\interpreter\AbstractPC.h" />
+ <ClInclude Include="..\interpreter\CachedCall.h" />
+ <ClInclude Include="..\interpreter\CallFrame.h" />
+ <ClInclude Include="..\interpreter\CallFrameClosure.h" />
+ <ClInclude Include="..\interpreter\Interpreter.h" />
+ <ClInclude Include="..\interpreter\JSStack.h" />
+ <ClInclude Include="..\interpreter\JSStackInlines.h" />
+ <ClInclude Include="..\interpreter\Register.h" />
+ <ClInclude Include="..\interpreter\VMInspector.h" />
+ <ClInclude Include="..\jit\ClosureCallStubRoutine.h" />
+ <ClInclude Include="..\jit\CompactJITCodeMap.h" />
+ <ClInclude Include="..\jit\ExecutableAllocator.h" />
+ <ClInclude Include="..\jit\GCAwareJITStubRoutine.h" />
+ <ClInclude Include="..\jit\HostCallReturnValue.h" />
+ <ClInclude Include="..\jit\JIT.h" />
+ <ClInclude Include="..\jit\JITCode.h" />
+ <ClInclude Include="..\jit\JITCompilationEffort.h" />
+ <ClInclude Include="..\jit\JITDisassembler.h" />
+ <ClInclude Include="..\jit\JITDriver.h" />
+ <ClInclude Include="..\jit\JITExceptions.h" />
+ <ClInclude Include="..\jit\JITInlines.h" />
+ <ClInclude Include="..\jit\JITStubCall.h" />
+ <ClInclude Include="..\jit\JITStubRoutine.h" />
+ <ClInclude Include="..\jit\JITStubs.h" />
+ <ClInclude Include="..\jit\JITThunks.h" />
+ <ClInclude Include="..\jit\JITWriteBarrier.h" />
+ <ClInclude Include="..\jit\JSInterfaceJIT.h" />
+ <ClInclude Include="..\jit\JumpReplacementWatchpoint.h" />
+ <ClInclude Include="..\jit\SpecializedThunkJIT.h" />
+ <ClInclude Include="..\jit\ThunkGenerator.h" />
+ <ClInclude Include="..\jit\ThunkGenerators.h" />
+ <ClInclude Include="..\jit\UnusedPointer.h" />
+ <ClInclude Include="..\llint\LLIntCLoop.h" />
+ <ClInclude Include="..\llint\LLIntCommon.h" />
+ <ClInclude Include="..\llint\LLIntData.h" />
+ <ClInclude Include="..\llint\LLIntEntrypoints.h" />
+ <ClInclude Include="..\llint\LLIntExceptions.h" />
+ <ClInclude Include="..\llint\LLIntOfflineAsmConfig.h" />
+ <ClInclude Include="..\llint\LLIntOpcode.h" />
+ <ClInclude Include="..\llint\LLIntSlowPaths.h" />
+ <ClInclude Include="..\llint\LLIntThunks.h" />
+ <ClInclude Include="..\llint\LowLevelInterpreter.h" />
+ <ClInclude Include="..\parser\ASTBuilder.h" />
+ <ClInclude Include="..\parser\Lexer.h" />
+ <ClInclude Include="..\parser\NodeConstructors.h" />
+ <ClInclude Include="..\parser\NodeInfo.h" />
+ <ClInclude Include="..\parser\Nodes.h" />
+ <ClInclude Include="..\parser\Parser.h" />
+ <ClInclude Include="..\parser\ParserArena.h" />
+ <ClInclude Include="..\parser\ParserModes.h" />
+ <ClInclude Include="..\parser\ParserTokens.h" />
+ <ClInclude Include="..\parser\ResultType.h" />
+ <ClInclude Include="..\parser\SourceCode.h" />
+ <ClInclude Include="..\parser\SourceProvider.h" />
+ <ClInclude Include="..\parser\SourceProviderCache.h" />
+ <ClInclude Include="..\parser\SourceProviderCacheItem.h" />
+ <ClInclude Include="..\parser\SyntaxChecker.h" />
+ <ClInclude Include="..\profiler\CallIdentifier.h" />
+ <ClInclude Include="..\profiler\LegacyProfiler.h" />
+ <ClInclude Include="..\profiler\Profile.h" />
+ <ClInclude Include="..\profiler\ProfileGenerator.h" />
+ <ClInclude Include="..\profiler\ProfileNode.h" />
+ <ClInclude Include="..\profiler\ProfilerBytecode.h" />
+ <ClInclude Include="..\profiler\ProfilerBytecodes.h" />
+ <ClInclude Include="..\profiler\ProfilerBytecodeSequence.h" />
+ <ClInclude Include="..\profiler\ProfilerCompilation.h" />
+ <ClInclude Include="..\profiler\ProfilerCompilationKind.h" />
+ <ClInclude Include="..\profiler\ProfilerCompiledBytecode.h" />
+ <ClInclude Include="..\profiler\ProfilerDatabase.h" />
+ <ClInclude Include="..\profiler\ProfilerExecutionCounter.h" />
+ <ClInclude Include="..\profiler\ProfilerOrigin.h" />
+ <ClInclude Include="..\profiler\ProfilerOriginStack.h" />
+ <ClInclude Include="..\profiler\ProfilerOSRExit.h" />
+ <ClInclude Include="..\profiler\ProfilerOSRExitSite.h" />
+ <ClInclude Include="..\profiler\ProfilerProfiledBytecodes.h" />
+ <ClInclude Include="..\runtime\ArgList.h" />
+ <ClInclude Include="..\runtime\Arguments.h" />
+ <ClInclude Include="..\runtime\ArrayConstructor.h" />
+ <ClInclude Include="..\runtime\ArrayConventions.h" />
+ <ClInclude Include="..\runtime\ArrayPrototype.h" />
+ <ClInclude Include="..\runtime\ArrayStorage.h" />
+ <ClInclude Include="..\runtime\BatchedTransitionOptimizer.h" />
+ <ClInclude Include="..\runtime\BigInteger.h" />
+ <ClInclude Include="..\runtime\BooleanConstructor.h" />
+ <ClInclude Include="..\runtime\BooleanObject.h" />
+ <ClInclude Include="..\runtime\BooleanPrototype.h" />
+ <ClInclude Include="..\runtime\Butterfly.h" />
+ <ClInclude Include="..\runtime\ButterflyInlines.h" />
+ <ClInclude Include="..\runtime\CachedTranscendentalFunction.h" />
+ <ClInclude Include="..\runtime\CallData.h" />
+ <ClInclude Include="..\runtime\ClassInfo.h" />
+ <ClInclude Include="..\runtime\CodeCache.h" />
+ <ClInclude Include="..\runtime\CodeSpecializationKind.h" />
+ <ClInclude Include="..\runtime\CommonIdentifiers.h" />
+ <ClInclude Include="..\runtime\CommonSlowPaths.h" />
+ <ClInclude Include="..\runtime\Completion.h" />
+ <ClInclude Include="..\runtime\ConstructData.h" />
+ <ClInclude Include="..\runtime\DateConstructor.h" />
+ <ClInclude Include="..\runtime\DateConversion.h" />
+ <ClInclude Include="..\runtime\DateInstance.h" />
+ <ClInclude Include="..\runtime\DateInstanceCache.h" />
+ <ClInclude Include="..\runtime\DatePrototype.h" />
+ <ClInclude Include="..\runtime\Error.h" />
+ <ClInclude Include="..\runtime\ErrorConstructor.h" />
+ <ClInclude Include="..\runtime\ErrorInstance.h" />
+ <ClInclude Include="..\runtime\ErrorPrototype.h" />
+ <ClInclude Include="..\runtime\ExceptionHelpers.h" />
+ <ClInclude Include="..\runtime\Executable.h" />
+ <ClInclude Include="..\runtime\ExecutionHarness.h" />
+ <ClInclude Include="..\runtime\FunctionConstructor.h" />
+ <ClInclude Include="..\runtime\FunctionPrototype.h" />
+ <ClInclude Include="..\runtime\GCActivityCallback.h" />
+ <ClInclude Include="..\runtime\GetterSetter.h" />
+ <ClInclude Include="..\runtime\Identifier.h" />
+ <ClInclude Include="..\runtime\IndexingHeader.h" />
+ <ClInclude Include="..\runtime\IndexingHeaderInlines.h" />
+ <ClInclude Include="..\runtime\IndexingType.h" />
+ <ClInclude Include="..\runtime\InitializeThreading.h" />
+ <ClInclude Include="..\runtime\InternalFunction.h" />
+ <ClInclude Include="..\runtime\Intrinsic.h" />
+ <ClInclude Include="..\runtime\JSActivation.h" />
+ <ClInclude Include="..\runtime\JSAPIValueWrapper.h" />
+ <ClInclude Include="..\runtime\JSArray.h" />
+ <ClInclude Include="..\runtime\JSBoundFunction.h" />
+ <ClInclude Include="..\runtime\JSCell.h" />
+ <ClInclude Include="..\runtime\JSCJSValue.h" />
+ <ClInclude Include="..\runtime\JSCJSValueInlines.h" />
+ <ClInclude Include="..\runtime\JSDateMath.h" />
+ <ClInclude Include="..\runtime\JSDestructibleObject.h" />
+ <ClInclude Include="..\runtime\JSExportMacros.h" />
+ <ClInclude Include="..\runtime\JSFunction.h" />
+ <ClInclude Include="..\runtime\VM.h" />
+ <ClInclude Include="..\runtime\JSGlobalObject.h" />
+ <ClInclude Include="..\runtime\JSGlobalObjectFunctions.h" />
+ <ClInclude Include="..\runtime\JSLock.h" />
+ <ClInclude Include="..\runtime\JSNameScope.h" />
+ <ClInclude Include="..\runtime\JSNotAnObject.h" />
+ <ClInclude Include="..\runtime\JSObject.h" />
+ <ClInclude Include="..\runtime\JSONObject.h" />
+ <ClInclude Include="..\runtime\JSPropertyNameIterator.h" />
+ <ClInclude Include="..\runtime\JSProxy.h" />
+ <ClInclude Include="..\runtime\JSScope.h" />
+ <ClInclude Include="..\runtime\JSSegmentedVariableObject.h" />
+ <ClInclude Include="..\runtime\JSString.h" />
+ <ClInclude Include="..\runtime\JSStringBuilder.h" />
+ <ClInclude Include="..\runtime\JSStringJoiner.h" />
+ <ClInclude Include="..\runtime\JSSymbolTableObject.h" />
+ <ClInclude Include="..\runtime\JSType.h" />
+ <ClInclude Include="..\runtime\JSTypeInfo.h" />
+ <ClInclude Include="..\runtime\JSVariableObject.h" />
+ <ClInclude Include="..\runtime\JSWithScope.h" />
+ <ClInclude Include="..\runtime\JSWrapperObject.h" />
+ <ClInclude Include="..\runtime\LiteralParser.h" />
+ <ClInclude Include="..\runtime\Lookup.h" />
+ <ClInclude Include="..\runtime\MatchResult.h" />
+ <ClInclude Include="..\runtime\MathObject.h" />
+ <ClInclude Include="..\runtime\NameConstructor.h" />
+ <ClInclude Include="..\runtime\NameInstance.h" />
+ <ClInclude Include="..\runtime\NamePrototype.h" />
+ <ClInclude Include="..\runtime\NativeErrorConstructor.h" />
+ <ClInclude Include="..\runtime\NativeErrorPrototype.h" />
+ <ClInclude Include="..\runtime\NumberConstructor.h" />
+ <ClInclude Include="..\runtime\NumberObject.h" />
+ <ClInclude Include="..\runtime\NumberPrototype.h" />
+ <ClInclude Include="..\runtime\NumericStrings.h" />
+ <ClInclude Include="..\runtime\ObjectConstructor.h" />
+ <ClInclude Include="..\runtime\ObjectPrototype.h" />
+ <ClInclude Include="..\runtime\Operations.h" />
+ <ClInclude Include="..\runtime\Options.h" />
+ <ClInclude Include="..\runtime\PrivateName.h" />
+ <ClInclude Include="..\runtime\PropertyDescriptor.h" />
+ <ClInclude Include="..\runtime\PropertyMapHashTable.h" />
+ <ClInclude Include="..\runtime\PropertyName.h" />
+ <ClInclude Include="..\runtime\PropertyNameArray.h" />
+ <ClInclude Include="..\runtime\PropertyOffset.h" />
+ <ClInclude Include="..\runtime\PropertySlot.h" />
+ <ClInclude Include="..\runtime\PropertyStorage.h" />
+ <ClInclude Include="..\runtime\Protect.h" />
+ <ClInclude Include="..\runtime\PrototypeMap.h" />
+ <ClInclude Include="..\runtime\PutDirectIndexMode.h" />
+ <ClInclude Include="..\runtime\PutPropertySlot.h" />
+ <ClInclude Include="..\runtime\RegExp.h" />
+ <ClInclude Include="..\runtime\RegExpCache.h" />
+ <ClInclude Include="..\runtime\RegExpCachedResult.h" />
+ <ClInclude Include="..\runtime\RegExpConstructor.h" />
+ <ClInclude Include="..\runtime\RegExpKey.h" />
+ <ClInclude Include="..\runtime\RegExpMatchesArray.h" />
+ <ClInclude Include="..\runtime\RegExpObject.h" />
+ <ClInclude Include="..\runtime\RegExpPrototype.h" />
+ <ClInclude Include="..\runtime\Reject.h" />
+ <ClInclude Include="..\runtime\SamplingCounter.h" />
+ <ClInclude Include="..\runtime\SmallStrings.h" />
+ <ClInclude Include="..\runtime\SparseArrayValueMap.h" />
+ <ClInclude Include="..\runtime\StrictEvalActivation.h" />
+ <ClInclude Include="..\runtime\StringConstructor.h" />
+ <ClInclude Include="..\runtime\StringObject.h" />
+ <ClInclude Include="..\runtime\StringPrototype.h" />
+ <ClInclude Include="..\runtime\StringRecursionChecker.h" />
+ <ClInclude Include="..\runtime\Structure.h" />
+ <ClInclude Include="..\runtime\StructureChain.h" />
+ <ClInclude Include="..\runtime\StructureRareData.h" />
+ <ClInclude Include="..\runtime\StructureRareDataInlines.h" />
+ <ClInclude Include="..\runtime\StructureTransitionTable.h" />
+ <ClInclude Include="..\runtime\SymbolTable.h" />
+ <ClInclude Include="..\runtime\Tracing.h" />
+ <ClInclude Include="..\runtime\TypedArrayDescriptor.h" />
+ <ClInclude Include="..\runtime\Uint16WithFraction.h" />
+ <ClInclude Include="..\runtime\Watchdog.h" />
+ <ClInclude Include="..\runtime\WeakGCMap.h" />
+ <ClInclude Include="..\runtime\WeakRandom.h" />
+ <ClInclude Include="..\runtime\WriteBarrier.h" />
+ <ClInclude Include="..\tools\CodeProfile.h" />
+ <ClInclude Include="..\tools\CodeProfiling.h" />
+ <ClInclude Include="..\tools\ProfileTreeNode.h" />
+ <ClInclude Include="..\tools\TieredMMapArray.h" />
+ <ClInclude Include="..\yarr\Yarr.h" />
+ <ClInclude Include="..\yarr\YarrCanonicalizeUCS2.h" />
+ <ClInclude Include="..\yarr\YarrInterpreter.h" />
+ <ClInclude Include="..\yarr\YarrJIT.h" />
+ <ClInclude Include="..\yarr\YarrParser.h" />
+ <ClInclude Include="..\yarr\YarrPattern.h" />
+ <ClInclude Include="..\yarr\YarrSyntaxChecker.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="JavaScriptCorePostBuild.cmd">
+ <FileType>Document</FileType>
+ </None>
+ <None Include="JavaScriptCorePreBuild.cmd">
+ <FileType>Document</FileType>
+ </None>
+ <None Include="JavaScriptCorePreLink.cmd">
+ <FileType>Document</FileType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="..\jit\JITStubsMSVC64.asm">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ </MASM>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
new file mode 100644
index 000000000..5a0a3176a
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
@@ -0,0 +1,1940 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="assembler">
+ <UniqueIdentifier>{429783a1-5d6a-4019-ad1a-ddb2c98f9b6c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="bytecode">
+ <UniqueIdentifier>{766088a0-1216-4854-aa43-560c5e283668}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="bytecodecompiler">
+ <UniqueIdentifier>{bddd153e-8c53-4515-ab9e-5d901686bd4f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="debugger">
+ <UniqueIdentifier>{6e0cb358-2fe7-46a4-8efd-f6649cee6370}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Derived Sources">
+ <UniqueIdentifier>{9f7469bb-7833-4279-8d28-2fc71c632552}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="dfg">
+ <UniqueIdentifier>{6c82539d-40d2-45a5-a663-8349c2141b1a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="disassembler">
+ <UniqueIdentifier>{940f749b-a189-45be-83b9-b4e74ecf1486}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="heap">
+ <UniqueIdentifier>{bd49e5cf-95d6-4151-b286-8837ccd347fa}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="interpreter">
+ <UniqueIdentifier>{10d97ea3-2af9-489c-a54e-d69ef2e4ca0a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="jit">
+ <UniqueIdentifier>{94d7eb64-3e51-4008-8536-0bcb6768ba9f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="llint">
+ <UniqueIdentifier>{63e3dd92-7ea9-4723-b099-6c79a939dec0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="parser">
+ <UniqueIdentifier>{e6a026a4-156a-4a59-9e3f-e8b54e665841}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="profiler">
+ <UniqueIdentifier>{351dcbd2-e47e-4467-8609-53acfce72f91}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="runtime">
+ <UniqueIdentifier>{3b9d72a5-135b-43b3-a524-c6d2b9d29d34}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="tools">
+ <UniqueIdentifier>{03eda3ec-bcb2-4474-b1b3-69ad771846a4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="yarr">
+ <UniqueIdentifier>{fac52666-842e-4d02-9d5f-844f54dca5f7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="API">
+ <UniqueIdentifier>{9ed0bc6e-7372-4795-9651-917c9e05c641}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\API\JSBase.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSCallbackConstructor.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSCallbackFunction.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSCallbackObject.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSClassRef.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSContextRef.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSObjectRef.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSScriptRef.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSStringRef.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSStringRefBSTR.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSStringRefCF.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSValueRef.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\JSWeakObjectMapRefPrivate.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\API\OpaqueJSString.cpp">
+ <Filter>API</Filter>
+ </ClCompile>
+ <ClCompile Include="..\assembler\LinkBuffer.cpp">
+ <Filter>assembler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\assembler\MacroAssembler.cpp">
+ <Filter>assembler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\ArrayProfile.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\CallLinkInfo.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\CallLinkStatus.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\CodeBlock.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\CodeBlockHash.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\CodeOrigin.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\CodeType.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\ExecutionCounter.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\ExitKind.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\GetByIdStatus.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\JumpTable.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\LazyOperandValueProfile.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\MethodOfGettingAValueProfile.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\Opcode.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\PolymorphicPutByIdList.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\PutByIdStatus.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\ReduceWhitespace.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\SamplingTool.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\SpecialPointer.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\SpeculatedType.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\StructureStubInfo.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecode\Watchpoint.cpp">
+ <Filter>bytecode</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecompiler\BytecodeGenerator.cpp">
+ <Filter>bytecodecompiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\bytecompiler\NodesCodegen.cpp">
+ <Filter>bytecodecompiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\debugger\Debugger.cpp">
+ <Filter>debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\debugger\DebuggerActivation.cpp">
+ <Filter>debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\debugger\DebuggerCallFrame.cpp">
+ <Filter>debugger</Filter>
+ </ClCompile>
+ <ClCompile Include="..\disassembler\Disassembler.cpp">
+ <Filter>disassembler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\BlockAllocator.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\ConservativeRoots.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\CopiedSpace.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\CopyVisitor.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\DFGCodeBlocks.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\GCThread.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\GCThreadSharedData.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\HandleSet.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\HandleStack.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\Heap.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\HeapStatistics.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\HeapTimer.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\IncrementalSweeper.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\JITStubRoutineSet.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\MachineStackMarker.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\MarkedAllocator.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\MarkedBlock.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\MarkedSpace.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\MarkStack.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\SlotVisitor.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\SuperRegion.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\VTableSpectrum.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\Weak.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\WeakBlock.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\WeakHandleOwner.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\WeakSet.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\heap\WriteBarrierSupport.cpp">
+ <Filter>heap</Filter>
+ </ClCompile>
+ <ClCompile Include="..\interpreter\AbstractPC.cpp">
+ <Filter>interpreter</Filter>
+ </ClCompile>
+ <ClCompile Include="..\interpreter\CallFrame.cpp">
+ <Filter>interpreter</Filter>
+ </ClCompile>
+ <ClCompile Include="..\interpreter\Interpreter.cpp">
+ <Filter>interpreter</Filter>
+ </ClCompile>
+ <ClCompile Include="..\interpreter\JSStack.cpp">
+ <Filter>interpreter</Filter>
+ </ClCompile>
+ <ClCompile Include="..\interpreter\VMInspector.cpp">
+ <Filter>interpreter</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\ClosureCallStubRoutine.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\ExecutableAllocator.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\GCAwareJITStubRoutine.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\HostCallReturnValue.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JIT.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITArithmetic.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITArithmetic32_64.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITCall.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITCall32_64.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITCode.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITDisassembler.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITExceptions.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITOpcodes.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITOpcodes32_64.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITPropertyAccess.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITPropertyAccess32_64.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITStubRoutine.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITStubs.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JITThunks.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\JumpReplacementWatchpoint.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\jit\ThunkGenerators.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntCLoop.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntData.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntEntrypoints.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntExceptions.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntOffsetsExtractor.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntSlowPaths.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LLIntThunks.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\llint\LowLevelInterpreter.cpp">
+ <Filter>llint</Filter>
+ </ClCompile>
+ <ClCompile Include="..\parser\Lexer.cpp">
+ <Filter>parser</Filter>
+ </ClCompile>
+ <ClCompile Include="..\parser\Nodes.cpp">
+ <Filter>parser</Filter>
+ </ClCompile>
+ <ClCompile Include="..\parser\Parser.cpp">
+ <Filter>parser</Filter>
+ </ClCompile>
+ <ClCompile Include="..\parser\ParserArena.cpp">
+ <Filter>parser</Filter>
+ </ClCompile>
+ <ClCompile Include="..\parser\SourceProviderCache.cpp">
+ <Filter>parser</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\LegacyProfiler.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\Profile.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfileGenerator.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfileNode.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerBytecode.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerBytecodes.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerBytecodeSequence.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerCompilation.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerCompilationKind.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerCompiledBytecode.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerDatabase.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerOrigin.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerOriginStack.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerOSRExit.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerOSRExitSite.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\profiler\ProfilerProfiledBytecodes.cpp">
+ <Filter>profiler</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ArgList.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Arguments.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ArrayConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ArrayPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\BooleanConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\BooleanObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\BooleanPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\CallData.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\CodeCache.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\CodeSpecializationKind.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\CommonIdentifiers.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Completion.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ConstructData.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\DateConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\DateConversion.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\DateInstance.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\DatePrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Error.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ErrorConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ErrorInstance.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ErrorPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ExceptionHelpers.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Executable.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\FunctionConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\FunctionPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\GCActivityCallback.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\GetterSetter.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Identifier.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\IndexingType.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\InitializeThreading.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\InternalFunction.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSActivation.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSAPIValueWrapper.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSArray.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSBoundFunction.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSCell.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSDateMath.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSFunction.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\VM.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSGlobalObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSGlobalObjectFunctions.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSLock.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSNameScope.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSNotAnObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSONObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSPropertyNameIterator.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSProxy.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSScope.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSSegmentedVariableObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSString.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSStringJoiner.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSSymbolTableObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSVariableObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSWithScope.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSWrapperObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\LiteralParser.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Lookup.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\MathObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NameConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NameInstance.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NamePrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NativeErrorConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NativeErrorPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NumberConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NumberObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\NumberPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ObjectConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\ObjectPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Operations.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Options.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\PropertyDescriptor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\PropertyNameArray.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\PropertySlot.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExp.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExpCache.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExpCachedResult.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExpConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExpMatchesArray.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExpObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\RegExpPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\SamplingCounter.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\SmallStrings.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\SparseArrayValueMap.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StrictEvalActivation.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StringConstructor.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StringObject.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StringPrototype.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StringRecursionChecker.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Structure.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StructureChain.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\SymbolTable.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\Watchdog.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\WatchdogNone.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\tools\CodeProfile.cpp">
+ <Filter>tools</Filter>
+ </ClCompile>
+ <ClCompile Include="..\tools\CodeProfiling.cpp">
+ <Filter>tools</Filter>
+ </ClCompile>
+ <ClCompile Include="..\yarr\YarrCanonicalizeUCS2.cpp">
+ <Filter>yarr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\yarr\YarrInterpreter.cpp">
+ <Filter>yarr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\yarr\YarrJIT.cpp">
+ <Filter>yarr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\yarr\YarrPattern.cpp">
+ <Filter>yarr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\yarr\YarrSyntaxChecker.cpp">
+ <Filter>yarr</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\PrototypeMap.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\JSCJSValue.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\StructureRareData.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ <ClCompile Include="..\parser\SourceProvider.cpp">
+ <Filter>parser</Filter>
+ </ClCompile>
+ <ClCompile Include="..\runtime\PropertyTable.cpp">
+ <Filter>runtime</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\API\APICast.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JavaScript.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JavaScriptCore.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSBase.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSBasePrivate.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSCallbackConstructor.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSCallbackFunction.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSCallbackObject.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSCallbackObjectFunctions.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSClassRef.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSContext.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSContextInternal.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSContextRef.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSContextRefPrivate.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSExport.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSObjectRef.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSObjectRefPrivate.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSRetainPtr.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSScriptRefPrivate.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSStringRef.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSStringRefBSTR.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSStringRefCF.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSValueInternal.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSValueRef.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSWeakObjectMapRefInternal.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSWeakObjectMapRefPrivate.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSWrapperMap.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\OpaqueJSString.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\WebKitAvailability.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\AbstractMacroAssembler.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\AssemblerBuffer.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\CodeLocation.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\LinkBuffer.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\MacroAssembler.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\MacroAssemblerX86.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\MacroAssemblerX86Common.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\MacroAssemblerX86_64.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\RepatchBuffer.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\assembler\X86Assembler.h">
+ <Filter>assembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ArrayAllocationProfile.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ArrayProfile.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ByValInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CallLinkInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CallLinkStatus.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CallReturnOffsetToBytecodeOffset.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CodeBlock.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CodeBlockHash.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CodeBlockWithJITType.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CodeOrigin.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\CodeType.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\Comment.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\EvalCodeCache.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ExecutionCounter.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ExitKind.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ExpressionRangeInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\GetByIdStatus.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\GlobalResolveInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\HandlerInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\Instruction.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\JumpTable.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\LazyOperandValueProfile.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\LineInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\LLIntCallLinkInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\MethodOfGettingAValueProfile.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\Opcode.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\Operands.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\PolymorphicPutByIdList.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\PutByIdStatus.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\PutKind.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ReduceWhitespace.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\SamplingTool.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\SpecialPointer.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\SpeculatedType.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\StructureSet.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\StructureStubClearingWatchpoint.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\StructureStubInfo.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\UnlinkedCodeBlock.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ValueProfile.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\ValueRecovery.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\VirtualRegister.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\Watchpoint.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecompiler\BytecodeGenerator.h">
+ <Filter>bytecodecompiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecompiler\Label.h">
+ <Filter>bytecodecompiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecompiler\LabelScope.h">
+ <Filter>bytecodecompiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecompiler\RegisterID.h">
+ <Filter>bytecodecompiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\debugger\Debugger.h">
+ <Filter>debugger</Filter>
+ </ClInclude>
+ <ClInclude Include="..\debugger\DebuggerActivation.h">
+ <Filter>debugger</Filter>
+ </ClInclude>
+ <ClInclude Include="..\debugger\DebuggerCallFrame.h">
+ <Filter>debugger</Filter>
+ </ClInclude>
+ <ClInclude Include="..\dfg\DFGDriver.h">
+ <Filter>dfg</Filter>
+ </ClInclude>
+ <ClInclude Include="..\dfg\DFGOSREntry.h">
+ <Filter>dfg</Filter>
+ </ClInclude>
+ <ClInclude Include="..\disassembler\Disassembler.h">
+ <Filter>disassembler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\BlockAllocator.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\ConservativeRoots.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopiedAllocator.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopiedBlock.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopiedBlockInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopiedSpace.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopiedSpaceInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopyVisitor.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopyVisitorInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\CopyWorkList.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\DFGCodeBlocks.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\GCAssertions.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\GCThread.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\GCThreadSharedData.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\Handle.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HandleBlock.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HandleBlockInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HandleSet.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HandleStack.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HandleTypes.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\Heap.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HeapBlock.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HeapRootVisitor.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HeapStatistics.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\HeapTimer.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\IncrementalSweeper.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\JITStubRoutineSet.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\ListableHandler.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\Local.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\LocalScope.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MachineStackMarker.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MarkedAllocator.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MarkedBlock.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MarkedBlockSet.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MarkedSpace.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MarkStack.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\MarkStackInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\PassWeak.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\Region.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\SlotVisitor.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\SlotVisitorInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\Strong.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\StrongInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\SuperRegion.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\TinyBloomFilter.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\UnconditionalFinalizer.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\VTableSpectrum.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\Weak.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WeakBlock.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WeakHandleOwner.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WeakImpl.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WeakReferenceHarvester.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WeakSet.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WeakSetInlines.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\heap\WriteBarrierSupport.h">
+ <Filter>heap</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\AbstractPC.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\CachedCall.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\CallFrame.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\CallFrameClosure.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\Interpreter.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\JSStack.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\JSStackInlines.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\Register.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\interpreter\VMInspector.h">
+ <Filter>interpreter</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\ClosureCallStubRoutine.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\CompactJITCodeMap.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\ExecutableAllocator.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\GCAwareJITStubRoutine.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\HostCallReturnValue.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JIT.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITCode.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITCompilationEffort.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITDisassembler.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITDriver.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITExceptions.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITInlines.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITStubCall.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITStubRoutine.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITStubs.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITThunks.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JITWriteBarrier.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JSInterfaceJIT.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\JumpReplacementWatchpoint.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\SpecializedThunkJIT.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\ThunkGenerator.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\ThunkGenerators.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\jit\UnusedPointer.h">
+ <Filter>jit</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntCLoop.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntCommon.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntData.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntEntrypoints.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntExceptions.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntOfflineAsmConfig.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntOpcode.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntSlowPaths.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LLIntThunks.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\llint\LowLevelInterpreter.h">
+ <Filter>llint</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\ASTBuilder.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\Lexer.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\NodeConstructors.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\NodeInfo.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\Nodes.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\Parser.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\ParserArena.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\ParserModes.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\ParserTokens.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\ResultType.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\SourceCode.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\SourceProvider.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\SourceProviderCache.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\SourceProviderCacheItem.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\parser\SyntaxChecker.h">
+ <Filter>parser</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\CallIdentifier.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\LegacyProfiler.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\Profile.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfileGenerator.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfileNode.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerBytecode.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerBytecodes.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerBytecodeSequence.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerCompilation.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerCompilationKind.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerCompiledBytecode.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerDatabase.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerExecutionCounter.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerOrigin.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerOriginStack.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerOSRExit.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerOSRExitSite.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\profiler\ProfilerProfiledBytecodes.h">
+ <Filter>profiler</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ArgList.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Arguments.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ArrayConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ArrayConventions.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ArrayPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ArrayStorage.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\BatchedTransitionOptimizer.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\BigInteger.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\BooleanConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\BooleanObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\BooleanPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Butterfly.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ButterflyInlines.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\CachedTranscendentalFunction.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\CallData.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ClassInfo.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\CodeCache.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\CodeSpecializationKind.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\CommonIdentifiers.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\CommonSlowPaths.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Completion.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ConstructData.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\DateConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\DateConversion.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\DateInstance.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\DateInstanceCache.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\DatePrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Error.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ErrorConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ErrorInstance.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ErrorPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ExceptionHelpers.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Executable.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ExecutionHarness.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\FunctionConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\FunctionPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\GCActivityCallback.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\GetterSetter.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Identifier.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\IndexingHeader.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\IndexingHeaderInlines.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\IndexingType.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\InitializeThreading.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\InternalFunction.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Intrinsic.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSActivation.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSAPIValueWrapper.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSArray.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSBoundFunction.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSCell.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSDateMath.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSDestructibleObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSExportMacros.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSFunction.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\VM.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSGlobalObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSGlobalObjectFunctions.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSLock.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSNameScope.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSNotAnObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSONObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSPropertyNameIterator.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSProxy.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSScope.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSSegmentedVariableObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSString.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSStringBuilder.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSStringJoiner.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSSymbolTableObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSType.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSTypeInfo.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSVariableObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSWithScope.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSWrapperObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\LiteralParser.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Lookup.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\MatchResult.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\MathObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NameConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NameInstance.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NamePrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NativeErrorConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NativeErrorPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NumberConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NumberObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NumberPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\NumericStrings.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ObjectConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\ObjectPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Operations.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Options.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PrivateName.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertyDescriptor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertyMapHashTable.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertyName.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertyNameArray.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertyOffset.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertySlot.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PropertyStorage.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Protect.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PutDirectIndexMode.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\PutPropertySlot.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExp.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpCache.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpCachedResult.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpKey.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpMatchesArray.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\RegExpPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Reject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\SamplingCounter.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\SmallStrings.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\SparseArrayValueMap.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StrictEvalActivation.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StringConstructor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StringObject.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StringPrototype.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StringRecursionChecker.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Structure.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StructureChain.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StructureTransitionTable.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\SymbolTable.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Tracing.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\TypedArrayDescriptor.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Uint16WithFraction.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\Watchdog.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\WeakGCMap.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\WeakRandom.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\WriteBarrier.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\tools\CodeProfile.h">
+ <Filter>tools</Filter>
+ </ClInclude>
+ <ClInclude Include="..\tools\CodeProfiling.h">
+ <Filter>tools</Filter>
+ </ClInclude>
+ <ClInclude Include="..\tools\ProfileTreeNode.h">
+ <Filter>tools</Filter>
+ </ClInclude>
+ <ClInclude Include="..\tools\TieredMMapArray.h">
+ <Filter>tools</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\Yarr.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\YarrCanonicalizeUCS2.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\YarrInterpreter.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\YarrJIT.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\YarrParser.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\YarrPattern.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\yarr\YarrSyntaxChecker.h">
+ <Filter>yarr</Filter>
+ </ClInclude>
+ <ClInclude Include="..\config.h" />
+ <ClInclude Include="..\runtime\PrototypeMap.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSValue.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSCJSValue.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\JSCJSValueInlines.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\bytecode\DataFormat.h">
+ <Filter>bytecode</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StructureRareData.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\runtime\StructureRareDataInlines.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
+ <ClInclude Include="..\API\JSAPIWrapperObject.h">
+ <Filter>API</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\BooleanPrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\DatePrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ErrorPrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\HeaderDetection.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\JSGlobalObject.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\JSONObject.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\Lexer.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\NumberConstructor.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ObjectConstructor.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ObjectPrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\RegExpConstructor.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\NumberPrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\LLIntAssembly.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\RegExpJitTables.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\RegExpPrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\StringConstructor.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ <ClInclude Include="$(ConfigurationBuildDir)\obj32\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h">
+ <Filter>Derived Sources</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="JavaScriptCorePreLink.cmd" />
+ <None Include="JavaScriptCorePostBuild.cmd" />
+ <None Include="JavaScriptCorePreBuild.cmd" />
+ </ItemGroup>
+ <ItemGroup>
+ <MASM Include="..\jit\JITStubsMSVC64.asm">
+ <Filter>jit</Filter>
+ </MASM>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCF.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCF.props
new file mode 100644
index 000000000..081981bb7
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCF.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalDependencies>CoreFoundation$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCFLite.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCFLite.props
new file mode 100644
index 000000000..cd3b5dd84
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCFLite.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalDependencies>CFLite.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCommon.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCommon.props
new file mode 100644
index 000000000..901aaa35d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreCommon.props
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\;..\tools\;..\runtime\;..\llint\;..\jit\;..\disassembler\;..\heap\;..\debugger\;..\assembler\;..\profiler\;..\yarr\;..\interpreter\;..\bytecode\;..\dfg\;..\bytecompiler\;..\parser\;..\API\;$(ConfigurationBuildDir)\obj32\JavaScriptCore\DerivedSources\;$(ConfigurationBuildDir)\include\;$(ConfigurationBuildDir)\include\JavaScriptCore\;$(ConfigurationBuildDir)\include\private\;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>winmm.lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;WTF$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebug.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebug.props
new file mode 100644
index 000000000..1f0bd7dc3
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebug.props
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="JavaScriptCoreCommon.props" />
+ <Import Project="JavaScriptCoreCF.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile />
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebugCFLite.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebugCFLite.props
new file mode 100644
index 000000000..3ccdbb1b3
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreDebugCFLite.props
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefinesCairo.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="JavaScriptCoreCommon.props" />
+ <Import Project="JavaScriptCoreCFLite.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile />
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make
index c7c640b0d..e480fa711 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.make
@@ -1,6 +1,6 @@
all:
touch "%ConfigurationBuildDir%\buildfailed"
- bash build-generated-files.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
+ bash build-generated-files.sh "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)"
copy-files.cmd
-del "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdbool.h" "%ConfigurationBuildDir%\include\private\JavaScriptCore\stdint.h"
@@ -9,4 +9,4 @@ all:
clean:
-del "%ConfigurationBuildDir%\buildfailed"
copy-files.cmd clean
- -del /s /q "%ConfigurationBuildDir%\obj\JavaScriptCore\DerivedSources"
+ -del /s /q "%ConfigurationBuildDir%\obj32\JavaScriptCore\DerivedSources"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj
new file mode 100644
index 000000000..d1f00cd0a
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\DerivedSources.make" />
+ <None Include="build-generated-files.sh" />
+ <None Include="copy-files.cmd" />
+ <None Include="JavaScriptCoreGenerated.make" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3670D01F-95F3-45A8-B878-947EB6CF214E}</ProjectGuid>
+ <Keyword>MakeFileProj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedProduction.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="JavaScriptCoreGeneratedProduction.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <NMakeOutput />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <NMakeOutput />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+ <NMakeOutput />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+ <NMakeOutput />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+ <NMakeOutput />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+ <NMakeOutput />
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <NMakeOutput>
+ </NMakeOutput>
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+ <NMakeOutput />
+ <NMakePreprocessorDefinitions>WIN32;NDEBUG;</NMakePreprocessorDefinitions>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters
new file mode 100644
index 000000000..9dce732ff
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGenerated.vcxproj.filters
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <None Include="build-generated-files.sh" />
+ <None Include="JavaScriptCoreGenerated.make" />
+ <None Include="..\DerivedSources.make" />
+ <None Include="copy-files.cmd" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedCommon.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedCommon.props
new file mode 100644
index 000000000..36fc059a5
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedCommon.props
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup />
+ <PropertyGroup />
+ <PropertyGroup Label="Configuration" />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedDebug.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedDebug.props
new file mode 100644
index 000000000..619e43a96
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedDebug.props
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="JavaScriptCoreGeneratedCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedProduction.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedProduction.props
new file mode 100644
index 000000000..aef8ccf37
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedProduction.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ <Import Project="JavaScriptCoreGeneratedCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedRelease.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedRelease.props
new file mode 100644
index 000000000..472cae9ec
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreGeneratedRelease.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="JavaScriptCoreGeneratedCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd
new file mode 100644
index 000000000..8b0a3a458
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePostBuild.cmd
@@ -0,0 +1,2 @@
+if exist "%WEBKIT_LIBRARIES%\tools\VersionStamper\VersionStamper.exe" "%WEBKIT_LIBRARIES%\tools\VersionStamper\VersionStamper.exe" --verbose "%TARGETPATH%"
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd
index a77077674..a77077674 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCorePreBuild.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreBuild.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreLink.cmd
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCorePreLink.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreProduction.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreProduction.props
new file mode 100644
index 000000000..48e7f4217
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreProduction.props
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ <Import Project="JavaScriptCoreCommon.props" />
+ <Import Project="JavaScriptCoreCF.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreRelease.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreRelease.props
new file mode 100644
index 000000000..593388531
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreRelease.props
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="JavaScriptCoreCommon.props" />
+ <Import Project="JavaScriptCoreCF.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreReleaseCFLite.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreReleaseCFLite.props
new file mode 100644
index 000000000..f5c263284
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCoreReleaseCFLite.props
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefinesCairo.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="JavaScriptCoreCommon.props" />
+ <Import Project="JavaScriptCoreCFLite.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make
index ea4a72902..3708c2b6c 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.make
@@ -1,9 +1,8 @@
all:
touch "%ConfigurationBuildDir%\buildfailed"
- bash build-LLIntAssembly.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
+ bash build-LLIntAssembly.sh "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)" "$(DEBUGSUFFIX)"
-del "%ConfigurationBuildDir%\buildfailed"
clean:
-del "%ConfigurationBuildDir%\buildfailed"
- -del /s /q "%ConfigurationBuildDir%\obj\LLIntOffsetsExtractor\LLIntOffsetsExtractor.exe"
- -del /s /q "%ConfigurationBuildDir%\obj\JavaScriptCore\DerivedSources\LLIntAssembly.h"
+ -del /s /q "%ConfigurationBuildDir%\obj32\JavaScriptCore\DerivedSources\LLIntAssembly.h"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj
new file mode 100644
index 000000000..4d50d4733
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/LLIntAssembly.vcxproj
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9221744B-5715-4F56-9590-42F7AB23DD8B}</ProjectGuid>
+ <RootNamespace>LLIntAssembly</RootNamespace>
+ <Keyword>MakeFileProj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">LLIntAssembly.h</NMakeOutput>
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Production|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Production|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">LLIntAssembly.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Production|x64'">LLIntAssembly.h</NMakeOutput>
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">%SystemDrive%\cygwin\bin\which.exe bash
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+nmake /nologo -f $(ProjectName).make DEBUGSUFFIX=_debug</NMakeBuildCommandLine>
+ <NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">%SystemDrive%\cygwin\bin\which.exe bash
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+nmake /nologo -f $(ProjectName).make DEBUGSUFFIX=_debug</NMakeBuildCommandLine>
+ <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">%SystemDrive%\cygwin\bin\which.exe bash
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+nmake /nologo -f $(ProjectName).make clean
+nmake /nologo -f $(ProjectName).make DEBUGSUFFIX=_debug</NMakeReBuildCommandLine>
+ <NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">%SystemDrive%\cygwin\bin\which.exe bash
+if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
+nmake /nologo -f $(ProjectName).make clean
+nmake /nologo -f $(ProjectName).make DEBUGSUFFIX=_debug</NMakeReBuildCommandLine>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="build-LLIntAssembly.sh" />
+ <None Include="LLIntAssembly.make" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh
index a809be776..e8a3b37f4 100755..100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntAssembly/build-LLIntAssembly.sh
@@ -1,6 +1,6 @@
#!/usr/bin/bash
-SRCROOT="`pwd`/../.."
+SRCROOT="`pwd`/../../.."
SRCROOT=`realpath "$SRCROOT"`
# Do a little dance to get the path into 8.3 form to make it safe for gnu make
# http://bugzilla.opendarwin.org/show_bug.cgi?id=8173
@@ -16,11 +16,11 @@ XDSTROOT=`cygpath -m -s "$XDSTROOT"`
XDSTROOT=`cygpath -u "$XDSTROOT"`
export XDSTROOT
-export BUILT_PRODUCTS_DIR="$XDSTROOT/obj"
+export BUILT_PRODUCTS_DIR="$XDSTROOT/obj32"
cd "${BUILT_PRODUCTS_DIR}/JavaScriptCore/DerivedSources"
##############################################################################
# Step 3: Build LLIntOffsetsExtractor
-/usr/bin/env ruby "${SRCROOT}/offlineasm/asm.rb" "${SRCROOT}/llint/LowLevelInterpreter.asm" "${BUILT_PRODUCTS_DIR}/LLIntOffsetsExtractor/LLIntOffsetsExtractor.exe" "LLIntAssembly.h" || exit 1
+/usr/bin/env ruby "${SRCROOT}/offlineasm/asm.rb" "${SRCROOT}/llint/LowLevelInterpreter.asm" "${BUILT_PRODUCTS_DIR}/LLIntOffsetsExtractor/LLIntOffsetsExtractor${3}.exe" "LLIntAssembly.h" || exit 1
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make
index 996c92377..f70c92bc4 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.make
@@ -1,9 +1,9 @@
all:
touch "%ConfigurationBuildDir%\buildfailed"
- bash build-LLIntDesiredOffsets.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
+ bash build-LLIntDesiredOffsets.sh "%ConfigurationBuildDir%" "$(WEBKIT_LIBRARIES)"
-del "%ConfigurationBuildDir%\buildfailed"
clean:
-del "%ConfigurationBuildDir%\buildfailed"
- -del /s /q "%ConfigurationBuildDir%\obj\JavaScriptCore\DerivedSources\LLIntDesiredOffsets.h"
+ -del /s /q "%ConfigurationBuildDir%\obj32\JavaScriptCore\DerivedSources\LLIntDesiredOffsets.h"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj
new file mode 100644
index 000000000..135fb87bd
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/LLIntDesiredOffsets.vcxproj
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{877150A0-41B3-4730-9D98-1B8298098B14}</ProjectGuid>
+ <RootNamespace>LLIntDesiredOffsets</RootNamespace>
+ <Keyword>MakeFileProj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Production|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Production|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Production|x64'">LLIntDesiredOffsets.h</NMakeOutput>
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="build-LLIntDesiredOffsets.sh" />
+ <None Include="LLIntDesiredOffsets.make" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh
index 57d715ca1..c3186fd7f 100755..100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh
@@ -1,6 +1,6 @@
#!/usr/bin/bash
-SRCROOT="`pwd`/../.."
+SRCROOT="`pwd`/../../.."
SRCROOT=`realpath "$SRCROOT"`
# Do a little dance to get the path into 8.3 form to make it safe for gnu make
# http://bugzilla.opendarwin.org/show_bug.cgi?id=8173
@@ -16,7 +16,7 @@ XDSTROOT=`cygpath -m -s "$XDSTROOT"`
XDSTROOT=`cygpath -u "$XDSTROOT"`
export XDSTROOT
-export BUILT_PRODUCTS_DIR="$XDSTROOT/obj/JavaScriptCore/DerivedSources"
+export BUILT_PRODUCTS_DIR="$XDSTROOT/obj32/JavaScriptCore/DerivedSources"
##############################################################################
# Step 1: Generate LLIntDesiredOffsets.h
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj
new file mode 100644
index 000000000..fffc03eb6
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcxproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\llint\LLIntOffsetsExtractor.cpp" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D595E3F6-24F2-4C60-935C-95D50C6B3E96}</ProjectGuid>
+ <RootNamespace>LLIntOffsetsExtractor</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorProduction.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="LLIntOffsetsExtractorProduction.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Production|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Production|x64'">$(ConfigurationBuildDir)\obj32\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+ <Link />
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props
new file mode 100644
index 000000000..88c0a95a6
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.props
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\obj32\JavaScriptCore\DerivedSources\;../../../;../../../os-win32/;../../../assembler/;../../../API/;../../../parser/;../../../heap/;../../../runtime/;../../../bytecode/;../../../interpreter/;../../../debugger/;../../../bytecompiler/;../../../profiler;../../../jit/;$(WebKit_Libraries)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>__STD_C;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ <ForcedUsingFiles>%(ForcedUsingFiles)</ForcedUsingFiles>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;winmm.lib;WTF$(DebugSuffix).lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+</Project>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props
new file mode 100644
index 000000000..462c5f5a6
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.props
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="LLIntOffsetsExtractorCommon.props" />
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.props
new file mode 100644
index 000000000..3549dab89
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ <Import Project="LLIntOffsetsExtractorCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props
new file mode 100644
index 000000000..d32fc860f
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/LLInt/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.props
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="LLIntOffsetsExtractorCommon.props" />
+ </ImportGroup>
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <Link />
+ </ItemDefinitionGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh b/Source/JavaScriptCore/JavaScriptCore.vcxproj/build-generated-files.sh
index 56316e9d7..e6b7ebb98 100755..100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/build-generated-files.sh
@@ -1,16 +1,15 @@
#!/usr/bin/bash
-NUMCPUS=`../../../../Tools/Scripts/num-cpus`
+NUMCPUS=`../../../Tools/Scripts/num-cpus`
-XSRCROOT="`pwd`/../.."
+XSRCROOT="`pwd`/.."
XSRCROOT=`realpath "$XSRCROOT"`
# Do a little dance to get the path into 8.3 form to make it safe for gnu make
# http://bugzilla.opendarwin.org/show_bug.cgi?id=8173
-XSRCROOT=`cygpath -m -s "$XSRCROOT"`
+XSRCROOT=`cygpath -m "$XSRCROOT"`
XSRCROOT=`cygpath -u "$XSRCROOT"`
export XSRCROOT
export SOURCE_ROOT=$XSRCROOT
-
XDSTROOT="$1"
export XDSTROOT
# Do a little dance to get the path into 8.3 form to make it safe for gnu make
@@ -27,7 +26,7 @@ SDKROOT=`cygpath -m -s "$SDKROOT"`
SDKROOT=`cygpath -u "$SDKROOT"`
export SDKROOT
-export BUILT_PRODUCTS_DIR="$XDSTROOT/obj/JavaScriptCore"
+export BUILT_PRODUCTS_DIR="$XDSTROOT/obj32/JavaScriptCore"
mkdir -p "${BUILT_PRODUCTS_DIR}/DerivedSources/docs"
cd "${BUILT_PRODUCTS_DIR}/DerivedSources"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/copy-files.cmd
index 0a32c319a..8d1e46f1e 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/copy-files.cmd
@@ -1,67 +1,68 @@
-@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
- disassembler
- 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
+@echo off
+
+set PublicHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\JavaScriptCore
+set PrivateHeadersDirectory=%CONFIGURATIONBUILDDIR%\include\private\JavaScriptCore
+set ResourcesDirectory=%CONFIGURATIONBUILDDIR%\bin32\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
+ JSClassRef.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
+ disassembler
+ 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.vcxproj/jsc/jsc.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj
new file mode 100644
index 000000000..ca9e1f78f
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{2BD437CF-BDAC-4119-9ED6-E10EF46C69F3}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>jsc</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscProduction.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="jscProduction.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\jsc.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="jscPostBuild.cmd" />
+ <None Include="jscPreBuild.cmd" />
+ <None Include="jscPreLink.cmd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters
new file mode 100644
index 000000000..47638ede7
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jsc.vcxproj.filters
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\jsc.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="jscPostBuild.cmd" />
+ <None Include="jscPreLink.cmd" />
+ <None Include="jscPreBuild.cmd" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscCommon.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscCommon.props
new file mode 100644
index 000000000..bed03fdfd
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscCommon.props
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\;..\..\tools\;..\..\runtime\;..\..\llint\;..\..\jit\;..\..\disassembler\;..\..\heap\;..\..\debugger\;..\..\assembler\;..\..\profiler\;..\..\interpreter\;..\..\bytecode\;..\..\dfg\;..\..\bytecompiler\;..\..\parser\;..\..\API\;$(ConfigurationBuildDir)\include\;$(ConfigurationBuildDir)\include\private\;$(ConfigurationBuildDir)\include\JavaScriptCore\;$(ConfigurationBuildDir)\obj32\JavaScriptCore\DerivedSources\;$(WebKit_Libraries)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>WTF$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;winmm.lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>
+ </ModuleDefinitionFile>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscDebug.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscDebug.props
new file mode 100644
index 000000000..3b3bc7663
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscDebug.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="jscCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd
new file mode 100644
index 000000000..02da44bdc
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPostBuild.cmd
@@ -0,0 +1 @@
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed" \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd
index a77077674..a77077674 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscPreBuild.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreBuild.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreLink.cmd
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscPreLink.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscProduction.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscProduction.props
new file mode 100644
index 000000000..396c1b3df
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscProduction.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ <Import Project="jscCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscRelease.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscRelease.props
new file mode 100644
index 000000000..9a1b6626b
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/jsc/jscRelease.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\FeatureDefines.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="jscCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/resource.h b/Source/JavaScriptCore/JavaScriptCore.vcxproj/resource.h
new file mode 100644
index 000000000..052eb0d0e
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by JavaScriptCore.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj
new file mode 100644
index 000000000..2d1c9706a
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{BB16286B-AADC-46C1-BC0D-6C06F323E04B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>textRegExp</RootNamespace>
+ <ProjectName>testRegExp</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpProduction.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testRegExpProduction.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <PreBuildEvent />
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testRegExp.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="testRegExpPostBuild.cmd" />
+ <None Include="testRegExpPreBuild.cmd" />
+ <None Include="testRegExpPreLink.cmd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj.filters b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj.filters
new file mode 100644
index 000000000..73b65999a
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExp.vcxproj.filters
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\testRegExp.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="testRegExpPostBuild.cmd" />
+ <None Include="testRegExpPreBuild.cmd" />
+ <None Include="testRegExpPreLink.cmd" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props
new file mode 100644
index 000000000..62881b31b
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpCommon.props
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PreprocessorDefinitions>_CONSOLE;__STD_C;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\obj32\JavaScriptCore\DerivedSources;..\..\;..\..\os-win32;..\..\assembler;..\..\API;..\..\parser;..\..\heap;..\..\runtime;..\..\bytecode;..\..\interpreter;..\..\debugger;..\..\bytecompiler;..\..\profiler;..\..\jit;$(WebKit_Libraries)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>JavaScriptCore$(DebugSuffix).lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;WTF$(DebugSuffix).lib;winmm.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpDebug.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpDebug.props
new file mode 100644
index 000000000..6e8ad946d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpDebug.props
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="testRegExpCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Manifest>
+ <AssemblyIdentity>
+ </AssemblyIdentity>
+ </Manifest>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd
new file mode 100644
index 000000000..0204125ca
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPostBuild.cmd
@@ -0,0 +1,3 @@
+if exist "%CONFIGURATIONBUILDDIR%\buildfailed" del "%CONFIGURATIONBUILDDIR%\buildfailed"
+
+cmd /c
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd
index a77077674..a77077674 100755..100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testRegExp/testRegExpPreBuild.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreBuild.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpPreLink.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpProduction.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpProduction.props
new file mode 100644
index 000000000..7e6b5b248
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpProduction.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ <Import Project="testRegExpCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpRelease.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpRelease.props
new file mode 100644
index 000000000..069677a21
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testRegExp/testRegExpRelease.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="testRegExpCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj
new file mode 100644
index 000000000..547b26af0
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugSuffix|Win32">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugSuffix|x64">
+ <Configuration>DebugSuffix</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|Win32">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug_WinCairo|x64">
+ <Configuration>Debug_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|Win32">
+ <Configuration>Production</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Production|x64">
+ <Configuration>Production</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|Win32">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_WinCairo|x64">
+ <Configuration>Release_WinCairo</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{5CC08E13-2CF9-4C2E-8544-07DA4E8C1843}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>testapi</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiDebug.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiDebugCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiDebugCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiDebug.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debugsuffix.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiRelease.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiReleaseCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiReleaseCFLite.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiProduction.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="testapiProduction.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'" />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Production|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <ForcedIncludeFiles>ICUVersion.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
+ </ClCompile>
+ <Link />
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="..\..\API\tests\testapi.js" />
+ <None Include="testapiPostBuild.cmd" />
+ <None Include="testapiPreBuild.cmd" />
+ <None Include="testapiPreLink.cmd" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\API\tests\testapi.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters
new file mode 100644
index 000000000..87ead9cc9
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <None Include="..\..\API\tests\testapi.js" />
+ <None Include="testapiPostBuild.cmd" />
+ <None Include="testapiPreBuild.cmd" />
+ <None Include="testapiPreLink.cmd" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\API\tests\testapi.c" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommon.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommon.props
new file mode 100644
index 000000000..c8c791a7d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommon.props
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalDependencies>CoreFoundation$(DebugSuffix).lib;JavaScriptCore$(DebugSuffix).lib;WTF$(DebugSuffix).lib;libicuin$(DebugSuffix).lib;libicuuc$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <ClCompile>
+ <PreprocessorDefinitions>NOMINMAX;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(ProjectDir)\..\..\API;$(ConfigurationBuildDir)\include\JavaScriptCore;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props
new file mode 100644
index 000000000..0da8cdf70
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiCommonCFLite.props
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <Link>
+ <AdditionalDependencies>CFLite.lib;JavaScriptCore$(DebugSuffix).lib;WTF$(DebugSuffix).lib;libicuin.lib;libicuuc.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ <ClCompile>
+ <PreprocessorDefinitions>NOMINMAX;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(ProjectDir)\..\..\API;$(ConfigurationBuildDir)\include\JavaScriptCore;$(ConfigurationBuildDir)\include\private\JavaScriptCore;$(ConfigurationBuildDir)\include;$(ConfigurationBuildDir)\include\private;$(WebKit_Libraries)\include;$(WebKit_Libraries)\include\private;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebug.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebug.props
new file mode 100644
index 000000000..8dc5cc955
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebug.props
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="testapiCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_PropertySheetDisplayName>testapiDebug</_PropertySheetDisplayName>
+ </PropertyGroup>
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebugCFLite.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebugCFLite.props
new file mode 100644
index 000000000..0aead2d2f
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiDebugCFLite.props
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\debug.props" />
+ <Import Project="testapiCommonCFLite.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_PropertySheetDisplayName>testapiDebug</_PropertySheetDisplayName>
+ </PropertyGroup>
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project>
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPostBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPostBuild.cmd
index 0820433b0..0820433b0 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPostBuild.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPostBuild.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreBuild.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd
index a77077674..a77077674 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiPreBuild.cmd
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreBuild.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreLink.cmd b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreLink.cmd
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiPreLink.cmd
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiProduction.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiProduction.props
new file mode 100644
index 000000000..b2ef74756
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiProduction.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\production.props" />
+ <Import Project="testapiCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiRelease.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiRelease.props
new file mode 100644
index 000000000..cd9b500b2
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiRelease.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="testapiCommon.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project> \ No newline at end of file
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiReleaseCFLite.props b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiReleaseCFLite.props
new file mode 100644
index 000000000..efb49e7e4
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapiReleaseCFLite.props
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\common.props" />
+ <Import Project="$(WebKit_Libraries)\tools\vsprops\release.props" />
+ <Import Project="testapiCommonCFLite.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup />
+ <ItemGroup />
+</Project>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 61867036a..e047fabf7 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -58,6 +58,7 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
+ 0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0776BD14FF002800102332 /* JITCompilationEffort.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
@@ -73,6 +74,10 @@
0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */; };
0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13912416771C30009CCB07 /* ProfilerBytecodeSequence.cpp */; };
+ 0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912516771C30009CCB07 /* ProfilerBytecodeSequence.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13912616771C30009CCB07 /* ProfilerProfiledBytecodes.cpp */; };
+ 0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; };
0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */; };
@@ -102,6 +107,13 @@
0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */; };
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 */; };
+ 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2F16828A7E003C2F8D /* UnusedPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */; };
+ 0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
+ 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */; };
0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */; };
@@ -126,20 +138,24 @@
0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */; };
0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; };
0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
+ 0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F5EF91E16878F7A003E5C25 /* JITThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */; };
+ 0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5EF91C16878F78003E5C25 /* JITThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
- 0F63943F15C75F19006A597C /* DFGStructureCheckHoistingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63943C15C75F14006A597C /* DFGStructureCheckHoistingPhase.cpp */; };
+ 0F63943F15C75F19006A597C /* DFGTypeCheckHoistingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */; };
0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63945115D07051006A597C /* ArrayProfile.cpp */; };
0F63945515D07057006A597C /* ArrayProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63945215D07051006A597C /* ArrayProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -147,6 +163,8 @@
0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63948215E48114006A597C /* DFGArrayMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
+ 0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */; };
0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */; };
@@ -164,7 +182,6 @@
0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8023E91613832300A0BA45 /* ByValInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */; };
@@ -192,6 +209,9 @@
0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329B14CA7DC10085F3C6 /* StructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */; };
+ 0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D336E165DBB8D005AD387 /* Disassembler.cpp */; };
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, ); }; };
@@ -201,6 +221,12 @@
0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; };
0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105821675480C00F8AB6E /* ExitKind.cpp */; };
+ 0FB105861675481200F8AB6E /* ExitKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB105831675480C00F8AB6E /* ExitKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105871675482E00F8AB6E /* ProfilerOSRExit.cpp */; };
+ 0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB105881675482E00F8AB6E /* ProfilerOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB105891675482E00F8AB6E /* ProfilerOSRExitSite.cpp */; };
+ 0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.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, ); }; };
@@ -218,6 +244,12 @@
0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */; };
0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBD7E691447999600481315 /* CodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBD7E671447998F00481315 /* CodeOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */; };
+ 0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */; };
+ 0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */; };
+ 0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976D1468AB4E00CF2442 /* DFGAssemblyHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976E1468AB5100CF2442 /* DFGAssemblyHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */; };
@@ -226,14 +258,14 @@
0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC09775146943AD00CF2442 /* DFGOSRExitCompiler32_64.cpp */; };
0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */; };
0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */; };
- 0FC0979C146A772500CF2442 /* DFGCorrectableJumpPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FC0979E146B272100CF2442 /* DFGCorrectableJumpPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */; };
0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; };
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC815141405118D00CFA603 /* VTableSpectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC815121405118600CFA603 /* VTableSpectrum.cpp */; };
+ 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2C92316D01EE900C7803F /* StructureInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */; };
0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3C82214115D0E00FD81CB /* DFGDriver.h */; };
0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */; };
@@ -250,6 +282,15 @@
0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; };
0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; };
+ 0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */; };
+ 0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */; };
+ 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51D16B62772003F696B /* DFGLongLivedState.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51E16B62772003F696B /* DFGNode.cpp */; };
+ 0FF0F19D16B72A08005DF95B /* DFGCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51A16B62772003F696B /* DFGCommon.cpp */; };
+ 0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51B16B62772003F696B /* DFGEdge.cpp */; };
+ 0FF0F19F16B72A17005DF95B /* FunctionExecutableDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */; };
+ 0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FF42731158EBD54004CB9FF /* Disassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4272F158EBD44004CB9FF /* Disassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF42730158EBD44004CB9FF /* UDis86Disassembler.cpp */; };
0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 0FF42734158EBD94004CB9FF /* udis86_decode.c */; };
@@ -270,8 +311,35 @@
0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */; };
0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF60AC016740F8100029779 /* ReduceWhitespace.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF60ABF16740F8100029779 /* ReduceWhitespace.cpp */; };
0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7168A15A3B231008F5DAA /* PropertyOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729A5166AD351000F5BA3 /* ProfilerBytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF72993166AD347000F5BA3 /* ProfilerBytecode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF72992166AD347000F5BA3 /* ProfilerBytecode.cpp */; };
+ 0FF729AE166AD35C000F5BA3 /* ProfilerBytecodes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF72994166AD347000F5BA3 /* ProfilerBytecodes.cpp */; };
+ 0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF72996166AD347000F5BA3 /* ProfilerCompilation.cpp */; };
+ 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF72998166AD347000F5BA3 /* ProfilerCompilationKind.cpp */; };
+ 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF7299A166AD347000F5BA3 /* ProfilerCompiledBytecode.cpp */; };
+ 0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF7299C166AD347000F5BA3 /* ProfilerDatabase.cpp */; };
+ 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF7299F166AD347000F5BA3 /* ProfilerOrigin.cpp */; };
+ 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */; };
+ 0FF729B9166AD360000F5BA3 /* ProfilerBytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF72995166AD347000F5BA3 /* ProfilerBytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF72997166AD347000F5BA3 /* ProfilerCompilation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF72999166AD347000F5BA3 /* ProfilerCompilationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7299B166AD347000F5BA3 /* ProfilerCompiledBytecode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7299D166AD347000F5BA3 /* ProfilerDatabase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7299E166AD347000F5BA3 /* ProfilerExecutionCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FF922D414F46B410041A24E /* LLIntOffsetsExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */; };
+ 0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51916B62772003F696B /* DFGAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB921E16D02F470055A5DB /* DFGVariadicFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB921F16D033050055A5DB /* (null) in Headers */ = {isa = PBXBuildFile; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 930DAD030FB1EB1A0082D205 /* NodeConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */; };
0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC94D14EF909500C72532 /* DFGCSEPhase.cpp */; };
@@ -331,7 +399,6 @@
142E313A134FF0A600AFADB5 /* LocalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 142E3131134FF0A600AFADB5 /* LocalScope.h */; };
142E313B134FF0A600AFADB5 /* Strong.h in Headers */ = {isa = PBXBuildFile; fileRef = 142E3132134FF0A600AFADB5 /* Strong.h */; settings = {ATTRIBUTES = (Private, ); }; };
142E313C134FF0A600AFADB5 /* Weak.h in Headers */ = {isa = PBXBuildFile; fileRef = 142E3133134FF0A600AFADB5 /* Weak.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 143A97E60A4A06E200456B66 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
1440057F0A5335640005F061 /* JSNode.c in Sources */ = {isa = PBXBuildFile; fileRef = 1440F6420A4F8B6A0005F061 /* JSNode.c */; };
144005CB0A5338D10005F061 /* JSNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F6410A4F8B6A0005F061 /* JSNode.h */; };
144005CC0A5338F80005F061 /* Node.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440051F0A531D3B0005F061 /* Node.h */; };
@@ -365,6 +432,8 @@
146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146AAB370B66A94400E55F16 /* JSStringRefCF.cpp */; };
146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */; };
146FE51211A710430087AE66 /* JITCall32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 146FE51111A710430087AE66 /* JITCall32_64.cpp */; };
+ 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */; };
1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 146FA5A81378F6B0003627A3 /* HandleTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; };
147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -391,7 +460,7 @@
147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */; };
147F39D4107EC37600427A48 /* JSObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A3980E16E14800AF21C8 /* JSObject.cpp */; };
147F39D5107EC37600427A48 /* JSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B60E1842FA000F9297 /* JSString.cpp */; };
- 147F39D6107EC37600427A48 /* JSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSValue.cpp */; };
+ 147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSCJSValue.cpp */; };
147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */; };
14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14816E19154CC56C00B8054C /* BlockAllocator.cpp */; };
14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14816E1A154CC56C00B8054C /* BlockAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -410,8 +479,6 @@
1497209114EB831500FEB1B7 /* PassWeak.h in Headers */ = {isa = PBXBuildFile; fileRef = 1497209014EB831500FEB1B7 /* PassWeak.h */; settings = {ATTRIBUTES = (Private, ); }; };
14A1563210966365006FA260 /* DateInstanceCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A1563010966365006FA260 /* DateInstanceCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */; };
- 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 */; };
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, ); }; };
@@ -422,10 +489,14 @@
14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; };
+ 14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BE7D3217135CF400D1807A /* WeakInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A6581A0F4E36F4000150FD /* JITStubs.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14CA958B16AB50DE00938A06 /* StaticPropertyAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CA958A16AB50DE00938A06 /* StaticPropertyAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14CA958D16AB50FA00938A06 /* ObjectAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
14D2F3DA139F4BE200491031 /* MarkedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14D2F3D8139F4BE200491031 /* MarkedSpace.cpp */; };
14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D2F3D9139F4BE200491031 /* MarkedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 14DF04DA16B3996D0016A513 /* StaticPropertyAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */; settings = {ATTRIBUTES = (Private, ); }; };
14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */; };
14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E84F9A14EE1ACC00D6D5D4 /* WeakBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14E84F9B14EE1ACC00D6D5D4 /* WeakSet.cpp */; };
@@ -435,9 +506,12 @@
14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */; };
14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F7256414EE265E00B1652B /* WeakHandleOwner.h */; settings = {ATTRIBUTES = (Private, ); }; };
14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F97446138C853E00DA1C67 /* HeapRootVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACF7376171CA6FB00C9BB1E /* Weak.cpp */; };
2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */; };
2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; };
41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; };
+ 4443AE3316E188D90076F110 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
@@ -450,9 +524,12 @@
6511230714046B0A002B101D /* testRegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 651122E5140469BA002B101D /* testRegExp.cpp */; };
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 */; };
+ 65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */; };
+ 65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */; };
+ 65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C0285B1717966800351E35 /* ARMv7DOpcode.h */; };
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 */; };
+ 7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0894D60FAFBA2D00001865 /* JSAPIValueWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -467,7 +544,7 @@
863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */; };
8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86F75EFB151C062F007C9BA3 /* RegExpCachedResult.cpp */; };
8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86F75EFD151C062F007C9BA3 /* RegExpMatchesArray.cpp */; };
- 865A30F1135007E100CDB49E /* JSValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSValueInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 865A30F1135007E100CDB49E /* JSCJSValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSCJSValueInlines.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 */; };
@@ -488,15 +565,14 @@
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 86AE64A8135E5E1C00963012 /* MacroAssemblerSH4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86AE64A5135E5E1C00963012 /* MacroAssemblerSH4.cpp */; };
86AE64A9135E5E1C00963012 /* MacroAssemblerSH4.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE64A6135E5E1C00963012 /* MacroAssemblerSH4.h */; settings = {ATTRIBUTES = (Private, ); }; };
86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE64A7135E5E1C00963012 /* SH4Assembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 86AE6C4D136A11E400963012 /* DFGFPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE6C4B136A11E400963012 /* DFGFPRInfo.h */; };
- 86AE6C4E136A11E400963012 /* DFGGPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE6C4C136A11E400963012 /* DFGGPRInfo.h */; };
+ 86AE6C4D136A11E400963012 /* DFGFPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE6C4B136A11E400963012 /* DFGFPRInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86AE6C4E136A11E400963012 /* DFGGPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AE6C4C136A11E400963012 /* DFGGPRInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B5822E14D2373B00A9C306 /* CodeProfile.cpp */; };
86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */; };
86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86BB09BE138E381B0056702F /* DFGRepatch.cpp */; };
- 86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; };
+ 86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BB09BF138E381B0056702F /* DFGRepatch.h */; settings = {ATTRIBUTES = (Private, ); }; };
86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -507,6 +583,7 @@
86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85A20EE79B7400288682 /* JITCall.cpp */; };
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, ); }; };
+ 86D2221A167EF9440024C804 /* testapi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86D22219167EF9440024C804 /* testapi.mm */; };
86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */; };
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C010156BDE002865E7 /* ARMAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
86D3B2C510156BDE002865E7 /* AssemblerBufferWithConstantPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -515,6 +592,18 @@
86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C210159D7F002865E7 /* RepatchBuffer.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 */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86E3C612167BABD7006D760A /* JSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C606167BAB87006D760A /* JSValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 86E3C613167BABD7006D760A /* JSContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C607167BAB87006D760A /* JSContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 86E3C614167BABD7006D760A /* JSExport.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60A167BAB87006D760A /* JSExport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60F167BAB87006D760A /* JSVirtualMachine.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 86E3C616167BABEE006D760A /* JSContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86E3C608167BAB87006D760A /* JSContext.mm */; };
+ 86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C609167BAB87006D760A /* JSContextInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86E3C60B167BAB87006D760A /* JSWrapperMap.mm */; };
+ 86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60C167BAB87006D760A /* JSWrapperMap.h */; };
+ 86E3C61A167BABEE006D760A /* JSValue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86E3C60D167BAB87006D760A /* JSValue.mm */; };
+ 86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60E167BAB87006D760A /* JSValueInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86E3C61C167BABEE006D760A /* JSVirtualMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86E3C610167BAB87006D760A /* JSVirtualMachine.mm */; };
+ 86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2F91560F036008E9222 /* NameConstructor.cpp */; };
86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FA1560F036008E9222 /* NameConstructor.h */; };
@@ -523,19 +612,22 @@
86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EBF2FD1560F036008E9222 /* NamePrototype.cpp */; };
86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EBF2FE1560F036008E9222 /* NamePrototype.h */; };
86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */; };
- 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */; };
- 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */; };
+ 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */; };
- 86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */; };
+ 86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB81328DF82002B2AD7 /* DFGGraph.h */; settings = {ATTRIBUTES = (Private, ); }; };
86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DBB1328DF82002B2AD7 /* DFGJITCompiler.cpp */; };
- 86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */; };
+ 86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */; };
- 86EC9DD01328DF82002B2AD7 /* DFGOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */; };
- 86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */; };
+ 86EC9DD01328DF82002B2AD7 /* DFGOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */; settings = {ATTRIBUTES = (Private, ); }; };
86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */; };
- 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 */; };
+ 86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86ECA3EA132DEF1C002B2AD7 /* DFGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86F3EEBD168CDE930077B92A /* ObjCCallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F3EEB9168CCF750077B92A /* ObjCCallbackFunction.h */; };
+ 86F3EEBE168CDE930077B92A /* ObjCCallbackFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86F3EEBA168CCF750077B92A /* ObjCCallbackFunction.mm */; };
+ 86F3EEBF168CDE930077B92A /* ObjcRuntimeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F3EEB616855A5B0077B92A /* ObjcRuntimeExtras.h */; };
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 */; };
@@ -552,7 +644,7 @@
9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93345A8712D838C400302BE3 /* StringRecursionChecker.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 */; };
- 95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */; };
+ 95AB83420DA4322500BC83F3 /* LegacyProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB832E0DA42CAD00BC83F3 /* LegacyProfiler.cpp */; };
95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95AB83540DA43B4400BC83F3 /* ProfileNode.cpp */; };
95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95CD45740E1C4FDD0085358E /* ProfileGenerator.cpp */; };
95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 95CD45750E1C4FDD0085358E /* ProfileGenerator.h */; settings = {ATTRIBUTES = (); }; };
@@ -566,18 +658,20 @@
969A072A0ED1CE6900F1F681 /* Label.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07270ED1CE6900F1F681 /* Label.h */; };
969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07280ED1CE6900F1F681 /* RegisterID.h */; };
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 */; };
+ 969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07910ED1D3AE00F1F681 /* CodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 969A07980ED1D3AE00F1F681 /* EvalCodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07930ED1D3AE00F1F681 /* Instruction.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
- 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, ); }; };
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, ); }; };
A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */; };
+ A72028B61797601E0098028C /* JSCTestRunnerUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */; };
+ A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B51797601E0098028C /* JSCTestRunnerUtils.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A72028BA1797603D0098028C /* JSFunctionInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = A72028B91797603D0098028C /* JSFunctionInlines.h */; };
A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
@@ -593,21 +687,22 @@
A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; };
A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */; };
- A7521E131429169A003C8D0C /* CardSet.h in Headers */ = {isa = PBXBuildFile; fileRef = A7521E121429169A003C8D0C /* CardSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */; };
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = A76C51741182748D00715B05 /* JSInterfaceJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */; };
- A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */; };
+ A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
A77F1821164088B200640A47 /* CodeCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A77F181F164088B200640A47 /* CodeCache.cpp */; };
A77F1822164088B200640A47 /* CodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A77F1820164088B200640A47 /* CodeCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
A77F1825164192C700640A47 /* ParserModes.h in Headers */ = {isa = PBXBuildFile; fileRef = A77F18241641925400640A47 /* ParserModes.h */; settings = {ATTRIBUTES = (Private, ); }; };
- A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; };
- A784A26411D16622005776AC /* SyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */; };
+ A784A26111D16622005776AC /* ASTBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7411B98B8D0065A14F /* ASTBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A784A26411D16622005776AC /* SyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7AFC17915F7EFE30048F57B /* ResolveOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = A7AFC17715F7EFE30048F57B /* ResolveOperation.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, ); }; };
A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */; };
A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */; };
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 */; };
@@ -617,6 +712,7 @@
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, ); }; };
A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
+ ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; };
BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9070E1839DB000F9297 /* ErrorPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */; };
@@ -651,10 +747,10 @@
BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F88F0A508B100005F061 /* JSCallbackFunction.h */; };
BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */; };
BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */; };
- BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440FCE10A51E46B0005F061 /* JSClassRef.h */; };
+ BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440FCE10A51E46B0005F061 /* JSClassRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A85F0255597D01FF60F7 /* JSFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */ = {isa = PBXBuildFile; fileRef = E18E3A560DF9278C00D90B34 /* JSGlobalData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C4200E16F5CD00B34460 /* VM.h in Headers */ = {isa = PBXBuildFile; fileRef = E18E3A560DF9278C00D90B34 /* VM.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E894330CD0603F00367179 /* JSGlobalObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4230E16F5CD00B34460 /* JSLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EA4C9A092AF9E20093D800 /* JSLock.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BC22A3990E16E14800AF21C8 /* JSObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -664,11 +760,11 @@
BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B74B0A43032800517CFC /* JSStringRef.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */ = {isa = PBXBuildFile; fileRef = 146AAB2A0B66A84900E55F16 /* JSStringRefCF.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB454099C2A0F00E2A24F /* JSType.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C42B0E16F5CD00B34460 /* JSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB36E099C076400E2A24F /* JSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C42B0E16F5CD00B34460 /* JSCJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 14ABB36E099C076400E2A24F /* JSCJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B6EA0A4300B300517CFC /* JSValueRef.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 */; };
+ BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8660255597D01FF60F7 /* Lexer.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8690255597D01FF60F7 /* Lookup.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86B0255597D01FF60F7 /* MathObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86E0255597D01FF60F7 /* Nodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -676,13 +772,13 @@
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, ); }; };
BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C50E16D4E900A06E92 /* NumberPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */; };
+ BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
- BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.h */; settings = {ATTRIBUTES = (); }; };
+ BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.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, ); }; };
+ BC18C4520E16F5CD00B34460 /* LegacyProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB832F0DA42CAD00BC83F3 /* LegacyProfiler.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, ); }; };
@@ -712,7 +808,7 @@
BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureTransitionTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = BCBE2CAD14E985AA000593AD /* GCAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */; };
+ BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */; };
BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */; };
BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */; };
@@ -725,7 +821,9 @@
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, ); }; };
BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
- BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; };
+ BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C20B25991706536200C21F4E /* Region.h in Headers */ = {isa = PBXBuildFile; fileRef = C20B25981706536200C21F4E /* Region.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; };
C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; };
C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122E015DD9AB300790E3A /* MarkStackInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -741,25 +839,35 @@
C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C240305314B404C90079EB64 /* CopiedSpace.cpp */; };
C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */; };
C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = C24D31E1161CD695002AA4DB /* HeapStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */ = {isa = PBXBuildFile; fileRef = C25D709916DE99F400FCA6BC /* JSManagedValue.mm */; };
+ C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = C25D709A16DE99F400FCA6BC /* JSManagedValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; };
C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */ = {isa = PBXBuildFile; fileRef = C25F8BCC157544A900245B71 /* IncrementalSweeper.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C28318FF16FE4B7D00157BFD /* HandleBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C283190216FE533E00157BFD /* HandleBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C283190116FE533E00157BFD /* HandleBlockInlines.h */; };
C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A7F687160432D400F76B98 /* JSDestructibleObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
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 /* CopiedSpaceInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */; };
+ C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */; };
C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */; };
+ C2DF442F1707AC0100A5CA96 /* SuperRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */; };
+ C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = C2DF442E1707AC0100A5CA96 /* SuperRegion.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2E526BB1590EF000054E48D /* HeapTimer.cpp */; };
C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = C2E526BC1590EF000054E48D /* HeapTimer.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAA3F8149A830800FCE112 /* CopiedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C2F0F2D116BAEEE900187C19 /* StructureRareData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */; };
C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FE18A316BAEC4000AF3061 /* StructureRareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
- E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */; };
+ E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* VM.cpp */; };
E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49DC15512EF277200184A1F /* SourceProviderCache.cpp */; };
E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC15112EF272200184A1F /* SourceProviderCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -767,7 +875,11 @@
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FE6617281774E03500495B00 /* VMStackBounds.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6617271774E03500495B00 /* VMStackBounds.h */; settings = {ATTRIBUTES = (Private, ); }; };
FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
+ FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -862,6 +974,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayifySlowPathGenerator.h; path = dfg/DFGArrayifySlowPathGenerator.h; sourceTree = "<group>"; };
0F0776BD14FF002800102332 /* JITCompilationEffort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCompilationEffort.h; sourceTree = "<group>"; };
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>"; };
@@ -877,6 +990,10 @@
0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutDirectIndexMode.h; sourceTree = "<group>"; };
0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SparseArrayValueMap.cpp; sourceTree = "<group>"; };
0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; };
+ 0F13912416771C30009CCB07 /* ProfilerBytecodeSequence.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerBytecodeSequence.cpp; path = profiler/ProfilerBytecodeSequence.cpp; sourceTree = "<group>"; };
+ 0F13912516771C30009CCB07 /* ProfilerBytecodeSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerBytecodeSequence.h; path = profiler/ProfilerBytecodeSequence.h; sourceTree = "<group>"; };
+ 0F13912616771C30009CCB07 /* ProfilerProfiledBytecodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerProfiledBytecodes.cpp; path = profiler/ProfilerProfiledBytecodes.cpp; sourceTree = "<group>"; };
+ 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerProfiledBytecodes.h; path = profiler/ProfilerProfiledBytecodes.h; sourceTree = "<group>"; };
0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; };
0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsSimplificationPhase.cpp; path = dfg/DFGArgumentsSimplificationPhase.cpp; sourceTree = "<group>"; };
@@ -907,6 +1024,11 @@
0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableEvent.cpp; path = dfg/DFGVariableEvent.cpp; sourceTree = "<group>"; };
0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGCodeBlocks.cpp; sourceTree = "<group>"; };
0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGCodeBlocks.h; sourceTree = "<group>"; };
+ 0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDCEPhase.cpp; path = dfg/DFGDCEPhase.cpp; sourceTree = "<group>"; };
+ 0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDCEPhase.h; path = dfg/DFGDCEPhase.h; sourceTree = "<group>"; };
+ 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
+ 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
+ 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicAccessStructureList.h; sourceTree = "<group>"; };
0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGConstantFoldingPhase.cpp; path = dfg/DFGConstantFoldingPhase.cpp; sourceTree = "<group>"; };
0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGConstantFoldingPhase.h; path = dfg/DFGConstantFoldingPhase.h; sourceTree = "<group>"; };
0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFGSimplificationPhase.cpp; path = dfg/DFGCFGSimplificationPhase.cpp; sourceTree = "<group>"; };
@@ -932,21 +1054,24 @@
0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; };
0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; };
0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; };
+ 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; };
0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; };
0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = "<group>"; };
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>"; };
- 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
+ 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThunkGenerator.h; sourceTree = "<group>"; };
+ 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITThunks.cpp; sourceTree = "<group>"; };
+ 0F5EF91C16878F78003E5C25 /* JITThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITThunks.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>"; };
0F62016E143FCD2F0068B77C /* DFGAbstractState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractState.h; path = dfg/DFGAbstractState.h; sourceTree = "<group>"; };
0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractValue.h; path = dfg/DFGAbstractValue.h; sourceTree = "<group>"; };
0F620170143FCD2F0068B77C /* DFGBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlock.h; path = dfg/DFGBasicBlock.h; sourceTree = "<group>"; };
0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessData.h; path = dfg/DFGVariableAccessData.h; sourceTree = "<group>"; };
- 0F63943C15C75F14006A597C /* DFGStructureCheckHoistingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureCheckHoistingPhase.cpp; path = dfg/DFGStructureCheckHoistingPhase.cpp; sourceTree = "<group>"; };
- 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureCheckHoistingPhase.h; path = dfg/DFGStructureCheckHoistingPhase.h; sourceTree = "<group>"; };
+ 0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGTypeCheckHoistingPhase.cpp; path = dfg/DFGTypeCheckHoistingPhase.cpp; sourceTree = "<group>"; };
+ 0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGTypeCheckHoistingPhase.h; path = dfg/DFGTypeCheckHoistingPhase.h; sourceTree = "<group>"; };
0F63945115D07051006A597C /* ArrayProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayProfile.cpp; sourceTree = "<group>"; };
0F63945215D07051006A597C /* ArrayProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayProfile.h; sourceTree = "<group>"; };
0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureAbstractValue.h; path = dfg/DFGStructureAbstractValue.h; sourceTree = "<group>"; };
@@ -954,6 +1079,8 @@
0F63948215E48114006A597C /* DFGArrayMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayMode.h; path = dfg/DFGArrayMode.h; sourceTree = "<group>"; };
0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
+ 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = "<group>"; };
+ 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBackwardsPropagationPhase.h; path = dfg/DFGBackwardsPropagationPhase.h; sourceTree = "<group>"; };
0F73D7AB165A142A00ACAB71 /* ClosureCallStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClosureCallStubRoutine.cpp; sourceTree = "<group>"; };
0F73D7AC165A142A00ACAB71 /* ClosureCallStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClosureCallStubRoutine.h; sourceTree = "<group>"; };
0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = "<group>"; };
@@ -975,6 +1102,7 @@
0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayAllocationProfile.cpp; sourceTree = "<group>"; };
0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; };
0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; };
+ 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariadicFunction.h; path = dfg/DFGVariadicFunction.h; sourceTree = "<group>"; };
0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeSpecializationKind.cpp; sourceTree = "<group>"; };
0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlockHash.cpp; sourceTree = "<group>"; };
0F8F943E1667632D00D61971 /* CodeBlockHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockHash.h; sourceTree = "<group>"; };
@@ -997,6 +1125,9 @@
0F93329B14CA7DC10085F3C6 /* StructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureSet.h; sourceTree = "<group>"; };
0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
+ 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCellInlines.h; sourceTree = "<group>"; };
+ 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PreciseJumpTargets.cpp; sourceTree = "<group>"; };
+ 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargets.h; sourceTree = "<group>"; };
0F9D336E165DBB8D005AD387 /* Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Disassembler.cpp; path = disassembler/Disassembler.cpp; sourceTree = "<group>"; };
0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicPutByIdList.cpp; sourceTree = "<group>"; };
0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicPutByIdList.h; sourceTree = "<group>"; };
@@ -1006,6 +1137,22 @@
0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeType.h; path = dfg/DFGNodeType.h; sourceTree = "<group>"; };
0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; };
0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; };
+ 0FB105821675480C00F8AB6E /* ExitKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExitKind.cpp; sourceTree = "<group>"; };
+ 0FB105831675480C00F8AB6E /* ExitKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExitKind.h; sourceTree = "<group>"; };
+ 0FB105871675482E00F8AB6E /* ProfilerOSRExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOSRExit.cpp; path = profiler/ProfilerOSRExit.cpp; sourceTree = "<group>"; };
+ 0FB105881675482E00F8AB6E /* ProfilerOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOSRExit.h; path = profiler/ProfilerOSRExit.h; sourceTree = "<group>"; };
+ 0FB105891675482E00F8AB6E /* ProfilerOSRExitSite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOSRExitSite.cpp; path = profiler/ProfilerOSRExitSite.cpp; sourceTree = "<group>"; };
+ 0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOSRExitSite.h; path = profiler/ProfilerOSRExitSite.h; sourceTree = "<group>"; };
+ 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = "<group>"; };
+ 0FB4B51916B62772003F696B /* DFGAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAllocator.h; path = dfg/DFGAllocator.h; sourceTree = "<group>"; };
+ 0FB4B51A16B62772003F696B /* DFGCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCommon.cpp; path = dfg/DFGCommon.cpp; sourceTree = "<group>"; };
+ 0FB4B51B16B62772003F696B /* DFGEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGEdge.cpp; path = dfg/DFGEdge.cpp; sourceTree = "<group>"; };
+ 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLongLivedState.cpp; path = dfg/DFGLongLivedState.cpp; sourceTree = "<group>"; };
+ 0FB4B51D16B62772003F696B /* DFGLongLivedState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLongLivedState.h; path = dfg/DFGLongLivedState.h; sourceTree = "<group>"; };
+ 0FB4B51E16B62772003F696B /* DFGNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNode.cpp; path = dfg/DFGNode.cpp; sourceTree = "<group>"; };
+ 0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeAllocator.h; path = dfg/DFGNodeAllocator.h; sourceTree = "<group>"; };
+ 0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionExecutableDump.cpp; sourceTree = "<group>"; };
+ 0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionExecutableDump.h; sourceTree = "<group>"; };
0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LazyOperandValueProfile.h; sourceTree = "<group>"; };
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>"; };
@@ -1023,6 +1170,12 @@
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>"; };
+ 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCPSRethreadingPhase.cpp; path = dfg/DFGCPSRethreadingPhase.cpp; sourceTree = "<group>"; };
+ 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCPSRethreadingPhase.h; path = dfg/DFGCPSRethreadingPhase.h; sourceTree = "<group>"; };
+ 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPredictionInjectionPhase.cpp; path = dfg/DFGPredictionInjectionPhase.cpp; sourceTree = "<group>"; };
+ 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPredictionInjectionPhase.h; path = dfg/DFGPredictionInjectionPhase.h; sourceTree = "<group>"; };
+ 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUnificationPhase.cpp; path = dfg/DFGUnificationPhase.cpp; sourceTree = "<group>"; };
+ 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = "<group>"; };
0FC097681468A6EF00CF2442 /* DFGOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExit.h; path = dfg/DFGOSRExit.h; sourceTree = "<group>"; };
0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAssemblyHelpers.cpp; path = dfg/DFGAssemblyHelpers.cpp; sourceTree = "<group>"; };
0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAssemblyHelpers.h; path = dfg/DFGAssemblyHelpers.h; sourceTree = "<group>"; };
@@ -1032,8 +1185,6 @@
0FC0977E1469EBC400CF2442 /* DFGCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCommon.h; path = dfg/DFGCommon.h; sourceTree = "<group>"; };
0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExit.cpp; path = dfg/DFGOSRExit.cpp; sourceTree = "<group>"; };
0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler.cpp; path = dfg/DFGOSRExitCompiler.cpp; sourceTree = "<group>"; };
- 0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCorrectableJumpPoint.h; path = dfg/DFGCorrectableJumpPoint.h; sourceTree = "<group>"; };
- 0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCorrectableJumpPoint.cpp; path = dfg/DFGCorrectableJumpPoint.cpp; sourceTree = "<group>"; };
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; };
0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; };
0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
@@ -1041,8 +1192,11 @@
0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; };
0FC815141405118D00CFA603 /* VTableSpectrum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTableSpectrum.h; sourceTree = "<group>"; };
0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotVisitorInlines.h; sourceTree = "<group>"; };
+ 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserError.h; sourceTree = "<group>"; };
+ 0FD2C92316D01EE900C7803F /* StructureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureInlines.h; sourceTree = "<group>"; };
0FD3C82014115CF800FD81CB /* DFGDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDriver.cpp; path = dfg/DFGDriver.cpp; sourceTree = "<group>"; };
0FD3C82214115D0E00FD81CB /* DFGDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDriver.h; path = dfg/DFGDriver.h; sourceTree = "<group>"; };
+ 0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlockInlines.h; path = dfg/DFGBasicBlockInlines.h; sourceTree = "<group>"; };
0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDominators.cpp; path = dfg/DFGDominators.cpp; sourceTree = "<group>"; };
0FD81AD0154FB4EB00983E72 /* DFGDominators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDominators.h; path = dfg/DFGDominators.h; sourceTree = "<group>"; };
0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCapabilities.cpp; path = dfg/DFGCapabilities.cpp; sourceTree = "<group>"; };
@@ -1058,6 +1212,8 @@
0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; };
0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayDescriptor.h; sourceTree = "<group>"; };
0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; };
+ 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitJumpPlaceholder.cpp; path = dfg/DFGOSRExitJumpPlaceholder.cpp; sourceTree = "<group>"; };
+ 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitJumpPlaceholder.h; path = dfg/DFGOSRExitJumpPlaceholder.h; sourceTree = "<group>"; };
0FF4272F158EBD44004CB9FF /* Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Disassembler.h; path = disassembler/Disassembler.h; sourceTree = "<group>"; };
0FF42730158EBD44004CB9FF /* UDis86Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UDis86Disassembler.cpp; path = disassembler/UDis86Disassembler.cpp; sourceTree = "<group>"; };
0FF42734158EBD94004CB9FF /* udis86_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udis86_decode.c; path = disassembler/udis86/udis86_decode.c; sourceTree = "<group>"; };
@@ -1078,7 +1234,26 @@
0FF427621591A1C9004CB9FF /* DFGDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDisassembler.h; path = dfg/DFGDisassembler.h; sourceTree = "<group>"; };
0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResolveGlobalStatus.cpp; sourceTree = "<group>"; };
0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolveGlobalStatus.h; sourceTree = "<group>"; };
+ 0FF60ABF16740F8100029779 /* ReduceWhitespace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReduceWhitespace.cpp; sourceTree = "<group>"; };
+ 0FF60AC016740F8100029779 /* ReduceWhitespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReduceWhitespace.h; sourceTree = "<group>"; };
0FF7168A15A3B231008F5DAA /* PropertyOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyOffset.h; sourceTree = "<group>"; };
+ 0FF72992166AD347000F5BA3 /* ProfilerBytecode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerBytecode.cpp; path = profiler/ProfilerBytecode.cpp; sourceTree = "<group>"; };
+ 0FF72993166AD347000F5BA3 /* ProfilerBytecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerBytecode.h; path = profiler/ProfilerBytecode.h; sourceTree = "<group>"; };
+ 0FF72994166AD347000F5BA3 /* ProfilerBytecodes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerBytecodes.cpp; path = profiler/ProfilerBytecodes.cpp; sourceTree = "<group>"; };
+ 0FF72995166AD347000F5BA3 /* ProfilerBytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerBytecodes.h; path = profiler/ProfilerBytecodes.h; sourceTree = "<group>"; };
+ 0FF72996166AD347000F5BA3 /* ProfilerCompilation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerCompilation.cpp; path = profiler/ProfilerCompilation.cpp; sourceTree = "<group>"; };
+ 0FF72997166AD347000F5BA3 /* ProfilerCompilation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerCompilation.h; path = profiler/ProfilerCompilation.h; sourceTree = "<group>"; };
+ 0FF72998166AD347000F5BA3 /* ProfilerCompilationKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerCompilationKind.cpp; path = profiler/ProfilerCompilationKind.cpp; sourceTree = "<group>"; };
+ 0FF72999166AD347000F5BA3 /* ProfilerCompilationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerCompilationKind.h; path = profiler/ProfilerCompilationKind.h; sourceTree = "<group>"; };
+ 0FF7299A166AD347000F5BA3 /* ProfilerCompiledBytecode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerCompiledBytecode.cpp; path = profiler/ProfilerCompiledBytecode.cpp; sourceTree = "<group>"; };
+ 0FF7299B166AD347000F5BA3 /* ProfilerCompiledBytecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerCompiledBytecode.h; path = profiler/ProfilerCompiledBytecode.h; sourceTree = "<group>"; };
+ 0FF7299C166AD347000F5BA3 /* ProfilerDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerDatabase.cpp; path = profiler/ProfilerDatabase.cpp; sourceTree = "<group>"; };
+ 0FF7299D166AD347000F5BA3 /* ProfilerDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerDatabase.h; path = profiler/ProfilerDatabase.h; sourceTree = "<group>"; };
+ 0FF7299E166AD347000F5BA3 /* ProfilerExecutionCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerExecutionCounter.h; path = profiler/ProfilerExecutionCounter.h; sourceTree = "<group>"; };
+ 0FF7299F166AD347000F5BA3 /* ProfilerOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOrigin.cpp; path = profiler/ProfilerOrigin.cpp; sourceTree = "<group>"; };
+ 0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOrigin.h; path = profiler/ProfilerOrigin.h; sourceTree = "<group>"; };
+ 0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOriginStack.cpp; path = profiler/ProfilerOriginStack.cpp; sourceTree = "<group>"; };
+ 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOriginStack.h; path = profiler/ProfilerOriginStack.h; sourceTree = "<group>"; };
0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFAPhase.cpp; path = dfg/DFGCFAPhase.cpp; sourceTree = "<group>"; };
0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFAPhase.h; path = dfg/DFGCFAPhase.h; sourceTree = "<group>"; };
@@ -1170,10 +1345,8 @@
14A1563010966365006FA260 /* DateInstanceCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateInstanceCache.h; sourceTree = "<group>"; };
14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubs.cpp; sourceTree = "<group>"; };
14A396A60CD2933100B5B4FF /* SymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = "<group>"; };
- 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeoutChecker.cpp; sourceTree = "<group>"; };
- 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeoutChecker.h; sourceTree = "<group>"; };
14A6581A0F4E36F4000150FD /* JITStubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubs.h; sourceTree = "<group>"; };
- 14ABB36E099C076400E2A24F /* JSValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSValue.h; sourceTree = "<group>"; };
+ 14ABB36E099C076400E2A24F /* JSCJSValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSCJSValue.h; sourceTree = "<group>"; };
14ABB454099C2A0F00E2A24F /* JSType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSType.h; sourceTree = "<group>"; };
14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObject.h; sourceTree = "<group>"; };
14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackObject.cpp; sourceTree = "<group>"; };
@@ -1187,14 +1360,20 @@
14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSContextRef.h; sourceTree = "<group>"; };
14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSValueRef.cpp; sourceTree = "<group>"; };
14BD5A2D0A3E91F600BAF59C /* testapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testapi.c; path = API/tests/testapi.c; sourceTree = "<group>"; };
+ 14BE7D3217135CF400D1807A /* WeakInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakInlines.h; sourceTree = "<group>"; };
14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMap.h; sourceTree = "<group>"; };
+ 14CA958A16AB50DE00938A06 /* StaticPropertyAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticPropertyAnalyzer.h; sourceTree = "<group>"; };
+ 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectAllocationProfile.h; sourceTree = "<group>"; };
14D2F3D8139F4BE200491031 /* MarkedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedSpace.cpp; sourceTree = "<group>"; };
14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; };
14D792640DAA03FB001A9F05 /* JSStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStack.h; sourceTree = "<group>"; };
+ 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrototypeMap.cpp; sourceTree = "<group>"; };
+ 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeMap.h; sourceTree = "<group>"; };
14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; };
14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; };
14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSActivation.cpp; sourceTree = "<group>"; };
14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObject.cpp; sourceTree = "<group>"; };
+ 14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticPropertyAnalysis.h; sourceTree = "<group>"; };
14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakBlock.cpp; sourceTree = "<group>"; };
14E84F9A14EE1ACC00D6D5D4 /* WeakBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakBlock.h; sourceTree = "<group>"; };
14E84F9B14EE1ACC00D6D5D4 /* WeakSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakSet.cpp; sourceTree = "<group>"; };
@@ -1204,6 +1383,8 @@
14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakHandleOwner.cpp; sourceTree = "<group>"; };
14F7256414EE265E00B1652B /* WeakHandleOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHandleOwner.h; sourceTree = "<group>"; };
14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
+ 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRefPrivate.h; sourceTree = "<group>"; };
+ 1ACF7376171CA6FB00C9BB1E /* Weak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Weak.cpp; sourceTree = "<group>"; };
1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = JavaScriptCore.xcconfig; sourceTree = "<group>"; };
1C9051440BA9E8A70081E9D0 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
@@ -1234,6 +1415,11 @@
6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
65621E6B089E859700760F35 /* PropertySlot.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertySlot.cpp; sourceTree = "<group>"; tabWidth = 8; };
65621E6C089E859700760F35 /* PropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = PropertySlot.h; sourceTree = "<group>"; tabWidth = 8; };
+ 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilationInfo.h; path = dfg/DFGOSRExitCompilationInfo.h; sourceTree = "<group>"; };
+ 65987F2F16828A7E003C2F8D /* UnusedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedPointer.h; sourceTree = "<group>"; };
+ 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ARMv7Disassembler.cpp; path = disassembler/ARMv7Disassembler.cpp; sourceTree = "<group>"; };
+ 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMv7DOpcode.cpp; sourceTree = "<group>"; };
+ 65C0285B1717966800351E35 /* ARMv7DOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7DOpcode.h; sourceTree = "<group>"; };
65C02FBB0637462A003E7EE6 /* Protect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Protect.h; sourceTree = "<group>"; tabWidth = 8; };
65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; };
65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; };
@@ -1262,7 +1448,7 @@
863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrCanonicalizeUCS2.cpp; path = yarr/YarrCanonicalizeUCS2.cpp; sourceTree = "<group>"; };
863C6D991521111200585E4E /* YarrCanonicalizeUCS2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrCanonicalizeUCS2.h; path = yarr/YarrCanonicalizeUCS2.h; sourceTree = "<group>"; };
863C6D9A1521111200585E4E /* YarrCanonicalizeUCS2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = YarrCanonicalizeUCS2.js; path = yarr/YarrCanonicalizeUCS2.js; sourceTree = "<group>"; };
- 865A30F0135007E100CDB49E /* JSValueInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueInlines.h; sourceTree = "<group>"; };
+ 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCJSValueInlines.h; sourceTree = "<group>"; };
865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; };
866739D013BFDE710023D87C /* BigInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BigInteger.h; sourceTree = "<group>"; };
866739D113BFDE710023D87C /* Uint16WithFraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uint16WithFraction.h; sourceTree = "<group>"; };
@@ -1286,7 +1472,6 @@
86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; };
- 86AE64A5135E5E1C00963012 /* MacroAssemblerSH4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerSH4.cpp; sourceTree = "<group>"; };
86AE64A6135E5E1C00963012 /* MacroAssemblerSH4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerSH4.h; sourceTree = "<group>"; };
86AE64A7135E5E1C00963012 /* SH4Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SH4Assembler.h; sourceTree = "<group>"; };
86AE6C4B136A11E400963012 /* DFGFPRInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFPRInfo.h; path = dfg/DFGFPRInfo.h; sourceTree = "<group>"; };
@@ -1308,6 +1493,7 @@
86CC85A20EE79B7400288682 /* JITCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCall.cpp; sourceTree = "<group>"; };
86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess.cpp; sourceTree = "<group>"; };
86CCEFDD0F413F8900FD7F9E /* JITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCode.h; sourceTree = "<group>"; };
+ 86D22219167EF9440024C804 /* testapi.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = testapi.mm; path = API/tests/testapi.mm; sourceTree = "<group>"; };
86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMAssembler.cpp; sourceTree = "<group>"; };
86D3B2C010156BDE002865E7 /* ARMAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMAssembler.h; sourceTree = "<group>"; };
86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBufferWithConstantPool.h; sourceTree = "<group>"; };
@@ -1316,6 +1502,18 @@
86D3B3C210159D7F002865E7 /* RepatchBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RepatchBuffer.h; sourceTree = "<group>"; };
86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; };
86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; };
+ 86E3C606167BAB87006D760A /* JSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValue.h; sourceTree = "<group>"; };
+ 86E3C607167BAB87006D760A /* JSContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSContext.h; sourceTree = "<group>"; };
+ 86E3C608167BAB87006D760A /* JSContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSContext.mm; sourceTree = "<group>"; };
+ 86E3C609167BAB87006D760A /* JSContextInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSContextInternal.h; sourceTree = "<group>"; };
+ 86E3C60A167BAB87006D760A /* JSExport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExport.h; sourceTree = "<group>"; };
+ 86E3C60B167BAB87006D760A /* JSWrapperMap.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSWrapperMap.mm; sourceTree = "<group>"; };
+ 86E3C60C167BAB87006D760A /* JSWrapperMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWrapperMap.h; sourceTree = "<group>"; };
+ 86E3C60D167BAB87006D760A /* JSValue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSValue.mm; sourceTree = "<group>"; };
+ 86E3C60E167BAB87006D760A /* JSValueInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueInternal.h; sourceTree = "<group>"; };
+ 86E3C60F167BAB87006D760A /* JSVirtualMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVirtualMachine.h; sourceTree = "<group>"; };
+ 86E3C610167BAB87006D760A /* JSVirtualMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSVirtualMachine.mm; sourceTree = "<group>"; };
+ 86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVirtualMachineInternal.h; sourceTree = "<group>"; };
86E85538111B9968001AF51E /* JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringBuilder.h; sourceTree = "<group>"; };
86EBF2F91560F036008E9222 /* NameConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameConstructor.cpp; sourceTree = "<group>"; };
86EBF2FA1560F036008E9222 /* NameConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameConstructor.h; sourceTree = "<group>"; };
@@ -1337,6 +1535,9 @@
86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSpeculativeJIT.h; path = dfg/DFGSpeculativeJIT.h; sourceTree = "<group>"; };
86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNode.h; path = dfg/DFGNode.h; sourceTree = "<group>"; };
86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGScoreBoard.h; path = dfg/DFGScoreBoard.h; sourceTree = "<group>"; };
+ 86F3EEB616855A5B0077B92A /* ObjcRuntimeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjcRuntimeExtras.h; sourceTree = "<group>"; };
+ 86F3EEB9168CCF750077B92A /* ObjCCallbackFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjCCallbackFunction.h; sourceTree = "<group>"; };
+ 86F3EEBA168CCF750077B92A /* ObjCCallbackFunction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ObjCCallbackFunction.mm; sourceTree = "<group>"; };
86F75EFB151C062F007C9BA3 /* RegExpCachedResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCachedResult.cpp; sourceTree = "<group>"; };
86F75EFC151C062F007C9BA3 /* RegExpCachedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCachedResult.h; sourceTree = "<group>"; };
86F75EFD151C062F007C9BA3 /* RegExpMatchesArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpMatchesArray.cpp; sourceTree = "<group>"; };
@@ -1368,8 +1569,8 @@
95742F630DD11F5A000917FB /* Profile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profile.cpp; path = profiler/Profile.cpp; sourceTree = "<group>"; };
95742F640DD11F5A000917FB /* Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profile.h; path = profiler/Profile.h; sourceTree = "<group>"; };
95988BA90E477BEC00D28D4D /* JSProfilerPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSProfilerPrivate.cpp; sourceTree = "<group>"; };
- 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profiler.cpp; path = profiler/Profiler.cpp; sourceTree = "<group>"; };
- 95AB832F0DA42CAD00BC83F3 /* Profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profiler.h; path = profiler/Profiler.h; sourceTree = "<group>"; };
+ 95AB832E0DA42CAD00BC83F3 /* LegacyProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LegacyProfiler.cpp; path = profiler/LegacyProfiler.cpp; sourceTree = "<group>"; };
+ 95AB832F0DA42CAD00BC83F3 /* LegacyProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LegacyProfiler.h; path = profiler/LegacyProfiler.h; sourceTree = "<group>"; };
95AB83540DA43B4400BC83F3 /* ProfileNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfileNode.cpp; path = profiler/ProfileNode.cpp; sourceTree = "<group>"; };
95AB83550DA43B4400BC83F3 /* ProfileNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfileNode.h; path = profiler/ProfileNode.h; sourceTree = "<group>"; };
95C18D3E0C90E7EF00E72F73 /* JSRetainPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRetainPtr.h; sourceTree = "<group>"; };
@@ -1393,13 +1594,15 @@
969A09220ED1E09C00F1F681 /* Completion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Completion.cpp; sourceTree = "<group>"; };
9788FC221471AD0C0068CE2D /* JSDateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDateMath.cpp; sourceTree = "<group>"; };
9788FC231471AD0C0068CE2D /* JSDateMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDateMath.h; sourceTree = "<group>"; };
- 97F6903A1169DF7F00A6BB46 /* Terminator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminator.h; sourceTree = "<group>"; };
A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
A1712B4011C7B235007A5315 /* RegExpKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpKey.h; sourceTree = "<group>"; };
A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITOpcodes32_64.cpp; sourceTree = "<group>"; };
A718F61A11754A21002465A7 /* RegExpJitTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpJitTables.h; sourceTree = "<group>"; };
A718F8211178EB4B002465A7 /* create_regex_tables */ = {isa = PBXFileReference; explicitFileType = text.script.python; fileEncoding = 4; path = create_regex_tables; sourceTree = "<group>"; };
+ A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCTestRunnerUtils.cpp; sourceTree = "<group>"; };
+ A72028B51797601E0098028C /* JSCTestRunnerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCTestRunnerUtils.h; sourceTree = "<group>"; };
+ A72028B91797603D0098028C /* JSFunctionInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFunctionInlines.h; sourceTree = "<group>"; };
A72700770DAC605600E548D7 /* JSNotAnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNotAnObject.h; sourceTree = "<group>"; };
A72700780DAC605600E548D7 /* JSNotAnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNotAnObject.cpp; sourceTree = "<group>"; };
A72701B30DADE94900E548D7 /* ExceptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHelpers.h; sourceTree = "<group>"; };
@@ -1414,7 +1617,6 @@
A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectMapRefPrivate.cpp; sourceTree = "<group>"; };
A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefInternal.h; sourceTree = "<group>"; };
A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMv7Assembler.cpp; sourceTree = "<group>"; };
- A7521E121429169A003C8D0C /* CardSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CardSet.h; sourceTree = "<group>"; };
A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic32_64.cpp; sourceTree = "<group>"; };
A767FF9F14F4502900789059 /* JSCTypedArrayStubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCTypedArrayStubs.h; sourceTree = "<group>"; };
A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; };
@@ -1431,6 +1633,8 @@
A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExportMacros.h; sourceTree = "<group>"; };
+ A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSScriptRef.cpp; sourceTree = "<group>"; };
+ A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSScriptRefPrivate.h; sourceTree = "<group>"; };
A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; };
A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; };
A7C225CD1399849C00FF1662 /* KeywordLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeywordLookup.h; sourceTree = "<group>"; };
@@ -1446,6 +1650,7 @@
A8A4748D151A8306004123FF /* libWTF.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWTF.a; sourceTree = BUILT_PRODUCTS_DIR; };
A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
+ AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
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>"; };
@@ -1535,6 +1740,8 @@
BCF605120E203EF800B9A64D /* ArgList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgList.h; sourceTree = "<group>"; };
BCFD8C900EEB2EE700283848 /* JumpTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JumpTable.cpp; sourceTree = "<group>"; };
BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
+ C20B25981706536200C21F4E /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Region.h; sourceTree = "<group>"; };
+ C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareDataInlines.h; sourceTree = "<group>"; };
C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; };
C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; };
C21122E015DD9AB300790E3A /* MarkStackInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStackInlines.h; sourceTree = "<group>"; };
@@ -1548,20 +1755,30 @@
C240305314B404C90079EB64 /* CopiedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopiedSpace.cpp; sourceTree = "<group>"; };
C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapStatistics.cpp; sourceTree = "<group>"; };
C24D31E1161CD695002AA4DB /* HeapStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapStatistics.h; sourceTree = "<group>"; };
+ C25D709916DE99F400FCA6BC /* JSManagedValue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSManagedValue.mm; sourceTree = "<group>"; };
+ C25D709A16DE99F400FCA6BC /* JSManagedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSManagedValue.h; sourceTree = "<group>"; };
C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = "<group>"; };
C25F8BCC157544A900245B71 /* IncrementalSweeper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncrementalSweeper.h; sourceTree = "<group>"; };
+ C28318FF16FE4B7D00157BFD /* HandleBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandleBlock.h; sourceTree = "<group>"; };
+ C283190116FE533E00157BFD /* HandleBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HandleBlockInlines.h; sourceTree = "<group>"; };
C2A7F687160432D400F76B98 /* JSDestructibleObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObject.h; sourceTree = "<group>"; };
C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocator.h; sourceTree = "<group>"; };
C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedAllocator.cpp; sourceTree = "<group>"; };
C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpaceInlines.h; sourceTree = "<group>"; };
C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedBlock.h; sourceTree = "<group>"; };
C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapBlock.h; sourceTree = "<group>"; };
+ C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSAPIWrapperObject.mm; sourceTree = "<group>"; };
+ C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAPIWrapperObject.h; sourceTree = "<group>"; };
C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCActivityCallback.cpp; sourceTree = "<group>"; };
+ C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuperRegion.cpp; sourceTree = "<group>"; };
+ C2DF442E1707AC0100A5CA96 /* SuperRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuperRegion.h; sourceTree = "<group>"; };
C2E526BB1590EF000054E48D /* HeapTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapTimer.cpp; sourceTree = "<group>"; };
C2E526BC1590EF000054E48D /* HeapTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapTimer.h; sourceTree = "<group>"; };
C2EAA3F8149A830800FCE112 /* CopiedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpace.h; sourceTree = "<group>"; };
C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedAllocator.h; sourceTree = "<group>"; };
+ C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureRareData.cpp; sourceTree = "<group>"; };
C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedBlockInlines.h; sourceTree = "<group>"; };
+ C2FE18A316BAEC4000AF3061 /* StructureRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareData.h; sourceTree = "<group>"; };
D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; };
DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCActivityCallback.h; sourceTree = "<group>"; };
@@ -1569,8 +1786,8 @@
E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; };
E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
- E18E3A560DF9278C00D90B34 /* JSGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalData.h; sourceTree = "<group>"; };
- E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalData.cpp; sourceTree = "<group>"; };
+ E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VM.h; sourceTree = "<group>"; };
+ E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VM.cpp; sourceTree = "<group>"; };
E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCacheItem.h; sourceTree = "<group>"; };
E49DC15112EF272200184A1F /* SourceProviderCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCache.h; sourceTree = "<group>"; };
E49DC15512EF277200184A1F /* SourceProviderCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProviderCache.cpp; sourceTree = "<group>"; };
@@ -1604,13 +1821,16 @@
F692A87C0255597D01FF60F7 /* RegExpObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObject.h; sourceTree = "<group>"; tabWidth = 8; };
F692A87D0255597D01FF60F7 /* RegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExp.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A87E0255597D01FF60F7 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A8870255597D01FF60F7 /* JSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8870255597D01FF60F7 /* JSCJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCJSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; };
FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
- FEB63AA2159B9DA3008932A6 /* Comment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Comment.h; sourceTree = "<group>"; };
+ FE6617271774E03500495B00 /* VMStackBounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMStackBounds.h; sourceTree = "<group>"; };
FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; };
+ FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Watchdog.cpp; sourceTree = "<group>"; };
+ FED94F2C171E3E2300BE77A4 /* Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchdog.h; sourceTree = "<group>"; };
+ FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WatchdogMac.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1634,7 +1854,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 143A97E60A4A06E200456B66 /* CoreFoundation.framework in Frameworks */,
+ 4443AE3316E188D90076F110 /* Foundation.framework in Frameworks */,
14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1675,12 +1895,12 @@
034768DFFF38A50411DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
- 932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
932F5BE10822A1C700736975 /* jsc */,
+ 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
+ 932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
141211200A48793C00480255 /* minidom */,
14BD59BF0A3E8F9000BAF59C /* testapi */,
6511230514046A4C002B101D /* testRegExp */,
- 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
);
name = Products;
sourceTree = "<group>";
@@ -1728,12 +1948,12 @@
0867D69AFE84028FC02AAC07 /* Frameworks */ = {
isa = PBXGroup;
children = (
- A8A4748D151A8306004123FF /* libWTF.a */,
6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */,
51F0EB6105C86C6B00E6DF1B /* Foundation.framework */,
5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */,
9322A00306C341D3009067BB /* libicucore.dylib */,
51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */,
+ A8A4748D151A8306004123FF /* libWTF.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -1743,26 +1963,26 @@
0F46809C14BA7F4D00BFE272 /* llint */ = {
isa = PBXGroup;
children = (
- FED287B115EC9A5700DA8161 /* LLIntOpcode.h */,
FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */,
FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */,
+ 0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
+ 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
+ 0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
5DDDF44614FEE72200B4FB4D /* LLIntDesiredOffsets.h */,
0F0B839514BCF45A00885B4F /* LLIntEntrypoints.cpp */,
0F0B839614BCF45A00885B4F /* LLIntEntrypoints.h */,
- 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
- 0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
- 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */,
- 0F4680CF14BBB3D100BFE272 /* LLIntData.h */,
- 0F4680C514BBB16900BFE272 /* LLIntCommon.h */,
- 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
- 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
- 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
0F46809D14BA7F8200BFE272 /* LLIntExceptions.cpp */,
0F46809E14BA7F8200BFE272 /* LLIntExceptions.h */,
+ 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */,
+ 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
+ FED287B115EC9A5700DA8161 /* LLIntOpcode.h */,
0F46809F14BA7F8200BFE272 /* LLIntSlowPaths.cpp */,
0F4680A014BA7F8200BFE272 /* LLIntSlowPaths.h */,
- 0F4680A114BA7F8200BFE272 /* LLIntOffsetsExtractor.cpp */,
+ 0F0B839714BCF45A00885B4F /* LLIntThunks.cpp */,
+ 0F0B839814BCF45A00885B4F /* LLIntThunks.h */,
86A054461556451B00445157 /* LowLevelInterpreter.asm */,
+ 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */,
+ 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */,
86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */,
86A054481556451B00445157 /* LowLevelInterpreter64.asm */,
);
@@ -1772,7 +1992,9 @@
0FF4272E158EBCCE004CB9FF /* disassembler */ = {
isa = PBXGroup;
children = (
+ 65C028591717966800351E35 /* ARMv7 */,
0FF42733158EBD64004CB9FF /* udis86 */,
+ 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */,
0F9D336E165DBB8D005AD387 /* Disassembler.cpp */,
0FF4272F158EBD44004CB9FF /* Disassembler.h */,
0FF42730158EBD44004CB9FF /* UDis86Disassembler.cpp */,
@@ -1783,6 +2005,8 @@
0FF42733158EBD64004CB9FF /* udis86 */ = {
isa = PBXGroup;
children = (
+ 0FF4273E158EBD94004CB9FF /* udis86.c */,
+ 0FF4273F158EBD94004CB9FF /* udis86.h */,
0FF42734158EBD94004CB9FF /* udis86_decode.c */,
0FF42735158EBD94004CB9FF /* udis86_decode.h */,
0FF42736158EBD94004CB9FF /* udis86_extern.h */,
@@ -1794,8 +2018,6 @@
0FF4273B158EBD94004CB9FF /* udis86_syn.c */,
0FF4273C158EBD94004CB9FF /* udis86_syn.h */,
0FF4273D158EBD94004CB9FF /* udis86_types.h */,
- 0FF4273E158EBD94004CB9FF /* udis86.c */,
- 0FF4273F158EBD94004CB9FF /* udis86.h */,
);
name = udis86;
sourceTree = "<group>";
@@ -1806,6 +2028,7 @@
144005170A531CB50005F061 /* minidom */,
14BD5A2D0A3E91F600BAF59C /* testapi.c */,
14D857740A4696C80032146C /* testapi.js */,
+ 86D22219167EF9440024C804 /* testapi.mm */,
651122E5140469BA002B101D /* testRegExp.cpp */,
);
name = tests;
@@ -1816,8 +2039,6 @@
1429D77A0ED20D7300B89619 /* interpreter */ = {
isa = PBXGroup;
children = (
- FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */,
- FE4A331E15BD2E07006F54F3 /* VMInspector.h */,
0F55F0F114D1063600AC7649 /* AbstractPC.cpp */,
0F55F0F214D1063600AC7649 /* AbstractPC.h */,
A7F8690E0F9584A100558697 /* CachedCall.h */,
@@ -1826,9 +2047,11 @@
A7F869EC0F95C2EC00558697 /* CallFrameClosure.h */,
1429D7D30ED2128200B89619 /* Interpreter.cpp */,
1429D77B0ED20D7300B89619 /* Interpreter.h */,
- 149B24FF0D8AF6D1009CB8C7 /* Register.h */,
1429D85B0ED218E900B89619 /* JSStack.cpp */,
14D792640DAA03FB001A9F05 /* JSStack.h */,
+ 149B24FF0D8AF6D1009CB8C7 /* Register.h */,
+ FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */,
+ FE4A331E15BD2E07006F54F3 /* VMInspector.h */,
);
path = interpreter;
sourceTree = "<group>";
@@ -1870,13 +2093,17 @@
0F766D1C15A5028D008F363E /* JITStubRoutine.h */,
14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */,
14A6581A0F4E36F4000150FD /* JITStubs.h */,
+ 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
+ 0F5EF91C16878F78003E5C25 /* JITThunks.h */,
A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */,
0F766D3315AE2535008F363E /* JumpReplacementWatchpoint.h */,
A7386551118697B400540279 /* SpecializedThunkJIT.h */,
+ 0F572D4D16879FDB00E57FBD /* ThunkGenerator.h */,
A7386552118697B400540279 /* ThunkGenerators.cpp */,
A7386553118697B400540279 /* ThunkGenerators.h */,
+ 65987F2F16828A7E003C2F8D /* UnusedPointer.h */,
);
path = jit;
sourceTree = "<group>";
@@ -1884,35 +2111,30 @@
142E312A134FF0A600AFADB5 /* heap */ = {
isa = PBXGroup;
children = (
- C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */,
- C2239D1316262BDD005AC5FD /* CopyVisitor.h */,
- C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */,
- C2239D1516262BDD005AC5FD /* GCThread.cpp */,
- C2239D1616262BDD005AC5FD /* GCThread.h */,
- C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */,
- C24D31E1161CD695002AA4DB /* HeapStatistics.h */,
- C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
- C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */,
- C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */,
- C21122E015DD9AB300790E3A /* MarkStackInlines.h */,
- C2E526BB1590EF000054E48D /* HeapTimer.cpp */,
- C2E526BC1590EF000054E48D /* HeapTimer.h */,
- C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */,
- C25F8BCC157544A900245B71 /* IncrementalSweeper.h */,
14816E19154CC56C00B8054C /* BlockAllocator.cpp */,
14816E1A154CC56C00B8054C /* BlockAllocator.h */,
- A7521E121429169A003C8D0C /* CardSet.h */,
146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
149DAAF212EB559D0083B12B /* ConservativeRoots.h */,
C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */,
C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */,
+ C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */,
C240305314B404C90079EB64 /* CopiedSpace.cpp */,
C2EAA3F8149A830800FCE112 /* CopiedSpace.h */,
C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlines.h */,
+ C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */,
+ C2239D1316262BDD005AC5FD /* CopyVisitor.h */,
+ C2239D1416262BDD005AC5FD /* CopyVisitorInlines.h */,
+ C218D13F1655CFD50062BB81 /* CopyWorkList.h */,
0F2C556D14738F2E00121E4F /* DFGCodeBlocks.cpp */,
0F2C556E14738F2E00121E4F /* DFGCodeBlocks.h */,
BCBE2CAD14E985AA000593AD /* GCAssertions.h */,
+ C2239D1516262BDD005AC5FD /* GCThread.cpp */,
+ C2239D1616262BDD005AC5FD /* GCThread.h */,
+ C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */,
+ C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */,
142E312B134FF0A600AFADB5 /* Handle.h */,
+ C28318FF16FE4B7D00157BFD /* HandleBlock.h */,
+ C283190116FE533E00157BFD /* HandleBlockInlines.h */,
142E312C134FF0A600AFADB5 /* HandleSet.cpp */,
142E312D134FF0A600AFADB5 /* HandleSet.h */,
142E312E134FF0A600AFADB5 /* HandleStack.cpp */,
@@ -1922,6 +2144,12 @@
14BA7A9613AADFF8005B7C2C /* Heap.h */,
C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */,
14F97446138C853E00DA1C67 /* HeapRootVisitor.h */,
+ C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */,
+ C24D31E1161CD695002AA4DB /* HeapStatistics.h */,
+ C2E526BB1590EF000054E48D /* HeapTimer.cpp */,
+ C2E526BC1590EF000054E48D /* HeapTimer.h */,
+ C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */,
+ C25F8BCC157544A900245B71 /* IncrementalSweeper.h */,
0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */,
0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */,
0F431736146BAC65007E3890 /* ListableHandler.h */,
@@ -1938,29 +2166,34 @@
14D2F3D9139F4BE200491031 /* MarkedSpace.h */,
142D6F0E13539A4100B02E86 /* MarkStack.cpp */,
142D6F0F13539A4100B02E86 /* MarkStack.h */,
+ C21122E015DD9AB300790E3A /* MarkStackInlines.h */,
1497209014EB831500FEB1B7 /* PassWeak.h */,
+ C20B25981706536200C21F4E /* Region.h */,
+ C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */,
142E3132134FF0A600AFADB5 /* Strong.h */,
145722851437E140005FDE26 /* StrongInlines.h */,
+ C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */,
+ C2DF442E1707AC0100A5CA96 /* SuperRegion.h */,
141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */,
0FC815121405118600CFA603 /* VTableSpectrum.cpp */,
0FC815141405118D00CFA603 /* VTableSpectrum.h */,
+ 1ACF7376171CA6FB00C9BB1E /* Weak.cpp */,
142E3133134FF0A600AFADB5 /* Weak.h */,
14E84F9914EE1ACC00D6D5D4 /* WeakBlock.cpp */,
14E84F9A14EE1ACC00D6D5D4 /* WeakBlock.h */,
14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */,
14F7256414EE265E00B1652B /* WeakHandleOwner.h */,
14E84F9D14EE1ACC00D6D5D4 /* WeakImpl.h */,
+ 14BE7D3217135CF400D1807A /* WeakInlines.h */,
0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */,
14E84F9B14EE1ACC00D6D5D4 /* WeakSet.cpp */,
14E84F9C14EE1ACC00D6D5D4 /* WeakSet.h */,
14150132154BB13F005D8C98 /* WeakSetInlines.h */,
0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */,
0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */,
- C218D13F1655CFD50062BB81 /* CopyWorkList.h */,
- C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */,
);
path = heap;
sourceTree = "<group>";
@@ -1968,12 +2201,16 @@
1432EBD70A34CAD400717B9F /* API */ = {
isa = PBXGroup;
children = (
+ A72028B41797601E0098028C /* JSCTestRunnerUtils.cpp */,
+ A72028B51797601E0098028C /* JSCTestRunnerUtils.h */,
1482B78A0A4305AB00517CFC /* APICast.h */,
865F408710E7D56300947361 /* APIShims.h */,
1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */,
1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */,
BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */,
BC0894D60FAFBA2D00001865 /* JSAPIValueWrapper.h */,
+ C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */,
+ C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */,
1421359A0A677F4F00A8195E /* JSBase.cpp */,
142711380A460BBB0080EEEA /* JSBase.h */,
140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */,
@@ -1986,27 +2223,47 @@
A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */,
1440FCE20A51E46B0005F061 /* JSClassRef.cpp */,
1440FCE10A51E46B0005F061 /* JSClassRef.h */,
+ 86E3C607167BAB87006D760A /* JSContext.h */,
+ 86E3C608167BAB87006D760A /* JSContext.mm */,
+ 86E3C609167BAB87006D760A /* JSContextInternal.h */,
14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */,
14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */,
148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */,
+ 86E3C60A167BAB87006D760A /* JSExport.h */,
+ C25D709A16DE99F400FCA6BC /* JSManagedValue.h */,
+ C25D709916DE99F400FCA6BC /* JSManagedValue.mm */,
1482B7E20A43076000517CFC /* JSObjectRef.cpp */,
1482B7E10A43076000517CFC /* JSObjectRef.h */,
A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */,
95988BA90E477BEC00D28D4D /* JSProfilerPrivate.cpp */,
952C63AC0E4777D600C13936 /* JSProfilerPrivate.h */,
95C18D3E0C90E7EF00E72F73 /* JSRetainPtr.h */,
+ A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */,
+ A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */,
1482B74C0A43032800517CFC /* JSStringRef.cpp */,
1482B74B0A43032800517CFC /* JSStringRef.h */,
146AAB370B66A94400E55F16 /* JSStringRefCF.cpp */,
146AAB2A0B66A84900E55F16 /* JSStringRefCF.h */,
+ 86E3C606167BAB87006D760A /* JSValue.h */,
+ 86E3C60D167BAB87006D760A /* JSValue.mm */,
+ 86E3C60E167BAB87006D760A /* JSValueInternal.h */,
14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */,
1482B6EA0A4300B300517CFC /* JSValueRef.h */,
+ 86E3C60F167BAB87006D760A /* JSVirtualMachine.h */,
+ 86E3C610167BAB87006D760A /* JSVirtualMachine.mm */,
+ 86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */,
A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */,
A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */,
A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */,
+ 86E3C60C167BAB87006D760A /* JSWrapperMap.h */,
+ 86E3C60B167BAB87006D760A /* JSWrapperMap.mm */,
+ 86F3EEB9168CCF750077B92A /* ObjCCallbackFunction.h */,
+ 86F3EEBA168CCF750077B92A /* ObjCCallbackFunction.mm */,
+ 86F3EEB616855A5B0077B92A /* ObjcRuntimeExtras.h */,
E124A8F60E555775003091F1 /* OpaqueJSString.cpp */,
E124A8F50E555775003091F1 /* OpaqueJSString.h */,
5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */,
+ 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */,
);
path = API;
sourceTree = "<group>";
@@ -2050,8 +2307,8 @@
1C9051450BA9E8A70081E9D0 /* Base.xcconfig */,
1C9051440BA9E8A70081E9D0 /* DebugRelease.xcconfig */,
449097EE0F8F81B50076A327 /* FeatureDefines.xcconfig */,
- 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */,
1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */,
+ 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */,
BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */,
1C9051420BA9E8A70081E9D0 /* Version.xcconfig */,
);
@@ -2083,6 +2340,16 @@
tabWidth = 4;
usesTabs = 0;
};
+ 65C028591717966800351E35 /* ARMv7 */ = {
+ isa = PBXGroup;
+ children = (
+ 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */,
+ 65C0285B1717966800351E35 /* ARMv7DOpcode.h */,
+ );
+ name = ARMv7;
+ path = disassembler/ARMv7;
+ sourceTree = "<group>";
+ };
7E39D81D0EC38EFA003AF11A /* bytecompiler */ = {
isa = PBXGroup;
children = (
@@ -2092,6 +2359,8 @@
960097A50EBABB58007A7297 /* LabelScope.h */,
655EB29A10CE2581001A990E /* NodesCodegen.cpp */,
969A07280ED1CE6900F1F681 /* RegisterID.h */,
+ 14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */,
+ 14CA958A16AB50DE00938A06 /* StaticPropertyAnalyzer.h */,
);
path = bytecompiler;
sourceTree = "<group>";
@@ -2111,15 +2380,17 @@
93F0B3AA09BB4DC00068FCE3 /* Parser.h */,
93052C320FB792190048FDC3 /* ParserArena.cpp */,
93052C330FB792190048FDC3 /* ParserArena.h */,
+ 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */,
+ A77F18241641925400640A47 /* ParserModes.h */,
65303D631447B9E100D3F904 /* ParserTokens.h */,
869EBCB60E8C6D4A008722CC /* ResultType.h */,
65E866EE0DD59AFA00A2B2A1 /* SourceCode.h */,
+ 0F493AF816D0CAD10084508B /* SourceProvider.cpp */,
65E866ED0DD59AFA00A2B2A1 /* SourceProvider.h */,
E49DC15512EF277200184A1F /* SourceProviderCache.cpp */,
E49DC15112EF272200184A1F /* SourceProviderCache.h */,
E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */,
A7A7EE7711B98B8D0065A14F /* SyntaxChecker.h */,
- A77F18241641925400640A47 /* ParserModes.h */,
);
path = parser;
sourceTree = "<group>";
@@ -2127,6 +2398,7 @@
7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
isa = PBXGroup;
children = (
+ A72028B91797603D0098028C /* JSFunctionInlines.h */,
BCF605110E203EF800B9A64D /* ArgList.cpp */,
BCF605120E203EF800B9A64D /* ArgList.h */,
BC257DE50E1F51C50016B6C9 /* Arguments.cpp */,
@@ -2151,6 +2423,8 @@
BCA62DFE0E2826230004F30D /* CallData.cpp */,
145C507F0D9DF63B0088F6B9 /* CallData.h */,
BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
+ A77F181F164088B200640A47 /* CodeCache.cpp */,
+ A77F1820164088B200640A47 /* CodeCache.h */,
0F8F943A1667631100D61971 /* CodeSpecializationKind.cpp */,
0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */,
65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */,
@@ -2184,6 +2458,8 @@
0F21C27A14BE727300ADC64B /* ExecutionHarness.h */,
BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */,
BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
+ 0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */,
+ 0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */,
F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
@@ -2209,14 +2485,16 @@
86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */,
BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
BC1167D80E19BCC9008066DD /* JSCell.h */,
+ 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */,
+ F692A8870255597D01FF60F7 /* JSCJSValue.cpp */,
+ 14ABB36E099C076400E2A24F /* JSCJSValue.h */,
+ 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
9788FC221471AD0C0068CE2D /* JSDateMath.cpp */,
9788FC231471AD0C0068CE2D /* JSDateMath.h */,
C2A7F687160432D400F76B98 /* JSDestructibleObject.h */,
A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */,
F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
F692A85F0255597D01FF60F7 /* JSFunction.h */,
- E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */,
- E18E3A560DF9278C00D90B34 /* JSGlobalData.h */,
14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */,
A8E894330CD0603F00367179 /* JSGlobalObject.h */,
BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
@@ -2248,9 +2526,6 @@
0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */,
14ABB454099C2A0F00E2A24F /* JSType.h */,
6507D2970E871E4A00D7D896 /* JSTypeInfo.h */,
- F692A8870255597D01FF60F7 /* JSValue.cpp */,
- 14ABB36E099C076400E2A24F /* JSValue.h */,
- 865A30F0135007E100CDB49E /* JSValueInlines.h */,
BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */,
14F252560D08DD8D004ECFFF /* JSVariableObject.h */,
1442565F15EDE98D0066A49B /* JSWithScope.cpp */,
@@ -2302,7 +2577,10 @@
65621E6B089E859700760F35 /* PropertySlot.cpp */,
65621E6C089E859700760F35 /* PropertySlot.h */,
0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */,
+ AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */,
65C02FBB0637462A003E7EE6 /* Protect.h */,
+ 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */,
+ 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */,
0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */,
147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
F692A87D0255597D01FF60F7 /* RegExp.cpp */,
@@ -2341,22 +2619,26 @@
BCDE3AB10E6C82CF001453A7 /* Structure.h */,
7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
7E4EE7080EBB7963005934AA /* StructureChain.h */,
+ 0FD2C92316D01EE900C7803F /* StructureInlines.h */,
+ C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */,
+ C2FE18A316BAEC4000AF3061 /* StructureRareData.h */,
+ C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */,
BC9041470EB9250900FE26FA /* StructureTransitionTable.h */,
0F919D2715856770004A4E7D /* SymbolTable.cpp */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
- 97F6903A1169DF7F00A6BB46 /* Terminator.h */,
- 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */,
- 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */,
5D53726D0E1C546B0021E549 /* Tracing.d */,
5D53726E0E1C54880021E549 /* Tracing.h */,
0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */,
866739D113BFDE710023D87C /* Uint16WithFraction.h */,
+ E18E3A570DF9278C00D90B34 /* VM.cpp */,
+ E18E3A560DF9278C00D90B34 /* VM.h */,
+ FE6617271774E03500495B00 /* VMStackBounds.h */,
+ FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */,
+ FED94F2C171E3E2300BE77A4 /* Watchdog.h */,
+ FED94F2D171E3E2300BE77A4 /* WatchdogMac.cpp */,
14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
A7DCB77912E3D90500911940 /* WriteBarrier.h */,
- C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
- A77F181F164088B200640A47 /* CodeCache.cpp */,
- A77F1820164088B200640A47 /* CodeCache.h */,
);
path = runtime;
sourceTree = "<group>";
@@ -2401,16 +2683,20 @@
0F62016E143FCD2F0068B77C /* DFGAbstractState.h */,
0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */,
0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */,
+ 0FB4B51916B62772003F696B /* DFGAllocator.h */,
0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
+ 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */,
0F63948115E48114006A597C /* DFGArrayMode.cpp */,
0F63948215E48114006A597C /* DFGArrayMode.h */,
0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */,
0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */,
+ 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */,
+ 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */,
0F620170143FCD2F0068B77C /* DFGBasicBlock.h */,
+ 0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */,
0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */,
- 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */,
86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */,
86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,
0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */,
@@ -2421,13 +2707,16 @@
0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */,
0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */,
0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */,
+ 0FB4B51A16B62772003F696B /* DFGCommon.cpp */,
0FC0977E1469EBC400CF2442 /* DFGCommon.h */,
0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */,
0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */,
- 0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */,
- 0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */,
+ 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */,
+ 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */,
0FFFC94D14EF909500C72532 /* DFGCSEPhase.cpp */,
0FFFC94E14EF909500C72532 /* DFGCSEPhase.h */,
+ 0F2FC77016E12F6F0038D976 /* DFGDCEPhase.cpp */,
+ 0F2FC77116E12F6F0038D976 /* DFGDCEPhase.h */,
0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */,
0FF427621591A1C9004CB9FF /* DFGDisassembler.h */,
0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */,
@@ -2435,6 +2724,7 @@
0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */,
0FD3C82014115CF800FD81CB /* DFGDriver.cpp */,
0FD3C82214115D0E00FD81CB /* DFGDriver.h */,
+ 0FB4B51B16B62772003F696B /* DFGEdge.cpp */,
0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */,
0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */,
0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */,
@@ -2446,10 +2736,15 @@
0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */,
86EC9DBB1328DF82002B2AD7 /* DFGJITCompiler.cpp */,
86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */,
+ 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */,
+ 0FB4B51D16B62772003F696B /* DFGLongLivedState.h */,
0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */,
+ 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */,
+ 0FB4B51E16B62772003F696B /* DFGNode.cpp */,
86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */,
+ 0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */,
0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */,
0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */,
@@ -2459,12 +2754,17 @@
0FD82E53141DAEDE00179C94 /* DFGOSREntry.h */,
0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */,
0FC097681468A6EF00CF2442 /* DFGOSRExit.h */,
+ 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */,
0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */,
0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */,
0FC09775146943AD00CF2442 /* DFGOSRExitCompiler32_64.cpp */,
0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */,
+ 0FEFC9A71681A3B000567F53 /* DFGOSRExitJumpPlaceholder.cpp */,
+ 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */,
0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
0FFFC95014EF909500C72532 /* DFGPhase.h */,
+ 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */,
+ 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
@@ -2480,10 +2780,14 @@
86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */,
86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */,
0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */,
- 0F63943C15C75F14006A597C /* DFGStructureCheckHoistingPhase.cpp */,
- 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */,
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
0FC097A0146B28C700CF2442 /* DFGThunks.h */,
+ 0F63943C15C75F14006A597C /* DFGTypeCheckHoistingPhase.cpp */,
+ 0F63943D15C75F14006A597C /* DFGTypeCheckHoistingPhase.h */,
+ 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */,
+ 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */,
+ 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */,
+ 0F34B14816D4200E001CDA5A /* DFGUseKind.h */,
0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */,
0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */,
0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,
@@ -2496,6 +2800,7 @@
0F2BDC411522801700CD8910 /* DFGVariableEvent.h */,
0F2BDC421522801700CD8910 /* DFGVariableEventStream.cpp */,
0F2BDC431522801700CD8910 /* DFGVariableEventStream.h */,
+ 0F85A31E16AB76AE0077571E /* DFGVariadicFunction.h */,
0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */,
0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */,
);
@@ -2516,14 +2821,39 @@
isa = PBXGroup;
children = (
95E3BC040E1AE68200B2D1C1 /* CallIdentifier.h */,
+ 95AB832E0DA42CAD00BC83F3 /* LegacyProfiler.cpp */,
+ 95AB832F0DA42CAD00BC83F3 /* LegacyProfiler.h */,
95742F630DD11F5A000917FB /* Profile.cpp */,
95742F640DD11F5A000917FB /* Profile.h */,
95CD45740E1C4FDD0085358E /* ProfileGenerator.cpp */,
95CD45750E1C4FDD0085358E /* ProfileGenerator.h */,
95AB83540DA43B4400BC83F3 /* ProfileNode.cpp */,
95AB83550DA43B4400BC83F3 /* ProfileNode.h */,
- 95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */,
- 95AB832F0DA42CAD00BC83F3 /* Profiler.h */,
+ 0FF72992166AD347000F5BA3 /* ProfilerBytecode.cpp */,
+ 0FF72993166AD347000F5BA3 /* ProfilerBytecode.h */,
+ 0FF72994166AD347000F5BA3 /* ProfilerBytecodes.cpp */,
+ 0FF72995166AD347000F5BA3 /* ProfilerBytecodes.h */,
+ 0F13912416771C30009CCB07 /* ProfilerBytecodeSequence.cpp */,
+ 0F13912516771C30009CCB07 /* ProfilerBytecodeSequence.h */,
+ 0FF72996166AD347000F5BA3 /* ProfilerCompilation.cpp */,
+ 0FF72997166AD347000F5BA3 /* ProfilerCompilation.h */,
+ 0FF72998166AD347000F5BA3 /* ProfilerCompilationKind.cpp */,
+ 0FF72999166AD347000F5BA3 /* ProfilerCompilationKind.h */,
+ 0FF7299A166AD347000F5BA3 /* ProfilerCompiledBytecode.cpp */,
+ 0FF7299B166AD347000F5BA3 /* ProfilerCompiledBytecode.h */,
+ 0FF7299C166AD347000F5BA3 /* ProfilerDatabase.cpp */,
+ 0FF7299D166AD347000F5BA3 /* ProfilerDatabase.h */,
+ 0FF7299E166AD347000F5BA3 /* ProfilerExecutionCounter.h */,
+ 0FF7299F166AD347000F5BA3 /* ProfilerOrigin.cpp */,
+ 0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */,
+ 0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */,
+ 0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */,
+ 0FB105871675482E00F8AB6E /* ProfilerOSRExit.cpp */,
+ 0FB105881675482E00F8AB6E /* ProfilerOSRExit.h */,
+ 0FB105891675482E00F8AB6E /* ProfilerOSRExitSite.cpp */,
+ 0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.h */,
+ 0F13912616771C30009CCB07 /* ProfilerProfiledBytecodes.cpp */,
+ 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */,
);
name = profiler;
sourceTree = "<group>";
@@ -2549,7 +2879,6 @@
86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */,
863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */,
86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */,
- 86AE64A5135E5E1C00963012 /* MacroAssemblerSH4.cpp */,
86AE64A6135E5E1C00963012 /* MacroAssemblerSH4.h */,
860161E00F3A83C100F84710 /* MacroAssemblerX86.h */,
860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */,
@@ -2576,22 +2905,23 @@
0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */,
0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */,
0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */,
+ 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
+ 969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
0F8F943D1667632D00D61971 /* CodeBlockHash.cpp */,
0F8F943E1667632D00D61971 /* CodeBlockHash.h */,
0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */,
- 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
- 969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
0F8F9445166764EE00D61971 /* CodeOrigin.cpp */,
0FBD7E671447998F00481315 /* CodeOrigin.h */,
0F8F943F1667632D00D61971 /* CodeType.cpp */,
0F0B83A514BCF50400885B4F /* CodeType.h */,
- FEB63AA2159B9DA3008932A6 /* Comment.h */,
0F426A4A1460CD6B00131F8F /* DataFormat.h */,
0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */,
0F56A1D115000F31002992B1 /* ExecutionCounter.h */,
+ 0FB105821675480C00F8AB6E /* ExitKind.cpp */,
+ 0FB105831675480C00F8AB6E /* ExitKind.h */,
0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */,
0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,
0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */,
@@ -2605,14 +2935,20 @@
0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */,
0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */,
0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */,
+ 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */,
969A07940ED1D3AE00F1F681 /* Opcode.cpp */,
969A07950ED1D3AE00F1F681 /* Opcode.h */,
0F2BDC2B151FDE8B00CD8910 /* Operands.h */,
+ 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */,
0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */,
0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */,
+ 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */,
+ 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */,
0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */,
+ 0FF60ABF16740F8100029779 /* ReduceWhitespace.cpp */,
+ 0FF60AC016740F8100029779 /* ReduceWhitespace.h */,
0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */,
0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */,
A7AFC17715F7EFE30048F57B /* ResolveOperation.h */,
@@ -2623,22 +2959,17 @@
0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
0FD82E4F141DAEA100179C94 /* SpeculatedType.h */,
0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
- 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */,
0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */,
0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */,
BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */,
BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */,
+ A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
+ A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */,
0F426A451460CBAB00131F8F /* ValueRecovery.h */,
0F426A461460CBAB00131F8F /* VirtualRegister.h */,
0F919D2215853CDE004A4E7D /* Watchpoint.cpp */,
0F919D2315853CDE004A4E7D /* Watchpoint.h */,
- 0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */,
- 0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */,
- 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */,
- 0F93329B14CA7DC10085F3C6 /* StructureSet.h */,
- A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
- A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
);
path = bytecode;
sourceTree = "<group>";
@@ -2662,56 +2993,68 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0FFB921F16D033050055A5DB /* (null) in Headers */,
860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
+ 0F55F0F514D1063C00AC7649 /* AbstractPC.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 */,
- C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
- C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
- C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
- C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
- FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */,
- C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */,
- C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,
- C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
- C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
- FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
- C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
- C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
- C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
- C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */,
- C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
+ 65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
+ 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */,
BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
+ 0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */,
+ 0F63945515D07057006A597C /* ArrayProfile.h in Headers */,
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */,
+ 0FB7F39615ED8E4600F167B2 /* ArrayStorage.h in Headers */,
9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */,
86D3B2C510156BDE002865E7 /* AssemblerBufferWithConstantPool.h in Headers */,
A784A26111D16622005776AC /* ASTBuilder.h in Headers */,
147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
866739D213BFDE710023D87C /* BigInteger.h in Headers */,
+ 14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */,
BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
- C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */,
- C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
- C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
+ 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
+ 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
+ 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
+ 0F8023EA1613832B00A0BA45 /* ByValInfo.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 */,
+ 0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
+ 0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
+ 0F0B83B914BCF95F00885B4F /* CallReturnOffsetToBytecodeOffset.h in Headers */,
BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
+ 0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
+ 0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
+ 0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */,
+ A77F1822164088B200640A47 /* CodeCache.h in Headers */,
86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */,
0FBD7E691447999600481315 /* CodeOrigin.h in Headers */,
+ 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
+ 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
+ 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
0FD82E39141AB14D00179C94 /* CompactJITCodeMap.h in Headers */,
BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
144836E7132DA7BE005BE785 /* ConservativeRoots.h in Headers */,
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */,
+ C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
+ 1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
+ C2C8D03014A3CEFC00578E65 /* CopiedBlock.h in Headers */,
+ C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
+ C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
+ C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
+ C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */,
+ C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,
+ C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
@@ -2725,29 +3068,83 @@
BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */,
0F620178143FCD440068B77C /* DFGAbstractState.h in Headers */,
0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */,
+ 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */,
+ 0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */,
+ 0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
+ 0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */,
+ 0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */,
+ 0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
0FC0976D1468AB4E00CF2442 /* DFGAssemblyHelpers.h in Headers */,
+ 0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */,
0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */,
+ 0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */,
+ A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
+ 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */,
86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */,
+ 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
+ 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
+ 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
+ 0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
+ 0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
0F2C556F14738F3100121E4F /* DFGCodeBlocks.h in Headers */,
- 0FC0979C146A772500CF2442 /* DFGCorrectableJumpPoint.h in Headers */,
+ 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
+ 0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */,
+ 0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */,
+ 0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
+ 0F2FC77316E12F740038D976 /* DFGDCEPhase.h in Headers */,
+ 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
+ 0FD81AD3154FB4F000983E72 /* DFGDominators.h in Headers */,
+ 0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */,
0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */,
+ 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */,
0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */,
+ 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
86AE6C4D136A11E400963012 /* DFGFPRInfo.h in Headers */,
86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,
86AE6C4E136A11E400963012 /* DFGGPRInfo.h in Headers */,
86EC9DC81328DF82002B2AD7 /* DFGGraph.h in Headers */,
+ 0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
86EC9DCC1328DF82002B2AD7 /* DFGJITCompiler.h in Headers */,
+ 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
+ 0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
+ 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
+ 0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
86ECA3EA132DEF1C002B2AD7 /* DFGNode.h in Headers */,
+ 0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */,
+ 0FA581BB150E953000B9A2D9 /* DFGNodeFlags.h in Headers */,
+ 0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */,
86EC9DD01328DF82002B2AD7 /* DFGOperations.h in Headers */,
0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
+ 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
+ 0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */,
+ 0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
+ 0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */,
+ 0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */,
86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
+ 0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */,
86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */,
86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */,
+ 0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */,
+ 0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
+ 0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */,
86EC9DD31328DF82002B2AD7 /* DFGSpeculativeJIT.h in Headers */,
+ 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */,
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
+ 0F63943F15C75F19006A597C /* DFGTypeCheckHoistingPhase.h in Headers */,
+ 0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */,
+ 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */,
+ 0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
+ 0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
+ 0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */,
+ 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
+ 0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
+ 0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
+ 0FFB921E16D02F470055A5DB /* DFGVariadicFunction.h in Headers */,
+ 0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */,
+ 0FF42731158EBD54004CB9FF /* Disassembler.h in Headers */,
BC3046070E1F497F003232CF /* Error.h in Headers */,
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
@@ -2756,17 +3153,37 @@
BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */,
86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
+ 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
+ 0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
+ 0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
+ 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
+ 0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */,
BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */,
+ BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
+ 0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
+ C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */,
+ C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
+ 0F9332A014CA7DCD0085F3C6 /* GetByIdStatus.h in Headers */,
142E3134134FF0A600AFADB5 /* Handle.h in Headers */,
+ C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */,
+ C283190216FE533E00157BFD /* HandleBlockInlines.h in Headers */,
+ 0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
142E3136134FF0A600AFADB5 /* HandleSet.h in Headers */,
142E3138134FF0A600AFADB5 /* HandleStack.h in Headers */,
1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */,
14BA7A9813AADFF8005B7C2C /* Heap.h in Headers */,
C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */,
14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
+ C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,
+ C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */,
+ 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
+ C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */,
+ 0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
+ 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
+ 0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
@@ -2777,12 +3194,20 @@
BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
1429D9300ED22D7000B89619 /* JIT.h in Headers */,
86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */,
+ 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
+ 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
+ 0F21C26814BE5F6800ADC64B /* JITDriver.h in Headers */,
+ 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
86CC85A10EE79A4700288682 /* JITInlines.h in Headers */,
960626960FB8EC02009798AB /* JITStubCall.h in Headers */,
+ 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
+ 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */,
+ 0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */,
A76F54A313B28AAB00EF2BCE /* JITWriteBarrier.h in Headers */,
BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */,
840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */,
+ C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */,
BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */,
140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */,
@@ -2792,51 +3217,83 @@
BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */,
+ 0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */,
+ BC18C42B0E16F5CD00B34460 /* JSCJSValue.h in Headers */,
+ 865A30F1135007E100CDB49E /* JSCJSValueInlines.h in Headers */,
BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
+ 86E3C613167BABD7006D760A /* JSContext.h in Headers */,
+ 86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */,
BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
978801411471AD920041B016 /* JSDateMath.h in Headers */,
+ C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
+ 86E3C614167BABD7006D760A /* JSExport.h in Headers */,
A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */,
- BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */,
BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */,
A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */,
BC18C4230E16F5CD00B34460 /* JSLock.h in Headers */,
+ C25D709C16DE99F400FCA6BC /* JSManagedValue.h in Headers */,
+ 14874AE415EBDE4A002E3587 /* JSNameScope.h in Headers */,
BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */,
BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */,
BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */,
9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
+ 862553D216136E1A009F17D0 /* JSProxy.h in Headers */,
BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */,
+ 14874AE615EBDE4A002E3587 /* JSScope.h in Headers */,
+ A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
+ 0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
BC18C45E0E16F5CD00B34460 /* JSStack.h in Headers */,
BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */,
BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */,
BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */,
+ 0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */,
- BC18C42B0E16F5CD00B34460 /* JSValue.h in Headers */,
- 865A30F1135007E100CDB49E /* JSValueInlines.h in Headers */,
+ 86E3C612167BABD7006D760A /* JSValue.h in Headers */,
+ 86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */,
+ 86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
+ 86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
+ 1442566215EDE98D0066A49B /* JSWithScope.h in Headers */,
+ 86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */,
BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */,
+ 0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */,
BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */,
A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */,
969A072A0ED1CE6900F1F681 /* Label.h in Headers */,
960097A60EBABB58007A7297 /* LabelScope.h in Headers */,
+ 0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */,
+ BC18C4520E16F5CD00B34460 /* LegacyProfiler.h in Headers */,
BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */,
BC18C52E0E16FCE100B34460 /* Lexer.lut.h in Headers */,
+ 0F0B83AD14BCF60400885B4F /* LineInfo.h in Headers */,
86D3B3C310159D7F002865E7 /* LinkBuffer.h in Headers */,
0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
+ 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
+ FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
+ 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
+ 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
+ 0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
+ 0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
+ 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
+ FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
+ 0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
+ 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
142E3139134FF0A600AFADB5 /* Local.h in Headers */,
142E313A134FF0A600AFADB5 /* LocalScope.h in Headers */,
BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */,
+ 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
14B723B812D7DA6F003BD5ED /* MachineStackMarker.h in Headers */,
86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */,
86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */,
@@ -2847,16 +3304,24 @@
860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */,
860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */,
860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */,
+ C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
142D6F0913539A2800B02E86 /* MarkedBlock.h in Headers */,
141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
+ C21122E315DD9AB300790E3A /* MarkStackInlines.h in Headers */,
+ 8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */,
90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */,
+ 0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */,
+ 86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */,
+ 86EBF3021560F06A008E9222 /* NameInstance.h in Headers */,
+ 86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */,
BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
+ 0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */,
7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
@@ -2864,25 +3329,57 @@
BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */,
BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */,
142D3939103E4560007DCB52 /* NumericStrings.h in Headers */,
+ 86F3EEBD168CDE930077B92A /* ObjCCallbackFunction.h in Headers */,
+ 86F3EEBF168CDE930077B92A /* ObjcRuntimeExtras.h in Headers */,
+ 14CA958D16AB50FA00938A06 /* ObjectAllocationProfile.h in Headers */,
BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */,
BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */,
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
+ 0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
0FE228ED1436AB2700196C48 /* Options.h in Headers */,
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
93052C350FB792190048FDC3 /* ParserArena.h in Headers */,
+ 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */,
+ A77F1825164192C700640A47 /* ParserModes.h in Headers */,
65303D641447B9E100D3F904 /* ParserTokens.h in Headers */,
- 0FD82E54141DAEEE00179C94 /* SpeculatedType.h in Headers */,
+ 1497209114EB831500FEB1B7 /* PassWeak.h in Headers */,
+ 0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */,
+ 0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
+ 0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
+ 868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
+ 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
- BC18C4520E16F5CD00B34460 /* Profiler.h in Headers */,
+ 0FF729A5166AD351000F5BA3 /* ProfilerBytecode.h in Headers */,
+ 0FF729B9166AD360000F5BA3 /* ProfilerBytecodes.h in Headers */,
+ 0F13912A16771C36009CCB07 /* ProfilerBytecodeSequence.h in Headers */,
+ 0FF729BA166AD360000F5BA3 /* ProfilerCompilation.h in Headers */,
+ 0FF729BB166AD360000F5BA3 /* ProfilerCompilationKind.h in Headers */,
+ A72028BA1797603D0098028C /* JSFunctionInlines.h in Headers */,
+ 0FF729BC166AD360000F5BA3 /* ProfilerCompiledBytecode.h in Headers */,
+ 0FF729BD166AD360000F5BA3 /* ProfilerDatabase.h in Headers */,
+ 0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */,
+ 0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */,
+ 0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */,
+ 0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */,
+ 0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */,
+ 0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */,
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */,
BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */,
+ 86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */,
BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */,
+ 0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */,
BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
+ 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
+ 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
+ 0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */,
+ 0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */,
+ 0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */,
147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
+ 0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */,
BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */,
A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */,
BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
@@ -2891,20 +3388,30 @@
BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,
BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */,
BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
+ C20B25991706536200C21F4E /* Region.h in Headers */,
BC18C45D0E16F5CD00B34460 /* Register.h in Headers */,
969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */,
+ 0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */,
86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */,
+ 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */,
+ A7AFC17915F7EFE30048F57B /* ResolveOperation.h in Headers */,
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */,
1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */,
86AE64AA135E5E1C00963012 /* SH4Assembler.h in Headers */,
14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
+ C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
933040040E6A749400786E6A /* SmallStrings.h in Headers */,
BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */,
BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */,
E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */,
+ 0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */,
A7386554118697B400540279 /* SpecializedThunkJIT.h in Headers */,
+ 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */,
+ 0FD82E54141DAEEE00179C94 /* SpeculatedType.h in Headers */,
+ 14DF04DA16B3996D0016A513 /* StaticPropertyAnalysis.h in Headers */,
+ 14CA958B16AB50DE00938A06 /* StaticPropertyAnalyzer.h in Headers */,
A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */,
BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */,
@@ -2914,25 +3421,50 @@
145722861437E140005FDE26 /* StrongInlines.h in Headers */,
BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */,
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
+ 0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
+ C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
+ C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */,
+ 0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
+ 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
+ C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */,
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
- 971EDEA61169E0D3005E4262 /* Terminator.h in Headers */,
+ 0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */,
A7386556118697B400540279 /* ThunkGenerators.h in Headers */,
- 14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */,
141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */,
5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
+ 0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */,
+ 0FF4274B158EBE91004CB9FF /* udis86.h in Headers */,
+ 0FF42741158EBE8D004CB9FF /* udis86_decode.h in Headers */,
+ 0FF42742158EBE91004CB9FF /* udis86_extern.h in Headers */,
+ 0FF42744158EBE91004CB9FF /* udis86_input.h in Headers */,
+ 0FF42748158EBE91004CB9FF /* udis86_syn.h in Headers */,
+ 0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */,
0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */,
+ A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
+ 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */,
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
+ BC18C4200E16F5CD00B34460 /* VM.h in Headers */,
+ FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */,
+ FE6617281774E03500495B00 /* VMStackBounds.h in Headers */,
0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */,
+ FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */,
+ 0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
142E313C134FF0A600AFADB5 /* Weak.h in Headers */,
+ 14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */,
14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */,
+ 14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
+ 14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
+ 14BE7D3317135CF400D1807A /* WeakInlines.h in Headers */,
1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */,
0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */,
+ 14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */,
+ 14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */,
A7DCB97312E5193F00911940 /* WriteBarrier.h in Headers */,
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */,
@@ -2943,140 +3475,6 @@
86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
- 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
- 0F4680A314BA7F8D00BFE272 /* LLIntExceptions.h in Headers */,
- 0F4680A514BA7F8D00BFE272 /* LLIntSlowPaths.h in Headers */,
- 0F46808214BA572D00BFE272 /* JITExceptions.h in Headers */,
- 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
- 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */,
- 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */,
- 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,
- 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */,
- 0F0B839B14BCF46000885B4F /* LLIntEntrypoints.h in Headers */,
- 0F0B839D14BCF46600885B4F /* LLIntThunks.h in Headers */,
- 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
- 0F0B83A914BCF56200885B4F /* HandlerInfo.h in Headers */,
- 0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
- 0F0B83AD14BCF60400885B4F /* LineInfo.h in Headers */,
- 0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
- 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 */,
- 0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */,
- 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
- 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */,
- 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
- 0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
- 0F9332A014CA7DCD0085F3C6 /* GetByIdStatus.h in Headers */,
- 0F9332A414CA7DD90085F3C6 /* PutByIdStatus.h in Headers */,
- 0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */,
- 0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */,
- 0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */,
- 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */,
- 0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */,
- 0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */,
- BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
- 0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
- 0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */,
- 0FFFC95C14EF90AF00C72532 /* DFGPhase.h in Headers */,
- 0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */,
- 0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */,
- 1497209114EB831500FEB1B7 /* PassWeak.h in Headers */,
- 14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */,
- 14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */,
- 14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
- 14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
- 0FB5467714F59B5C002C2989 /* LazyOperandValueProfile.h in Headers */,
- 0FB5467B14F5C7E1002C2989 /* MethodOfGettingAValueProfile.h in Headers */,
- 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */,
- 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */,
- 0FA581BB150E953000B9A2D9 /* DFGNodeFlags.h in Headers */,
- 0FA581BC150E953000B9A2D9 /* DFGNodeType.h in Headers */,
- 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
- 0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
- 0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
- 0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
- 0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
- 0F2BDC471522802500CD8910 /* DFGValueRecoveryOverride.h in Headers */,
- 0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
- 0F2BDC491522809600CD8910 /* DFGVariableEvent.h in Headers */,
- 0F2BDC4B1522809D00CD8910 /* DFGVariableEventStream.h in Headers */,
- 8612E4CD152389EC00C836BE /* MatchResult.h in Headers */,
- 0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
- 0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */,
- 0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */,
- 14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
- 14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */,
- 86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */,
- 868916B0155F286300CB2B9A /* PrivateName.h in Headers */,
- 86EBF3001560F06A008E9222 /* NameConstructor.h in Headers */,
- 86EBF3021560F06A008E9222 /* NameInstance.h in Headers */,
- 86EBF3041560F06A008E9222 /* NamePrototype.h in Headers */,
- 0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
- 0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
- 0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
- 0FD81AD3154FB4F000983E72 /* DFGDominators.h in Headers */,
- 0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */,
- 0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
- 0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
- 0F919D2615853CE3004A4E7D /* Watchpoint.h in Headers */,
- 0FF42731158EBD54004CB9FF /* Disassembler.h in Headers */,
- 0FF42741158EBE8D004CB9FF /* udis86_decode.h in Headers */,
- 0FF42742158EBE91004CB9FF /* udis86_extern.h in Headers */,
- 0FF42744158EBE91004CB9FF /* udis86_input.h in Headers */,
- 0FF42748158EBE91004CB9FF /* udis86_syn.h in Headers */,
- 0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */,
- 0FF4274B158EBE91004CB9FF /* udis86.h in Headers */,
- 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */,
- 0FF42772159275D8004CB9FF /* ResolveGlobalStatus.h in Headers */,
- 0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */,
- 0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
- 0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
- 0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
- 0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */,
- 0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
- 0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */,
- 0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */,
- 0F63943F15C75F19006A597C /* DFGStructureCheckHoistingPhase.h in Headers */,
- 0F63945515D07057006A597C /* ArrayProfile.h in Headers */,
- 0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
- 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */,
- 14874AE415EBDE4A002E3587 /* JSNameScope.h in Headers */,
- 14874AE615EBDE4A002E3587 /* JSScope.h in Headers */,
- FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */,
- 1442566215EDE98D0066A49B /* JSWithScope.h in Headers */,
- A7AFC17915F7EFE30048F57B /* ResolveOperation.h in Headers */,
- 0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */,
- 0FB7F39615ED8E4600F167B2 /* ArrayStorage.h in Headers */,
- 0FB7F39715ED8E4600F167B2 /* Butterfly.h in Headers */,
- 0FB7F39815ED8E4600F167B2 /* ButterflyInlines.h in Headers */,
- 0FB7F39915ED8E4600F167B2 /* IndexingHeader.h in Headers */,
- 0FB7F39A15ED8E4600F167B2 /* IndexingHeaderInlines.h in Headers */,
- 0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
- 0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
- 0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */,
- 0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */,
- 0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */,
- 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
- 862553D216136E1A009F17D0 /* JSProxy.h in Headers */,
- 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */,
- 0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */,
- 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
- C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */,
- 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */,
- 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */,
- A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
- A77F1822164088B200640A47 /* CodeCache.h in Headers */,
- A77F1825164192C700640A47 /* ParserModes.h in Headers */,
- 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */,
- 0F73D7AF165A143000ACAB71 /* ClosureCallStubRoutine.h in Headers */,
- 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */,
- 0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
- 0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3164,6 +3562,7 @@
932F5BD20822A1C700736975 /* Frameworks */,
5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables and Externals */,
3713F014142905240036387F /* Check For Inappropriate Objective-C Class Names */,
+ A55DEAA416703DF7003DB841 /* Check For Inappropriate Macros in External Headers */,
);
buildRules = (
);
@@ -3356,6 +3755,21 @@
shellPath = /bin/sh;
shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\n/bin/ln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake --no-builtin-rules -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu` || exit 1\n\n/usr/bin/env ruby JavaScriptCore/offlineasm/asm.rb JavaScriptCore/llint/LowLevelInterpreter.asm ${BUILT_PRODUCTS_DIR}/JSCLLIntOffsetsExtractor LLIntAssembly.h || exit 1\n";
};
+ A55DEAA416703DF7003DB841 /* Check For Inappropriate Macros in External Headers */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
+ );
+ name = "Check For Inappropriate Macros in External Headers";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"${ACTION}\" = \"installhdrs\" ]; then\n exit 0;\nfi\n\nif [ -f ../../Tools/Scripts/check-for-inappropriate-macros-in-external-headers ]; then\n ../../Tools/Scripts/check-for-inappropriate-macros-in-external-headers Headers PrivateHeaders/JSBasePrivate.h || exit $?\nfi";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -3384,6 +3798,7 @@
buildActionMask = 2147483647;
files = (
1440F6100A4F85670005F061 /* testapi.c in Sources */,
+ 86D2221A167EF9440024C804 /* testapi.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3399,24 +3814,41 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,
A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */,
+ 65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */,
+ 65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */,
+ 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
147F39BF107EC37600427A48 /* ArrayConstructor.cpp in Sources */,
+ 0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
+ 14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
- C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
148F21AA107EC53A0042EC2C /* BytecodeGenerator.cpp in Sources */,
1428082D107EC0570013E7B2 /* CallData.cpp in Sources */,
1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
+ 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
+ 0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
+ 0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
+ 0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
+ A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
+ 0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
+ 86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */,
+ 86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
+ 0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
+ 0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */,
147F39C2107EC37600427A48 /* Completion.cpp in Sources */,
146B16D812EB5B59001BEC1B /* ConservativeRoots.cpp in Sources */,
1428082E107EC0570013E7B2 /* ConstructData.cpp in Sources */,
+ C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
+ C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
147F39C3107EC37600427A48 /* DateConstructor.cpp in Sources */,
147F39C4107EC37600427A48 /* DateConversion.cpp in Sources */,
147F39C5107EC37600427A48 /* DateInstance.cpp in Sources */,
@@ -3425,26 +3857,57 @@
BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */,
149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
0F620179143FCD480068B77C /* DFGAbstractState.cpp in Sources */,
+ 0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */,
+ 0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
0FC0976E1468AB5100CF2442 /* DFGAssemblyHelpers.cpp in Sources */,
+ 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
86EC9DC41328DF82002B2AD7 /* DFGByteCodeParser.cpp in Sources */,
0FD82E2114172CE300179C94 /* DFGCapabilities.cpp in Sources */,
+ 0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
+ 0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
0F2C557014738F3500121E4F /* DFGCodeBlocks.cpp in Sources */,
- 0FC0979E146B272100CF2442 /* DFGCorrectableJumpPoint.cpp in Sources */,
+ 0FF0F19D16B72A08005DF95B /* DFGCommon.cpp in Sources */,
+ 0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */,
+ 0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */,
+ 0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
+ 0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
+ 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
+ 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */,
+ 0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */,
0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */,
+ 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */,
86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
+ 0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */,
+ 0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */,
+ 0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */,
+ 0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
86EC9DCF1328DF82002B2AD7 /* DFGOperations.cpp in Sources */,
0FD82E56141DAF0800179C94 /* DFGOSREntry.cpp in Sources */,
0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
+ 0FEFC9AA1681A3B300567F53 /* DFGOSRExitJumpPlaceholder.cpp in Sources */,
+ 0FFFC95B14EF90AD00C72532 /* DFGPhase.cpp in Sources */,
+ 0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */,
+ 0FFFC95D14EF90B300C72532 /* DFGPredictionPropagationPhase.cpp in Sources */,
86BB09C0138E381B0056702F /* DFGRepatch.cpp in Sources */,
86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */,
0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
+ 0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */,
+ 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */,
+ 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */,
+ 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */,
+ 0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */,
+ 0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
+ 0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
+ 0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
+ 0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
+ 0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */,
147F39C7107EC37600427A48 /* Error.cpp in Sources */,
147F39C8107EC37600427A48 /* ErrorConstructor.cpp in Sources */,
147F39C9107EC37600427A48 /* ErrorInstance.cpp in Sources */,
@@ -3453,13 +3916,26 @@
86CA032E1038E8440028A609 /* Executable.cpp in Sources */,
A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */,
+ 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
+ 0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
147F39CB107EC37600427A48 /* FunctionConstructor.cpp in Sources */,
+ 0FF0F19F16B72A17005DF95B /* FunctionExecutableDump.cpp in Sources */,
147F39CC107EC37600427A48 /* FunctionPrototype.cpp in Sources */,
+ C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */,
+ 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
+ C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */,
+ C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */,
+ 0F93329F14CA7DCA0085F3C6 /* GetByIdStatus.cpp in Sources */,
14280855107EC0E70013E7B2 /* GetterSetter.cpp in Sources */,
142E3135134FF0A600AFADB5 /* HandleSet.cpp in Sources */,
142E3137134FF0A600AFADB5 /* HandleStack.cpp in Sources */,
14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */,
+ C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */,
+ C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */,
+ 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
147F39CE107EC37600427A48 /* Identifier.cpp in Sources */,
+ C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */,
+ 0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */,
E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */,
147F39CF107EC37600427A48 /* InternalFunction.cpp in Sources */,
1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */,
@@ -3468,13 +3944,21 @@
A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */,
86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */,
146FE51211A710430087AE66 /* JITCall32_64.cpp in Sources */,
+ 0F8F94441667635400D61971 /* JITCode.cpp in Sources */,
+ 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */,
+ 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
BCDD51EB0FB8DF74004A8BDC /* JITOpcodes.cpp in Sources */,
A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */,
86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */,
A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */,
+ 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */,
+ 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */,
14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */,
+ A72028B61797601E0098028C /* JSCTestRunnerUtils.cpp in Sources */,
+ 0F5EF91E16878F7A003E5C25 /* JITThunks.cpp in Sources */,
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */,
+ C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */,
147F39D0107EC37600427A48 /* JSArray.cpp in Sources */,
1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */,
@@ -3482,42 +3966,69 @@
1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */,
14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
147F39D1107EC37600427A48 /* JSCell.cpp in Sources */,
+ 147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */,
1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
+ 86E3C616167BABEE006D760A /* JSContext.mm in Sources */,
14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */,
- E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */,
147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */,
14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */,
14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */,
+ C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
+ 14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */,
A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */,
147F39D4107EC37600427A48 /* JSObject.cpp in Sources */,
1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */,
A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */,
95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */,
A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */,
+ 862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */,
+ 14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
+ A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */,
+ 0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */,
1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
147F39D5107EC37600427A48 /* JSString.cpp in Sources */,
2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */,
1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
- 147F39D6107EC37600427A48 /* JSValue.cpp in Sources */,
+ 0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */,
+ 86E3C61A167BABEE006D760A /* JSValue.mm in Sources */,
14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */,
147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */,
+ 86E3C61C167BABEE006D760A /* JSVirtualMachine.mm in Sources */,
A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
+ 1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
+ 86E3C618167BABEE006D760A /* JSWrapperMap.mm in Sources */,
14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */,
+ 0F766D3415AE2538008F363E /* JumpReplacementWatchpoint.cpp in Sources */,
BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,
+ 0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */,
+ 95AB83420DA4322500BC83F3 /* LegacyProfiler.cpp in Sources */,
148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */,
+ 0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */,
A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */,
+ FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */,
+ 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
+ 0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
+ 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
+ 0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
+ 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
14469DDE107EC7E700650446 /* Lookup.cpp in Sources */,
+ 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
+ 0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */,
86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */,
- 86AE64A8135E5E1C00963012 /* MacroAssemblerSH4.cpp in Sources */,
+ C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
142D6F0813539A2800B02E86 /* MarkedBlock.cpp in Sources */,
14D2F3DA139F4BE200491031 /* MarkedSpace.cpp in Sources */,
142D6F1113539A4100B02E86 /* MarkStack.cpp in Sources */,
14469DDF107EC7E700650446 /* MathObject.cpp in Sources */,
90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */,
+ 0FB5467D14F5CFD6002C2989 /* MethodOfGettingAValueProfile.cpp in Sources */,
+ 86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */,
+ 86EBF3011560F06A008E9222 /* NameInstance.cpp in Sources */,
+ 86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */,
14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */,
14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */,
148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */,
@@ -3525,6 +4036,7 @@
14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */,
14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */,
14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */,
+ 86F3EEBE168CDE930077B92A /* ObjCCallbackFunction.mm in Sources */,
14469DE5107EC7E700650446 /* ObjectConstructor.cpp in Sources */,
14469DE6107EC7E700650446 /* ObjectPrototype.cpp in Sources */,
E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */,
@@ -3533,23 +4045,47 @@
0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */,
148F21BC107EC54D0042EC2C /* Parser.cpp in Sources */,
93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */,
- 0FD82E86141F3FF100179C94 /* SpeculatedType.cpp in Sources */,
+ 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
+ 0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
- 95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */,
+ 0FF729AD166AD35C000F5BA3 /* ProfilerBytecode.cpp in Sources */,
+ 0FF729AE166AD35C000F5BA3 /* ProfilerBytecodes.cpp in Sources */,
+ 0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */,
+ 0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */,
+ 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */,
+ 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */,
+ 0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */,
+ 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
+ 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
+ 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
+ 0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
+ 0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,
A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */,
14469DE7107EC7E700650446 /* PropertyNameArray.cpp in Sources */,
14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */,
+ ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */,
+ 1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */,
+ 0F9332A314CA7DD70085F3C6 /* PutByIdStatus.cpp in Sources */,
+ 0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */,
14280841107EC0930013E7B2 /* RegExp.cpp in Sources */,
A1712B3B11C7B212007A5315 /* RegExpCache.cpp in Sources */,
+ 8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */,
+ 8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */,
14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */,
14280844107EC0930013E7B2 /* RegExpPrototype.cpp in Sources */,
+ 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */,
0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */,
1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */,
+ C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */,
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
+ 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */,
+ 0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */,
+ 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */,
+ 0FD82E86141F3FF100179C94 /* SpeculatedType.cpp in Sources */,
A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */,
14469DEB107EC7E700650446 /* StringConstructor.cpp in Sources */,
14469DEC107EC7E700650446 /* StringObject.cpp in Sources */,
@@ -3557,114 +4093,37 @@
9335F24D12E6765B002B5553 /* StringRecursionChecker.cpp in Sources */,
BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */,
7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */,
+ C2F0F2D116BAEEE900187C19 /* StructureRareData.cpp in Sources */,
+ 0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */,
BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
- A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */,
- 14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */,
- 0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */,
- 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
- 86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
- 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
- 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
- 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
- 0F4680A414BA7F8D00BFE272 /* LLIntSlowPaths.cpp in Sources */,
- 0F4680A814BA7FAB00BFE272 /* LLIntExceptions.cpp in Sources */,
- 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */,
- 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
- 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */,
- 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */,
- 0F0B839A14BCF45D00885B4F /* LLIntEntrypoints.cpp in Sources */,
- 0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
- 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
- 0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
- 0F93329F14CA7DCA0085F3C6 /* GetByIdStatus.cpp in Sources */,
- 0F9332A314CA7DD70085F3C6 /* PutByIdStatus.cpp in Sources */,
- 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
- 86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */,
- 86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
- C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
- 0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */,
- 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
- 14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
- 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
- 0FFFC95714EF90A000C72532 /* DFGCFAPhase.cpp in Sources */,
- 0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
- 0FFFC95B14EF90AD00C72532 /* DFGPhase.cpp in Sources */,
- 0FFFC95D14EF90B300C72532 /* DFGPredictionPropagationPhase.cpp in Sources */,
- 0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
- 0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */,
- 0FB5467D14F5CFD6002C2989 /* MethodOfGettingAValueProfile.cpp in Sources */,
- 0F56A1D515001CF4002992B1 /* ExecutionCounter.cpp in Sources */,
- 0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
- 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
- 8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
- 8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */,
- 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
- 0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
- 0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */,
- 0F2BDC4F15228BF300CD8910 /* DFGValueSource.cpp in Sources */,
- 0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
- 14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
- 86EBF2FF1560F06A008E9222 /* NameConstructor.cpp in Sources */,
- 86EBF3011560F06A008E9222 /* NameInstance.cpp in Sources */,
- 86EBF3031560F06A008E9222 /* NamePrototype.cpp in Sources */,
- 0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */,
- 0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */,
- 0F3B3A2B15475000003ED0FF /* DFGValidate.cpp in Sources */,
- 0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */,
- 0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */,
- C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */,
- 0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */,
- 0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */,
- 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
+ C2DF442F1707AC0100A5CA96 /* SuperRegion.cpp in Sources */,
0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
- 0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
+ A7386555118697B400540279 /* ThunkGenerators.cpp in Sources */,
+ 0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
0FF42743158EBE91004CB9FF /* udis86_input.c in Sources */,
+ 0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */,
0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */,
- 0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
- 0FF4274D158EBFE6004CB9FF /* udis86_itab_holder.c in Sources */,
- C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */,
- 0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */,
- C2D58C3415912FEE0021A844 /* GCActivityCallback.cpp in Sources */,
- 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
- 0FF42771159275D5004CB9FF /* ResolveGlobalStatus.cpp in Sources */,
- 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */,
- 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */,
- 0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
- 0F766D3415AE2538008F363E /* JumpReplacementWatchpoint.cpp in Sources */,
- 0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */,
- FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */,
- 0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */,
- 0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
- 0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
- C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */,
- 14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */,
- 14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
- 1442566115EDE98D0066A49B /* JSWithScope.cpp in Sources */,
- 0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */,
- FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */,
- C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */,
- 862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */,
- 0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */,
- 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */,
- 0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */,
- C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */,
- C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
- C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */,
- 0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */,
+ 0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
A76F279415F13C9600517D67 /* UnlinkedCodeBlock.cpp in Sources */,
- A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
- 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */,
- 0F73D7AE165A142D00ACAB71 /* ClosureCallStubRoutine.cpp in Sources */,
- 0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */,
- 0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
- 0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
- 0F8F94401667633000D61971 /* CodeBlockHash.cpp in Sources */,
- 0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
- 0F8F94441667635400D61971 /* JITCode.cpp in Sources */,
- 0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
+ E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */,
+ FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */,
+ 0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */,
+ FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
+ FED94F30171E3E2300BE77A4 /* WatchdogMac.cpp in Sources */,
+ 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
+ 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
+ 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
+ 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
+ 14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */,
+ 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */,
+ 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
+ 86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
+ 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
+ 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
+ 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/JavaScriptCore/KeywordLookupGenerator.py b/Source/JavaScriptCore/KeywordLookupGenerator.py
index 748acf9dc..e5c3b2d68 100644
--- a/Source/JavaScriptCore/KeywordLookupGenerator.py
+++ b/Source/JavaScriptCore/KeywordLookupGenerator.py
@@ -68,11 +68,16 @@ def allWhitespace(str):
def parseKeywords(keywordsText):
+
+ if sys.platform == "cygwin":
+ keywordsText = keywordsText.replace("\r\n", "\n")
+
lines = keywordsText.split("\n")
lines = [line.split("#")[0] for line in lines]
lines = [line for line in lines if (not allWhitespace(line))]
name = lines[0].split()
terminator = lines[-1]
+
if not name[0] == "@begin":
raise Exception("expected description beginning with @begin")
if not terminator == "@end":
@@ -139,7 +144,7 @@ class Trie:
print(str + "if (!isIdentPart(code[%d])) {" % (len(self.fullPrefix)))
print(str + " internalShift<%d>();" % len(self.fullPrefix))
print(str + " if (shouldCreateIdentifier)")
- print(str + (" data->ident = &m_globalData->propertyNames->%sKeyword;" % self.fullPrefix))
+ print(str + (" data->ident = &m_vm->propertyNames->%sKeyword;" % self.fullPrefix))
print(str + " return " + self.value + ";")
print(str + "}")
rootIndex = len(self.fullPrefix)
diff --git a/Source/JavaScriptCore/LLIntOffsetsExtractor.pro b/Source/JavaScriptCore/LLIntOffsetsExtractor.pro
index d119bbf08..37d6f1962 100644
--- a/Source/JavaScriptCore/LLIntOffsetsExtractor.pro
+++ b/Source/JavaScriptCore/LLIntOffsetsExtractor.pro
@@ -34,7 +34,7 @@ LLINT_DEPENDENCY = \
$$PWD/llint/LowLevelInterpreter.asm \
$$PWD/llint/LowLevelInterpreter32_64.asm \
$$PWD/llint/LowLevelInterpreter64.asm \
- $$PWD/offlineasm/armv7.rb \
+ $$PWD/offlineasm/arm.rb \
$$PWD/offlineasm/ast.rb \
$$PWD/offlineasm/backends.rb \
$$PWD/offlineasm/generate_offset_extractor.rb \
@@ -45,6 +45,7 @@ LLINT_DEPENDENCY = \
$$PWD/offlineasm/registers.rb \
$$PWD/offlineasm/self_hash.rb \
$$PWD/offlineasm/settings.rb \
+ $$PWD/offlineasm/sh4.rb \
$$PWD/offlineasm/transform.rb \
$$PWD/offlineasm/x86.rb
diff --git a/Source/JavaScriptCore/PlatformBlackBerry.cmake b/Source/JavaScriptCore/PlatformBlackBerry.cmake
index f9352cd4f..15e45f28a 100644
--- a/Source/JavaScriptCore/PlatformBlackBerry.cmake
+++ b/Source/JavaScriptCore/PlatformBlackBerry.cmake
@@ -1,14 +1,9 @@
-LIST(INSERT JavaScriptCore_INCLUDE_DIRECTORIES 0
- "${BLACKBERRY_THIRD_PARTY_DIR}/icu"
-)
-
-LIST(REMOVE_ITEM JavaScriptCore_SOURCES
+list(REMOVE_ITEM JavaScriptCore_SOURCES
runtime/GCActivityCallback.cpp
)
-LIST(APPEND JavaScriptCore_SOURCES
+list(APPEND JavaScriptCore_SOURCES
runtime/GCActivityCallbackBlackBerry.cpp
- runtime/MemoryStatistics.cpp
)
-INSTALL(FILES "wtf/Forward.h" DESTINATION usr/include/browser/webkit/wtf)
+install(FILES "wtf/Forward.h" DESTINATION usr/include/browser/webkit/wtf)
diff --git a/Source/JavaScriptCore/PlatformEfl.cmake b/Source/JavaScriptCore/PlatformEfl.cmake
index 3b4115514..0a3688078 100644
--- a/Source/JavaScriptCore/PlatformEfl.cmake
+++ b/Source/JavaScriptCore/PlatformEfl.cmake
@@ -1,20 +1,4 @@
-LIST(APPEND JavaScriptCore_SOURCES
- jit/ExecutableAllocatorFixedVMPool.cpp
- jit/ExecutableAllocator.cpp
-
- runtime/MemoryStatistics.cpp
+list(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
+ ${ECORE_INCLUDE_DIRS}
+ ${EINA_INCLUDE_DIRS}
)
-
-LIST(APPEND JavaScriptCore_LIBRARIES
- ${ICU_I18N_LIBRARIES}
-)
-
-LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
- ${ICU_INCLUDE_DIRS}
-)
-
-IF (ENABLE_GLIB_SUPPORT)
- LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES
- ${JAVASCRIPTCORE_DIR}/wtf/gobject
- )
-ENDIF ()
diff --git a/Source/JavaScriptCore/PlatformWinCE.cmake b/Source/JavaScriptCore/PlatformWinCE.cmake
deleted file mode 100644
index e1a43ff93..000000000
--- a/Source/JavaScriptCore/PlatformWinCE.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-LIST(APPEND JavaScriptCore_SOURCES
- jit/ExecutableAllocator.cpp
-)
-
-IF (ENABLE_JIT AND WTF_CPU_ARM)
- ADD_CUSTOM_COMMAND(
- OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
- MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create_jit_stubs
- DEPENDS ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp
- COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_jit_stubs --prefix=MSVC ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp > ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
- VERBATIM)
-
- ADD_CUSTOM_COMMAND(
- OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj
- MAIN_DEPENDENCY ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm
- COMMAND armasm -nologo ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj
- VERBATIM)
-
- LIST (APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj)
-ENDIF ()
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri
index 0f2659ec9..12fd19ca6 100644
--- a/Source/JavaScriptCore/Target.pri
+++ b/Source/JavaScriptCore/Target.pri
@@ -40,7 +40,9 @@ SOURCES += \
API/JSClassRef.cpp \
API/JSContextRef.cpp \
API/JSObjectRef.cpp \
+ API/JSScriptRef.cpp \
API/JSStringRef.cpp \
+ API/JSStringRefQt.cpp \
API/JSValueRef.cpp \
API/JSWeakObjectMapRefPrivate.cpp \
API/OpaqueJSString.cpp \
@@ -49,7 +51,6 @@ SOURCES += \
assembler/LinkBuffer.cpp \
assembler/MacroAssembler.cpp \
assembler/MacroAssemblerARM.cpp \
- assembler/MacroAssemblerSH4.cpp \
bytecode/ArrayAllocationProfile.cpp \
bytecode/ArrayProfile.cpp \
bytecode/CallLinkInfo.cpp \
@@ -60,13 +61,16 @@ SOURCES += \
bytecode/CodeType.cpp \
bytecode/DFGExitProfile.cpp \
bytecode/ExecutionCounter.cpp \
+ bytecode/ExitKind.cpp \
bytecode/GetByIdStatus.cpp \
bytecode/JumpTable.cpp \
bytecode/LazyOperandValueProfile.cpp \
bytecode/MethodOfGettingAValueProfile.cpp \
bytecode/Opcode.cpp \
bytecode/PolymorphicPutByIdList.cpp \
+ bytecode/PreciseJumpTargets.cpp \
bytecode/PutByIdStatus.cpp \
+ bytecode/ReduceWhitespace.cpp \
bytecode/ResolveGlobalStatus.cpp \
bytecode/SamplingTool.cpp \
bytecode/SpecialPointer.cpp \
@@ -81,9 +85,10 @@ SOURCES += \
heap/CopyVisitor.cpp \
heap/ConservativeRoots.cpp \
heap/DFGCodeBlocks.cpp \
- heap/WeakSet.cpp \
- heap/WeakHandleOwner.cpp \
+ heap/Weak.cpp \
heap/WeakBlock.cpp \
+ heap/WeakHandleOwner.cpp \
+ heap/WeakSet.cpp \
heap/HandleSet.cpp \
heap/HandleStack.cpp \
heap/BlockAllocator.cpp \
@@ -100,6 +105,7 @@ SOURCES += \
heap/MarkedBlock.cpp \
heap/MarkedSpace.cpp \
heap/SlotVisitor.cpp \
+ heap/SuperRegion.cpp \
heap/VTableSpectrum.cpp \
heap/WriteBarrierSupport.cpp \
debugger/DebuggerActivation.cpp \
@@ -109,20 +115,26 @@ SOURCES += \
dfg/DFGArgumentsSimplificationPhase.cpp \
dfg/DFGArrayMode.cpp \
dfg/DFGAssemblyHelpers.cpp \
+ dfg/DFGBackwardsPropagationPhase.cpp \
dfg/DFGByteCodeParser.cpp \
dfg/DFGCapabilities.cpp \
+ dfg/DFGCommon.cpp \
dfg/DFGCFAPhase.cpp \
dfg/DFGCFGSimplificationPhase.cpp \
+ dfg/DFGCPSRethreadingPhase.cpp \
dfg/DFGConstantFoldingPhase.cpp \
- dfg/DFGCorrectableJumpPoint.cpp \
dfg/DFGCSEPhase.cpp \
+ dfg/DFGDCEPhase.cpp \
dfg/DFGDisassembler.cpp \
dfg/DFGDominators.cpp \
dfg/DFGDriver.cpp \
+ dfg/DFGEdge.cpp \
dfg/DFGFixupPhase.cpp \
dfg/DFGGraph.cpp \
dfg/DFGJITCompiler.cpp \
+ dfg/DFGLongLivedState.cpp \
dfg/DFGMinifiedNode.cpp \
+ dfg/DFGNode.cpp \
dfg/DFGNodeFlags.cpp \
dfg/DFGOperations.cpp \
dfg/DFGOSREntry.cpp \
@@ -130,14 +142,18 @@ SOURCES += \
dfg/DFGOSRExitCompiler.cpp \
dfg/DFGOSRExitCompiler64.cpp \
dfg/DFGOSRExitCompiler32_64.cpp \
+ dfg/DFGOSRExitJumpPlaceholder.cpp \
dfg/DFGPhase.cpp \
dfg/DFGPredictionPropagationPhase.cpp \
+ dfg/DFGPredictionInjectionPhase.cpp \
dfg/DFGRepatch.cpp \
dfg/DFGSpeculativeJIT.cpp \
dfg/DFGSpeculativeJIT32_64.cpp \
dfg/DFGSpeculativeJIT64.cpp \
- dfg/DFGStructureCheckHoistingPhase.cpp \
+ dfg/DFGTypeCheckHoistingPhase.cpp \
dfg/DFGThunks.cpp \
+ dfg/DFGUnificationPhase.cpp \
+ dfg/DFGUseKind.cpp \
dfg/DFGValueSource.cpp \
dfg/DFGVariableAccessDataDump.cpp \
dfg/DFGVariableEvent.cpp \
@@ -168,6 +184,7 @@ SOURCES += \
jit/JITPropertyAccess32_64.cpp \
jit/JITStubRoutine.cpp \
jit/JITStubs.cpp \
+ jit/JITThunks.cpp \
jit/JumpReplacementWatchpoint.cpp \
jit/ThunkGenerators.cpp \
llint/LLIntCLoop.cpp \
@@ -181,11 +198,33 @@ SOURCES += \
parser/Nodes.cpp \
parser/ParserArena.cpp \
parser/Parser.cpp \
+ parser/SourceProvider.cpp \
parser/SourceProviderCache.cpp \
+ profiler/ProfilerBytecode.cpp \
+ profiler/ProfilerBytecode.h \
+ profiler/ProfilerBytecodeSequence.cpp \
+ profiler/ProfilerBytecodes.cpp \
+ profiler/ProfilerBytecodes.h \
+ profiler/ProfilerCompilation.cpp \
+ profiler/ProfilerCompilation.h \
+ profiler/ProfilerCompilationKind.cpp \
+ profiler/ProfilerCompilationKind.h \
+ profiler/ProfilerCompiledBytecode.cpp \
+ profiler/ProfilerCompiledBytecode.h \
+ profiler/ProfilerDatabase.cpp \
+ profiler/ProfilerDatabase.h \
+ profiler/ProfilerExecutionCounter.h \
+ profiler/ProfilerOrigin.cpp \
+ profiler/ProfilerOrigin.h \
+ profiler/ProfilerOriginStack.cpp \
+ profiler/ProfilerOriginStack.h \
+ profiler/ProfilerOSRExit.cpp \
+ profiler/ProfilerOSRExitSite.cpp \
+ profiler/ProfilerProfiledBytecodes.cpp \
profiler/Profile.cpp \
profiler/ProfileGenerator.cpp \
profiler/ProfileNode.cpp \
- profiler/Profiler.cpp \
+ profiler/LegacyProfiler.cpp \
runtime/ArgList.cpp \
runtime/Arguments.cpp \
runtime/ArrayConstructor.cpp \
@@ -210,6 +249,7 @@ SOURCES += \
runtime/ExceptionHelpers.cpp \
runtime/Executable.cpp \
runtime/FunctionConstructor.cpp \
+ runtime/FunctionExecutableDump.cpp \
runtime/FunctionPrototype.cpp \
runtime/GCActivityCallback.cpp \
runtime/GetterSetter.cpp \
@@ -225,7 +265,7 @@ SOURCES += \
runtime/JSDateMath.cpp \
runtime/JSFunction.cpp \
runtime/JSBoundFunction.cpp \
- runtime/JSGlobalData.cpp \
+ runtime/VM.cpp \
runtime/JSGlobalObject.cpp \
runtime/JSGlobalObjectFunctions.cpp \
runtime/JSProxy.cpp \
@@ -241,7 +281,7 @@ SOURCES += \
runtime/JSString.cpp \
runtime/JSStringJoiner.cpp \
runtime/JSSymbolTableObject.cpp \
- runtime/JSValue.cpp \
+ runtime/JSCJSValue.cpp \
runtime/JSVariableObject.cpp \
runtime/JSWrapperObject.cpp \
runtime/LiteralParser.cpp \
@@ -262,6 +302,8 @@ SOURCES += \
runtime/PropertyDescriptor.cpp \
runtime/PropertyNameArray.cpp \
runtime/PropertySlot.cpp \
+ runtime/PropertyTable.cpp \
+ runtime/PrototypeMap.cpp \
runtime/RegExpConstructor.cpp \
runtime/RegExpCachedResult.cpp \
runtime/RegExpMatchesArray.cpp \
@@ -279,8 +321,10 @@ SOURCES += \
runtime/StringRecursionChecker.cpp \
runtime/StructureChain.cpp \
runtime/Structure.cpp \
+ runtime/StructureRareData.cpp \
runtime/SymbolTable.cpp \
- runtime/TimeoutChecker.cpp \
+ runtime/Watchdog.cpp \
+ runtime/WatchdogNone.cpp \
tools/CodeProfile.cpp \
tools/CodeProfiling.cpp \
yarr/YarrJIT.cpp \
@@ -310,17 +354,14 @@ win32:!win32-g++*:isEqual(QT_ARCH, "x86_64"):{
ASM_SOURCES += jit/JITStubsMSVC64.asm
}
+build?(qttestsupport) {
+ HEADERS += API/JSCTestRunnerUtils.h
+ SOURCES += API/JSCTestRunnerUtils.cpp
+}
+
HEADERS += $$files(*.h, true)
*sh4* {
QMAKE_CXXFLAGS += -mieee -w
QMAKE_CFLAGS += -mieee -w
}
-
-lessThan(QT_GCC_MAJOR_VERSION, 5) {
- # GCC 4.5 and before
- lessThan(QT_GCC_MINOR_VERSION, 6) {
- # Disable C++0x mode in JSC for those who enabled it in their Qt's mkspec.
- *-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x
- }
-}
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.cpp b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
index 6912d1ea3..4f4199bf2 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -391,14 +391,14 @@ void ARMAssembler::baseIndexTransferFloat(DataTransferTypeFloat transferType, FP
dataTransferFloat(transferType, srcDst, ARMRegisters::S1, offset);
}
-PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
+PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(VM& vm, 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, effort);
+ RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(vm, 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 31d316d0d..c950e47bb 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.h
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.h
@@ -107,21 +107,21 @@ namespace JSC {
// ARM conditional constants
typedef enum {
- EQ = 0x00000000, // Zero
- NE = 0x10000000, // Non-zero
- CS = 0x20000000,
- CC = 0x30000000,
- MI = 0x40000000,
- PL = 0x50000000,
- VS = 0x60000000,
- VC = 0x70000000,
- HI = 0x80000000,
- LS = 0x90000000,
- GE = 0xa0000000,
- LT = 0xb0000000,
- GT = 0xc0000000,
- LE = 0xd0000000,
- AL = 0xe0000000
+ EQ = 0x00000000, // Zero / Equal.
+ NE = 0x10000000, // Non-zero / Not equal.
+ CS = 0x20000000, // Unsigned higher or same.
+ CC = 0x30000000, // Unsigned lower.
+ MI = 0x40000000, // Negative.
+ PL = 0x50000000, // Positive or zero.
+ VS = 0x60000000, // Overflowed.
+ VC = 0x70000000, // Not overflowed.
+ HI = 0x80000000, // Unsigned higher.
+ LS = 0x90000000, // Unsigned lower or same.
+ GE = 0xa0000000, // Signed greater than or equal.
+ LT = 0xb0000000, // Signed less than.
+ GT = 0xc0000000, // Signed greater than.
+ LE = 0xd0000000, // Signed less than or equal.
+ AL = 0xe0000000 // Unconditional / Always execute.
} Condition;
// ARM instruction constants
@@ -760,7 +760,7 @@ namespace JSC {
return loadBranchTarget(ARMRegisters::pc, cc, useConstantPool);
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData&, void* ownerUID, JITCompilationEffort);
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM&, void* ownerUID, JITCompilationEffort);
unsigned debugOffset() { return m_buffer.debugOffset(); }
@@ -1022,29 +1022,46 @@ namespace JSC {
return AL | B | (offset & BranchOffsetMask);
}
+#if OS(LINUX) && COMPILER(GCC)
+ static inline void linuxPageFlush(uintptr_t begin, uintptr_t end)
+ {
+ asm volatile(
+ "push {r7}\n"
+ "mov r0, %0\n"
+ "mov r1, %1\n"
+ "mov r7, #0xf0000\n"
+ "add r7, r7, #0x2\n"
+ "mov r2, #0x0\n"
+ "svc 0x0\n"
+ "pop {r7}\n"
+ :
+ : "r" (begin), "r" (end)
+ : "r0", "r1", "r2");
+ }
+#endif
+
#if OS(LINUX) && COMPILER(RVCT)
static __asm void cacheFlush(void* code, size_t);
#else
static void cacheFlush(void* code, size_t size)
{
#if OS(LINUX) && COMPILER(GCC)
- uintptr_t currentPage = reinterpret_cast<uintptr_t>(code) & ~(pageSize() - 1);
- uintptr_t lastPage = (reinterpret_cast<uintptr_t>(code) + size) & ~(pageSize() - 1);
- do {
- asm volatile(
- "push {r7}\n"
- "mov r0, %0\n"
- "mov r1, %1\n"
- "mov r7, #0xf0000\n"
- "add r7, r7, #0x2\n"
- "mov r2, #0x0\n"
- "svc 0x0\n"
- "pop {r7}\n"
- :
- : "r" (currentPage), "r" (currentPage + pageSize())
- : "r0", "r1", "r2");
- currentPage += pageSize();
- } while (lastPage >= currentPage);
+ size_t page = pageSize();
+ uintptr_t current = reinterpret_cast<uintptr_t>(code);
+ uintptr_t end = current + size;
+ uintptr_t firstPageEnd = (current & ~(page - 1)) + page;
+
+ if (end <= firstPageEnd) {
+ linuxPageFlush(current, end);
+ return;
+ }
+
+ linuxPageFlush(current, firstPageEnd);
+
+ for (current = firstPageEnd; current + page < end; current += page)
+ linuxPageFlush(current, current + page);
+
+ linuxPageFlush(current, end);
#elif OS(WINCE)
CacheRangeFlush(code, size, CACHE_SYNC_ALL);
#elif OS(QNX) && ENABLE(ASSEMBLER_WX_EXCLUSIVE)
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index aa402e208..28989549d 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 University of Szeged
*
* Redistribution and use in source and binary forms, with or without
@@ -422,21 +422,21 @@ public:
// (HS, LO, HI, LS) -> (AE, B, A, BE)
// (VS, VC) -> (O, NO)
typedef enum {
- ConditionEQ,
- ConditionNE,
- ConditionHS, ConditionCS = ConditionHS,
- ConditionLO, ConditionCC = ConditionLO,
- ConditionMI,
- ConditionPL,
- ConditionVS,
- ConditionVC,
- ConditionHI,
- ConditionLS,
- ConditionGE,
- ConditionLT,
- ConditionGT,
- ConditionLE,
- ConditionAL,
+ ConditionEQ, // Zero / Equal.
+ ConditionNE, // Non-zero / Not equal.
+ ConditionHS, ConditionCS = ConditionHS, // Unsigned higher or same.
+ ConditionLO, ConditionCC = ConditionLO, // Unsigned lower.
+ ConditionMI, // Negative.
+ ConditionPL, // Positive or zero.
+ ConditionVS, // Overflowed.
+ ConditionVC, // Not overflowed.
+ ConditionHI, // Unsigned higher.
+ ConditionLS, // Unsigned lower or same.
+ ConditionGE, // Signed greater than or equal.
+ ConditionLT, // Signed less than.
+ ConditionGT, // Signed greater than.
+ ConditionLE, // Signed less than or equal.
+ ConditionAL, // Unconditional / Always execute.
ConditionInvalid
} Condition;
@@ -661,6 +661,10 @@ private:
OP_ROR_reg_T2 = 0xFA60,
OP_CLZ = 0xFAB0,
OP_SMULL_T1 = 0xFB80,
+#if CPU(APPLE_ARMV7S)
+ OP_SDIV_T1 = 0xFB90,
+ OP_UDIV_T1 = 0xFBB0,
+#endif
} OpcodeID1;
typedef enum {
@@ -1403,6 +1407,16 @@ public:
m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
}
+#if CPU(APPLE_ARMV7S)
+ ALWAYS_INLINE void sdiv(RegisterID rd, RegisterID rn, RegisterID rm)
+ {
+ ASSERT(!BadReg(rd));
+ ASSERT(!BadReg(rn));
+ ASSERT(!BadReg(rm));
+ m_formatter.twoWordOp12Reg4FourFours(OP_SDIV_T1, rn, FourFours(0xf, rd, 0xf, rm));
+ }
+#endif
+
ALWAYS_INLINE void smull(RegisterID rdLo, RegisterID rdHi, RegisterID rn, RegisterID rm)
{
ASSERT(!BadReg(rdLo));
@@ -1739,6 +1753,16 @@ public:
m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f);
}
+#if CPU(APPLE_ARMV7S)
+ ALWAYS_INLINE void udiv(RegisterID rd, RegisterID rn, RegisterID rm)
+ {
+ ASSERT(!BadReg(rd));
+ ASSERT(!BadReg(rn));
+ ASSERT(!BadReg(rm));
+ m_formatter.twoWordOp12Reg4FourFours(OP_UDIV_T1, rn, FourFours(0xf, rd, 0xf, rm));
+ }
+#endif
+
void vadd(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
{
m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm);
@@ -2011,7 +2035,7 @@ public:
offsets[ptr++] = offset;
}
- Vector<LinkRecord>& jumpsToLink()
+ Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink()
{
std::sort(m_jumpsToLink.begin(), m_jumpsToLink.end(), linkRecordSourceComparator);
return m_jumpsToLink;
@@ -2042,7 +2066,7 @@ public:
linkBX(reinterpret_cast_ptr<uint16_t*>(from), to);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
@@ -2202,7 +2226,7 @@ public:
cacheFlush(ptr, sizeof(uint16_t) * 2);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -2222,17 +2246,15 @@ public:
case OP_ADD_imm_T3:
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
unsigned debugOffset() { return m_formatter.debugOffset(); }
- static void cacheFlush(void* code, size_t size)
+#if OS(LINUX)
+ static inline void linuxPageFlush(uintptr_t begin, uintptr_t end)
{
-#if OS(IOS)
- sys_cache_control(kCacheFunctionPrepareForExecution, code, size);
-#elif OS(LINUX)
asm volatile(
"push {r7}\n"
"mov r0, %0\n"
@@ -2243,8 +2265,32 @@ public:
"svc 0x0\n"
"pop {r7}\n"
:
- : "r" (code), "r" (reinterpret_cast<char*>(code) + size)
+ : "r" (begin), "r" (end)
: "r0", "r1", "r2");
+ }
+#endif
+
+ static void cacheFlush(void* code, size_t size)
+ {
+#if OS(IOS)
+ sys_cache_control(kCacheFunctionPrepareForExecution, code, size);
+#elif OS(LINUX)
+ size_t page = pageSize();
+ uintptr_t current = reinterpret_cast<uintptr_t>(code);
+ uintptr_t end = current + size;
+ uintptr_t firstPageEnd = (current & ~(page - 1)) + page;
+
+ if (end <= firstPageEnd) {
+ linuxPageFlush(current, end);
+ return;
+ }
+
+ linuxPageFlush(current, firstPageEnd);
+
+ for (current = firstPageEnd; current + page < end; current += page)
+ linuxPageFlush(current, current + page);
+
+ linuxPageFlush(current, end);
#elif OS(WINCE)
CacheRangeFlush(code, size, CACHE_SYNC_ALL);
#elif OS(QNX)
@@ -2732,8 +2778,7 @@ private:
AssemblerBuffer m_buffer;
} m_formatter;
- Vector<LinkRecord> m_jumpsToLink;
- Vector<int32_t> m_offsets;
+ Vector<LinkRecord, 0, UnsafeVectorOverflow> m_jumpsToLink;
int m_indexOfLastWatchpoint;
int m_indexOfTailOfLastWatchpoint;
};
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 673031b7a..1861dc15c 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -31,7 +31,6 @@
#include "MacroAssemblerCodeRef.h"
#include <wtf/CryptographicallyRandomNumber.h>
#include <wtf/Noncopyable.h>
-#include <wtf/UnusedParam.h>
#if ENABLE(ASSEMBLER)
@@ -46,12 +45,30 @@
namespace JSC {
+inline bool isARMv7s()
+{
+#if CPU(APPLE_ARMV7S)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool isX86()
+{
+#if CPU(X86_64) || CPU(X86)
+ return true;
+#else
+ return false;
+#endif
+}
+
class JumpReplacementWatchpoint;
class LinkBuffer;
class RepatchBuffer;
class Watchpoint;
namespace DFG {
-class CorrectableJumpPoint;
+struct OSRExit;
}
template <class AssemblerType>
@@ -320,7 +337,7 @@ public:
class Label {
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
- friend class DFG::CorrectableJumpPoint;
+ friend struct DFG::OSRExit;
friend class Jump;
friend class JumpReplacementWatchpoint;
friend class MacroAssemblerCodeRef;
@@ -501,7 +518,7 @@ public:
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
friend class Call;
- friend class DFG::CorrectableJumpPoint;
+ friend struct DFG::OSRExit;
friend class LinkBuffer;
public:
Jump()
@@ -510,7 +527,7 @@ public:
#if CPU(ARM_THUMB2)
// Fixme: this information should be stored in the instruction stream, not in the Jump object.
- Jump(AssemblerLabel jmp, ARMv7Assembler::JumpType type, ARMv7Assembler::Condition condition = ARMv7Assembler::ConditionInvalid)
+ Jump(AssemblerLabel jmp, ARMv7Assembler::JumpType type = ARMv7Assembler::JumpNoCondition, ARMv7Assembler::Condition condition = ARMv7Assembler::ConditionInvalid)
: m_label(jmp)
, m_type(type)
, m_condition(condition)
@@ -528,9 +545,20 @@ public:
{
}
#endif
+
+ Label label() const
+ {
+ Label result;
+ result.m_label = m_label;
+ return result;
+ }
void link(AbstractMacroAssembler<AssemblerType>* masm) const
{
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ masm->checkRegisterAllocationAgainstBranchRange(m_label.m_offset, masm->debugOffset());
+#endif
+
#if CPU(ARM_THUMB2)
masm->m_assembler.linkJump(m_label, masm->m_assembler.label(), m_type, m_condition);
#elif CPU(SH4)
@@ -542,6 +570,10 @@ public:
void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
{
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ masm->checkRegisterAllocationAgainstBranchRange(label.m_label.m_offset, m_label.m_offset);
+#endif
+
#if CPU(ARM_THUMB2)
masm->m_assembler.linkJump(m_label, label.m_label, m_type, m_condition);
#else
@@ -585,7 +617,7 @@ public:
friend class LinkBuffer;
public:
- typedef Vector<Jump, 16> JumpVector;
+ typedef Vector<Jump, 2> JumpVector;
JumpList() { }
@@ -676,6 +708,44 @@ public:
return Label(this);
}
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ class RegisterAllocationOffset {
+ public:
+ RegisterAllocationOffset(unsigned offset)
+ : m_offset(offset)
+ {
+ }
+
+ void check(unsigned low, unsigned high)
+ {
+ RELEASE_ASSERT_WITH_MESSAGE(!(low <= m_offset && m_offset <= high), "Unsafe branch over register allocation at instruction offset %u in jump offset range %u..%u", m_offset, low, high);
+ }
+
+ private:
+ unsigned m_offset;
+ };
+
+ void addRegisterAllocationAtOffset(unsigned offset)
+ {
+ m_registerAllocationForOffsets.append(RegisterAllocationOffset(offset));
+ }
+
+ void clearRegisterAllocationOffsets()
+ {
+ m_registerAllocationForOffsets.clear();
+ }
+
+ void checkRegisterAllocationAgainstBranchRange(unsigned offset1, unsigned offset2)
+ {
+ if (offset1 > offset2)
+ std::swap(offset1, offset2);
+
+ size_t size = m_registerAllocationForOffsets.size();
+ for (size_t i = 0; i < size; ++i)
+ m_registerAllocationForOffsets[i].check(offset1, offset2);
+ }
+#endif
+
template<typename T, typename U>
static ptrdiff_t differenceBetween(T from, U to)
{
@@ -708,6 +778,10 @@ protected:
WeakRandom m_randomSource;
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ Vector<RegisterAllocationOffset, 10> m_registerAllocationForOffsets;
+#endif
+
#if ENABLE(JIT_CONSTANT_BLINDING)
static bool scratchRegisterForBlinding() { return false; }
static bool shouldBlindForSpecificArch(uint32_t) { return true; }
diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.h b/Source/JavaScriptCore/assembler/AssemblerBuffer.h
index 6bc1b3924..d82c0b946 100644
--- a/Source/JavaScriptCore/assembler/AssemblerBuffer.h
+++ b/Source/JavaScriptCore/assembler/AssemblerBuffer.h
@@ -30,7 +30,7 @@
#include "ExecutableAllocator.h"
#include "JITCompilationEffort.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "stdint.h"
#include <string.h>
#include <wtf/Assertions.h>
@@ -130,12 +130,12 @@ namespace JSC {
return AssemblerLabel(m_index);
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
{
if (!m_index)
return 0;
- RefPtr<ExecutableMemoryHandle> result = globalData.executableAllocator.allocate(globalData, m_index, ownerUID, effort);
+ RefPtr<ExecutableMemoryHandle> result = vm.executableAllocator.allocate(vm, m_index, ownerUID, effort);
if (!result)
return 0;
@@ -168,7 +168,7 @@ namespace JSC {
}
private:
- Vector<char, inlineCapacity> m_storage;
+ Vector<char, inlineCapacity, UnsafeVectorOverflow> m_storage;
char* m_buffer;
int m_capacity;
int m_index;
diff --git a/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h b/Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
index 5377ef0c7..852f86df7 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, JITCompilationEffort effort)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
{
flushConstantPool(false);
- return AssemblerBuffer::executableCopy(globalData, ownerUID, effort);
+ return AssemblerBuffer::executableCopy(vm, ownerUID, effort);
}
void putShortWithConstantInt(uint16_t insn, uint32_t constant, bool isReusable = false)
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.cpp b/Source/JavaScriptCore/assembler/LinkBuffer.cpp
index c269157ba..cd393be65 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.cpp
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.cpp
@@ -62,7 +62,7 @@ void LinkBuffer::linkCode(void* ownerUID, JITCompilationEffort effort)
{
ASSERT(!m_code);
#if !ENABLE(BRANCH_COMPACTION)
- m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
+ m_executableMemory = m_assembler->m_assembler.executableCopy(*m_vm, ownerUID, effort);
if (!m_executableMemory)
return;
m_code = m_executableMemory->start();
@@ -70,7 +70,7 @@ void LinkBuffer::linkCode(void* ownerUID, JITCompilationEffort effort)
ASSERT(m_code);
#else
m_initialSize = m_assembler->m_assembler.codeSize();
- m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
+ m_executableMemory = m_vm->executableAllocator.allocate(*m_vm, m_initialSize, ownerUID, effort);
if (!m_executableMemory)
return;
m_code = (uint8_t*)m_executableMemory->start();
@@ -80,7 +80,7 @@ void LinkBuffer::linkCode(void* ownerUID, JITCompilationEffort effort)
uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
int readPtr = 0;
int writePtr = 0;
- Vector<LinkRecord>& jumpsToLink = m_assembler->jumpsToLink();
+ Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink = m_assembler->jumpsToLink();
unsigned jumpCount = jumpsToLink.size();
for (unsigned i = 0; i < jumpCount; ++i) {
int offset = readPtr - writePtr;
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index e1882433c..52630fe50 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -41,7 +41,7 @@
namespace JSC {
-class JSGlobalData;
+class VM;
// LinkBuffer:
//
@@ -76,14 +76,14 @@ class LinkBuffer {
#endif
public:
- LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
+ LinkBuffer(VM& vm, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
: m_size(0)
#if ENABLE(BRANCH_COMPACTION)
, m_initialSize(0)
#endif
, m_code(0)
, m_assembler(masm)
- , m_globalData(&globalData)
+ , m_vm(&vm)
#ifndef NDEBUG
, m_completed(false)
, m_effort(effort)
@@ -256,7 +256,7 @@ private:
#endif
void* m_code;
MacroAssembler* m_assembler;
- JSGlobalData* m_globalData;
+ VM* m_vm;
#ifndef NDEBUG
bool m_completed;
JITCompilationEffort m_effort;
diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
index 7f553bb9a..5f7b9b21a 100644
--- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
@@ -676,9 +676,9 @@ public:
return m_buffer.codeSize();
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
{
- RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID, effort);
+ RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(vm, ownerUID, effort);
if (!result)
return 0;
diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
index 2f26ff281..f74680d7f 100644
--- a/Source/JavaScriptCore/assembler/MacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
@@ -121,7 +121,7 @@ public:
case DoubleLessThanOrEqualOrUnordered:
return DoubleGreaterThan;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return DoubleEqual; // make compiler happy
}
}
@@ -145,7 +145,7 @@ public:
case NonZero:
return Zero;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return Zero; // Make compiler happy for release builds.
}
}
@@ -854,7 +854,7 @@ public:
bool shouldBlindDouble(double value)
{
// Don't trust NaN or +/-Infinity
- if (!isfinite(value))
+ if (!std::isfinite(value))
return shouldConsiderBlinding();
// Try to force normalisation, and check that there's no change
@@ -876,7 +876,7 @@ public:
bool shouldBlind(ImmPtr imm)
{
-#if !defined(NDEBUG)
+#if ENABLE(FORCED_JIT_BLINDING)
UNUSED_PARAM(imm);
// Debug always blind all constants, if only so we know
// if we've broken blinding during patch development.
@@ -934,8 +934,8 @@ public:
}
bool shouldBlind(Imm64 imm)
- {
-#if !defined(NDEBUG)
+ {
+#if ENABLE(FORCED_JIT_BLINDING)
UNUSED_PARAM(imm);
// Debug always blind all constants, if only so we know
// if we've broken blinding during patch development.
@@ -1073,8 +1073,8 @@ public:
#if ENABLE(JIT_CONSTANT_BLINDING)
bool shouldBlind(Imm32 imm)
- {
-#if !defined(NDEBUG)
+ {
+#if ENABLE(FORCED_JIT_BLINDING)
UNUSED_PARAM(imm);
// Debug always blind all constants, if only so we know
// if we've broken blinding during patch development.
@@ -1357,12 +1357,9 @@ public:
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 (src == dest)
+ ASSERT(scratchRegisterForBlinding());
+
if (shouldBlind(imm)) {
if (src == dest) {
if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
@@ -1378,12 +1375,9 @@ public:
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 (src == dest)
+ ASSERT(scratchRegisterForBlinding());
+
if (shouldBlind(imm)) {
if (src == dest) {
if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index c5ea9c542..494fe640d 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -58,6 +58,7 @@ public:
enum ResultCondition {
Overflow = ARMAssembler::VS,
Signed = ARMAssembler::MI,
+ PositiveOrZero = ARMAssembler::PL,
Zero = ARMAssembler::EQ,
NonZero = ARMAssembler::NE
};
@@ -152,6 +153,12 @@ public:
m_assembler.bitAnds(dest, src, w);
}
+ void and32(Address src, RegisterID dest)
+ {
+ load32(src, ARMRegisters::S1);
+ and32(ARMRegisters::S1, dest);
+ }
+
void lshift32(RegisterID shiftAmount, RegisterID dest)
{
lshift32(dest, shiftAmount, dest);
@@ -342,7 +349,7 @@ public:
#else
UNUSED_PARAM(src);
UNUSED_PARAM(dest);
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif
}
@@ -445,10 +452,10 @@ public:
m_assembler.baseIndexTransfer32(ARMAssembler::StoreUint8, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
}
- void store8(TrustedImm32 imm, void* address)
+ void store8(TrustedImm32 imm, const void* address)
{
move(TrustedImm32(reinterpret_cast<ARMWord>(address)), ARMRegisters::S0);
- m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
+ move(imm, ARMRegisters::S1);
m_assembler.dtrUp(ARMAssembler::StoreUint8, ARMRegisters::S1, ARMRegisters::S0, 0);
}
@@ -479,13 +486,13 @@ public:
m_assembler.baseIndexTransfer32(ARMAssembler::StoreUint32, ARMRegisters::S1, address.base, address.index, static_cast<int>(address.scale), address.offset);
}
- void store32(RegisterID src, void* address)
+ void store32(RegisterID src, const void* address)
{
m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
m_assembler.dtrUp(ARMAssembler::StoreUint32, src, ARMRegisters::S0, 0);
}
- void store32(TrustedImm32 imm, void* address)
+ void store32(TrustedImm32 imm, const void* address)
{
m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
@@ -532,9 +539,9 @@ public:
void swap(RegisterID reg1, RegisterID reg2)
{
- m_assembler.mov(ARMRegisters::S0, reg1);
- m_assembler.mov(reg1, reg2);
- m_assembler.mov(reg2, ARMRegisters::S0);
+ xor32(reg1, reg2);
+ xor32(reg2, reg1);
+ xor32(reg1, reg2);
}
void signExtend32ToPtr(RegisterID src, RegisterID dest)
@@ -680,35 +687,40 @@ public:
Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero)
+ || (cond == NonZero) || (cond == PositiveOrZero));
add32(src, dest);
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero)
+ || (cond == NonZero) || (cond == PositiveOrZero));
add32(op1, op2, dest);
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero)
+ || (cond == NonZero) || (cond == PositiveOrZero));
add32(imm, dest);
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));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero)
+ || (cond == NonZero) || (cond == PositiveOrZero));
add32(src, imm, dest);
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero)
+ || (cond == NonZero) || (cond == PositiveOrZero));
add32(imm, dest);
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
@@ -885,20 +897,41 @@ public:
void add32(TrustedImm32 imm, AbsoluteAddress address)
{
- m_assembler.ldrUniqueImmediate(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
- m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S1, ARMRegisters::S1, 0);
+ load32(address.m_ptr, ARMRegisters::S1);
add32(imm, ARMRegisters::S1);
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr));
- m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S1, ARMRegisters::S0, 0);
+ store32(ARMRegisters::S1, address.m_ptr);
+ }
+
+ void add64(TrustedImm32 imm, AbsoluteAddress address)
+ {
+ ARMWord tmp;
+
+ move(TrustedImmPtr(address.m_ptr), ARMRegisters::S1);
+ m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S0, ARMRegisters::S1, 0);
+
+ if ((tmp = ARMAssembler::getOp2(imm.m_value)) != ARMAssembler::InvalidImmediate)
+ m_assembler.adds(ARMRegisters::S0, ARMRegisters::S0, tmp);
+ else if ((tmp = ARMAssembler::getOp2(-imm.m_value)) != ARMAssembler::InvalidImmediate)
+ m_assembler.subs(ARMRegisters::S0, ARMRegisters::S0, tmp);
+ else {
+ m_assembler.adds(ARMRegisters::S0, ARMRegisters::S0, m_assembler.getImm(imm.m_value, ARMRegisters::S1));
+ move(TrustedImmPtr(address.m_ptr), ARMRegisters::S1);
+ }
+ m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S0, ARMRegisters::S1, 0);
+
+ m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S0, ARMRegisters::S1, sizeof(ARMWord));
+ if (imm.m_value >= 0)
+ m_assembler.adc(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
+ else
+ m_assembler.sbc(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
+ m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S0, ARMRegisters::S1, sizeof(ARMWord));
}
void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
- m_assembler.ldrUniqueImmediate(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
- m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S1, ARMRegisters::S1, 0);
+ load32(address.m_ptr, ARMRegisters::S1);
sub32(imm, ARMRegisters::S1);
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr));
- m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S1, ARMRegisters::S0, 0);
+ store32(ARMRegisters::S1, address.m_ptr);
}
void load32(const void* address, RegisterID dest)
@@ -1080,7 +1113,7 @@ public:
void divDouble(Address src, FPRegisterID dest)
{
- ASSERT_NOT_REACHED(); // Untested
+ RELEASE_ASSERT_NOT_REACHED(); // Untested
loadDouble(src, ARMRegisters::SD0);
divDouble(ARMRegisters::SD0, dest);
}
@@ -1216,7 +1249,7 @@ public:
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
// (specifically, in this case, 0).
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true)
{
m_assembler.vcvt_s32_f64(ARMRegisters::SD0 << 1, src);
m_assembler.vmov_arm32(dest, ARMRegisters::SD0 << 1);
@@ -1226,7 +1259,8 @@ public:
failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, ARMRegisters::SD0));
// If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
- failureCases.append(branchTest32(Zero, dest));
+ if (negZeroCheck)
+ failureCases.append(branchTest32(Zero, dest));
}
Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 06d0e1534..b1bc41729 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -59,7 +59,7 @@ public:
return value >= -255 && value <= 255;
}
- Vector<LinkRecord>& jumpsToLink() { return m_assembler.jumpsToLink(); }
+ Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink() { return m_assembler.jumpsToLink(); }
void* unlinkedCode() { return m_assembler.unlinkedCode(); }
bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); }
JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(jumpType, from, to); }
@@ -119,6 +119,7 @@ public:
enum ResultCondition {
Overflow = ARMv7Assembler::ConditionVS,
Signed = ARMv7Assembler::ConditionMI,
+ PositiveOrZero = ARMv7Assembler::ConditionPL,
Zero = ARMv7Assembler::ConditionEQ,
NonZero = ARMv7Assembler::ConditionNE
};
@@ -263,6 +264,12 @@ public:
and32(imm, dest, dest);
}
+ void and32(Address src, RegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ and32(dataTempRegister, dest);
+ }
+
void countLeadingZeros32(RegisterID src, RegisterID dest)
{
m_assembler.clz(dest, src);
@@ -1097,7 +1104,7 @@ public:
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
// (specifically, in this case, 0).
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true)
{
m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src);
m_assembler.vmov(dest, fpTempRegisterAsSingle());
@@ -1107,7 +1114,8 @@ public:
failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister));
// If the result is zero, it might have been -0.0, and the double comparison won't catch this!
- failureCases.append(branchTest32(Zero, dest));
+ if (negZeroCheck)
+ failureCases.append(branchTest32(Zero, dest));
}
Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
index c2af24060..ec16659d5 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
@@ -32,7 +32,6 @@
#include <wtf/DataLog.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).
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index f5298a0ab..298a25c29 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -80,6 +80,7 @@ public:
enum ResultCondition {
Overflow,
Signed,
+ PositiveOrZero,
Zero,
NonZero
};
@@ -233,22 +234,46 @@ public:
/*
li addrTemp, address
li immTemp, imm
- lw dataTemp, 0(addrTemp)
- addu dataTemp, dataTemp, immTemp
+ lw cmpTemp, 0(addrTemp)
+ addu dataTemp, cmpTemp, immTemp
sw dataTemp, 0(addrTemp)
*/
move(TrustedImmPtr(address.m_ptr), addrTempRegister);
- m_assembler.lw(dataTempRegister, addrTempRegister, 0);
- if (imm.m_value >= -32768 && imm.m_value <= 32767
- && !m_fixedWidth)
- m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value);
+ m_assembler.lw(cmpTempRegister, addrTempRegister, 0);
+ if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth)
+ m_assembler.addiu(dataTempRegister, cmpTempRegister, imm.m_value);
else {
move(imm, immTempRegister);
- m_assembler.addu(dataTempRegister, dataTempRegister, immTempRegister);
+ m_assembler.addu(dataTempRegister, cmpTempRegister, immTempRegister);
}
m_assembler.sw(dataTempRegister, addrTempRegister, 0);
}
+ void add64(TrustedImm32 imm, AbsoluteAddress address)
+ {
+ /*
+ add32(imm, address)
+ sltu immTemp, dataTemp, cmpTemp # set carry-in bit
+ lw dataTemp, 4(addrTemp)
+ addiu dataTemp, imm.m_value >> 31 ? -1 : 0
+ addu dataTemp, dataTemp, immTemp
+ sw dataTemp, 4(addrTemp)
+ */
+ add32(imm, address);
+ m_assembler.sltu(immTempRegister, dataTempRegister, cmpTempRegister);
+ m_assembler.lw(dataTempRegister, addrTempRegister, 4);
+ if (imm.m_value >> 31)
+ m_assembler.addiu(dataTempRegister, dataTempRegister, -1);
+ m_assembler.addu(dataTempRegister, dataTempRegister, immTempRegister);
+ m_assembler.sw(dataTempRegister, addrTempRegister, 4);
+ }
+
+ void and32(Address src, RegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ and32(dataTempRegister, dest);
+ }
+
void and32(RegisterID src, RegisterID dest)
{
m_assembler.andInsn(dest, dest, src);
@@ -596,7 +621,7 @@ public:
void absDouble(FPRegisterID, FPRegisterID)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
@@ -1485,7 +1510,7 @@ public:
Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
if (cond == Overflow) {
/*
move dest, dataTemp
@@ -1518,6 +1543,12 @@ public:
m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
}
+ if (cond == PositiveOrZero) {
+ add32(src, dest);
+ // Check if dest is not negative.
+ m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+ return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+ }
if (cond == Zero) {
add32(src, dest);
return branchEqual(dest, MIPSRegisters::zero);
@@ -1532,7 +1563,7 @@ public:
Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
if (cond == Overflow) {
/*
move dataTemp, op1
@@ -1565,6 +1596,12 @@ public:
m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
}
+ if (cond == PositiveOrZero) {
+ add32(op1, op2, dest);
+ // Check if dest is not negative.
+ m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+ return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+ }
if (cond == Zero) {
add32(op1, op2, dest);
return branchEqual(dest, MIPSRegisters::zero);
@@ -1592,7 +1629,7 @@ public:
Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
if (cond == Overflow) {
/*
move dataTemp, dest
@@ -1642,6 +1679,11 @@ public:
m_assembler.slt(cmpTempRegister, dataTempRegister, MIPSRegisters::zero);
return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
}
+ if (cond == PositiveOrZero) {
+ // Check if dest is not negative.
+ m_assembler.slt(cmpTempRegister, dataTempRegister, MIPSRegisters::zero);
+ return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+ }
if (cond == Zero)
return branchEqual(dataTempRegister, MIPSRegisters::zero);
if (cond == NonZero)
@@ -2598,13 +2640,14 @@ public:
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
// (specifically, in this case, 0).
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true)
{
m_assembler.cvtwd(fpTempRegister, src);
m_assembler.mfc1(dest, fpTempRegister);
// If the result is zero, it might have been -0.0, and the double comparison won't catch this!
- failureCases.append(branch32(Equal, dest, MIPSRegisters::zero));
+ if (negZeroCheck)
+ failureCases.append(branch32(Equal, dest, MIPSRegisters::zero));
// Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
convertInt32ToDouble(dest, fpTemp);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
index 0c7fe12c6..ad5acfaeb 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
* Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
@@ -40,7 +41,7 @@ public:
typedef SH4Assembler::FPRegisterID FPRegisterID;
static const Scale ScalePtr = TimesFour;
- static const FPRegisterID fscratch = SH4Registers::fr10;
+ static const FPRegisterID fscratch = SH4Registers::dr10;
static const RegisterID stackPointerRegister = SH4Registers::sp;
static const RegisterID linkRegister = SH4Registers::pr;
static const RegisterID scratchReg3 = SH4Registers::r13;
@@ -49,7 +50,7 @@ public:
static bool isCompactPtrAlignedAddressOffset(ptrdiff_t value)
{
- return (value >= 0) && (value <= MaximumCompactPtrAlignedAddressOffset);
+ return (value >= 0) && (value <= MaximumCompactPtrAlignedAddressOffset) && (!(value & 3));
}
enum RelationalCondition {
@@ -68,6 +69,7 @@ public:
enum ResultCondition {
Overflow = SH4Assembler::OF,
Signed = SH4Assembler::SI,
+ PositiveOrZero = SH4Assembler::NS,
Zero = SH4Assembler::EQ,
NonZero = SH4Assembler::NE
};
@@ -99,6 +101,34 @@ public:
m_assembler.releaseScratch(reg);
}
+ static RelationalCondition invert(RelationalCondition cond)
+ {
+ switch (cond) {
+ case Equal:
+ return NotEqual;
+ case NotEqual:
+ return Equal;
+ case Above:
+ return BelowOrEqual;
+ case AboveOrEqual:
+ return Below;
+ case Below:
+ return AboveOrEqual;
+ case BelowOrEqual:
+ return Above;
+ case GreaterThan:
+ return LessThanOrEqual;
+ case GreaterThanOrEqual:
+ return LessThan;
+ case LessThan:
+ return GreaterThanOrEqual;
+ case LessThanOrEqual:
+ return GreaterThan;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+
// Integer arithmetic operations
void add32(RegisterID src, RegisterID dest)
@@ -106,8 +136,21 @@ public:
m_assembler.addlRegReg(src, dest);
}
+ void add32(RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ if (src1 == dest)
+ add32(src2, dest);
+ else {
+ move(src2, dest);
+ add32(src1, dest);
+ }
+ }
+
void add32(TrustedImm32 imm, RegisterID dest)
{
+ if (!imm.m_value)
+ return;
+
if (m_assembler.isImmediate(imm.m_value)) {
m_assembler.addlImm8r(imm.m_value, dest);
return;
@@ -121,13 +164,15 @@ public:
void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
- if (src != dest)
- m_assembler.movlRegReg(src, dest);
+ move(src, dest);
add32(imm, dest);
}
void add32(TrustedImm32 imm, Address address)
{
+ if (!imm.m_value)
+ return;
+
RegisterID scr = claimScratch();
load32(address, scr);
add32(imm, scr);
@@ -156,15 +201,38 @@ public:
m_assembler.andlRegReg(src, dest);
}
+ void and32(RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ if (src1 == dest)
+ and32(src2, dest);
+ else {
+ move(src2, dest);
+ and32(src1, dest);
+ }
+ }
+
+ void and32(Address src, RegisterID dest)
+ {
+ RegisterID scr = claimScratch();
+ load32(src, scr);
+ and32(scr, dest);
+ releaseScratch(scr);
+ }
+
void and32(TrustedImm32 imm, RegisterID dest)
{
+ if (!imm.m_value) {
+ m_assembler.movImm8(0, dest);
+ return;
+ }
+
if ((imm.m_value <= 255) && (imm.m_value >= 0) && (dest == SH4Registers::r0)) {
m_assembler.andlImm8r(imm.m_value, dest);
return;
}
RegisterID scr = claimScratch();
- m_assembler.loadConstant((imm.m_value), scr);
+ m_assembler.loadConstant(imm.m_value, scr);
m_assembler.andlRegReg(scr, dest);
releaseScratch(scr);
}
@@ -182,63 +250,64 @@ public:
void lshift32(RegisterID shiftamount, RegisterID dest)
{
- if (shiftamount == SH4Registers::r0)
- m_assembler.andlImm8r(0x1f, shiftamount);
- else {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(0x1f, scr);
- m_assembler.andlRegReg(scr, shiftamount);
- releaseScratch(scr);
- }
- m_assembler.shllRegReg(dest, shiftamount);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(0x1f, shiftTmp);
+ m_assembler.andlRegReg(shiftamount, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
- void rshift32(int imm, RegisterID dest)
+ void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
{
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(-imm, scr);
- m_assembler.shaRegReg(dest, scr);
- releaseScratch(scr);
+ move(src, dest);
+ lshift32(shiftAmount, dest);
}
void lshift32(TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_value)
+ int immMasked = imm.m_value & 0x1f;
+ if (!immMasked)
return;
- if ((imm.m_value == 1) || (imm.m_value == 2) || (imm.m_value == 8) || (imm.m_value == 16)) {
- m_assembler.shllImm8r(imm.m_value, dest);
+ if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) {
+ m_assembler.shllImm8r(immMasked, dest);
return;
}
- RegisterID scr = claimScratch();
- m_assembler.loadConstant((imm.m_value & 0x1f) , scr);
- m_assembler.shllRegReg(dest, scr);
- releaseScratch(scr);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(immMasked, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void lshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
{
- if (src != dest)
- move(src, dest);
-
+ move(src, dest);
lshift32(shiftamount, dest);
}
void mul32(RegisterID src, RegisterID dest)
{
- m_assembler.imullRegReg(src, dest);
+ mul32(src, dest, dest);
+ }
+
+ void mul32(RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ m_assembler.imullRegReg(src1, src2);
m_assembler.stsmacl(dest);
}
void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
- RegisterID scr = claimScratch();
- move(imm, scr);
- if (src != dest)
- move(src, dest);
- mul32(scr, dest);
- releaseScratch(scr);
+ if (src == dest) {
+ RegisterID immval = claimScratch();
+ move(imm, immval);
+ mul32(immval, dest);
+ releaseScratch(immval);
+ } else {
+ move(imm, dest);
+ mul32(src, dest);
+ }
}
void or32(RegisterID src, RegisterID dest)
@@ -271,10 +340,9 @@ public:
}
}
-
-void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
- if (src != dest) {
+ if (src != dest) {
move(imm, dest);
or32(src, dest);
return;
@@ -283,9 +351,21 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
or32(imm, dest);
}
+ void or32(RegisterID src, AbsoluteAddress address)
+ {
+ RegisterID destptr = claimScratch();
+ move(TrustedImmPtr(address.m_ptr), destptr);
+ RegisterID destval = claimScratch();
+ m_assembler.movlMemReg(destptr, destval);
+ m_assembler.orlRegReg(src, destval);
+ m_assembler.movlRegMem(destval, destptr);
+ releaseScratch(destval);
+ releaseScratch(destptr);
+ }
+
void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
- if (src != dest) {
+ if (src != dest) {
move(imm, dest);
xor32(src, dest);
return;
@@ -296,28 +376,40 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void rshift32(RegisterID shiftamount, RegisterID dest)
{
- if (shiftamount == SH4Registers::r0)
- m_assembler.andlImm8r(0x1f, shiftamount);
- else {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(0x1f, scr);
- m_assembler.andlRegReg(scr, shiftamount);
- releaseScratch(scr);
- }
- m_assembler.neg(shiftamount, shiftamount);
- m_assembler.shaRegReg(dest, shiftamount);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(0x1f, shiftTmp);
+ m_assembler.andlRegReg(shiftamount, shiftTmp);
+ m_assembler.neg(shiftTmp, shiftTmp);
+ m_assembler.shadRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
+ }
+
+ void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
+ {
+ move(src, dest);
+ rshift32(shiftAmount, dest);
}
void rshift32(TrustedImm32 imm, RegisterID dest)
{
- if (imm.m_value & 0x1f)
- rshift32(imm.m_value & 0x1f, dest);
+ int immMasked = imm.m_value & 0x1f;
+ if (!immMasked)
+ return;
+
+ if (immMasked == 1) {
+ m_assembler.sharImm8r(immMasked, dest);
+ return;
+ }
+
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(-immMasked, shiftTmp);
+ m_assembler.shadRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
{
- if (src != dest)
- move(src, dest);
+ move(src, dest);
rshift32(imm, dest);
}
@@ -326,30 +418,15 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.sublRegReg(src, dest);
}
- void sub32(TrustedImm32 imm, AbsoluteAddress address, RegisterID scratchReg)
- {
- RegisterID result = claimScratch();
-
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
- m_assembler.movlMemReg(scratchReg, result);
-
- if (m_assembler.isImmediate(-imm.m_value))
- m_assembler.addlImm8r(-imm.m_value, result);
- else {
- m_assembler.loadConstant(imm.m_value, scratchReg3);
- m_assembler.sublRegReg(scratchReg3, result);
- }
-
- store32(result, scratchReg);
- releaseScratch(result);
- }
-
void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
+ if (!imm.m_value)
+ return;
+
RegisterID result = claimScratch();
RegisterID scratchReg = claimScratch();
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
+ move(TrustedImmPtr(address.m_ptr), scratchReg);
m_assembler.movlMemReg(scratchReg, result);
if (m_assembler.isImmediate(-imm.m_value))
@@ -364,30 +441,20 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scratchReg);
}
- void add32(TrustedImm32 imm, AbsoluteAddress address, RegisterID scratchReg)
+ void sub32(TrustedImm32 imm, Address address)
{
- RegisterID result = claimScratch();
-
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
- m_assembler.movlMemReg(scratchReg, result);
-
- if (m_assembler.isImmediate(imm.m_value))
- m_assembler.addlImm8r(imm.m_value, result);
- else {
- m_assembler.loadConstant(imm.m_value, scratchReg3);
- m_assembler.addlRegReg(scratchReg3, result);
- }
-
- store32(result, scratchReg);
- releaseScratch(result);
+ add32(TrustedImm32(-imm.m_value), address);
}
void add32(TrustedImm32 imm, AbsoluteAddress address)
{
+ if (!imm.m_value)
+ return;
+
RegisterID result = claimScratch();
RegisterID scratchReg = claimScratch();
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg);
+ move(TrustedImmPtr(address.m_ptr), scratchReg);
m_assembler.movlMemReg(scratchReg, result);
if (m_assembler.isImmediate(imm.m_value))
@@ -402,8 +469,37 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scratchReg);
}
+ void add64(TrustedImm32 imm, AbsoluteAddress address)
+ {
+ RegisterID scr1 = claimScratch();
+ RegisterID scr2 = claimScratch();
+
+ // Add 32-bit LSB first.
+ move(TrustedImmPtr(address.m_ptr), scratchReg3);
+ m_assembler.movlMemReg(scratchReg3, scr1); // scr1 = 32-bit LSB of int64 @ address
+ m_assembler.loadConstant(imm.m_value, scr2);
+ m_assembler.clrt();
+ m_assembler.addclRegReg(scr1, scr2);
+ m_assembler.movlRegMem(scr2, scratchReg3); // Update address with 32-bit LSB result.
+
+ // Then add 32-bit MSB.
+ m_assembler.addlImm8r(4, scratchReg3);
+ m_assembler.movlMemReg(scratchReg3, scr1); // scr1 = 32-bit MSB of int64 @ address
+ m_assembler.movt(scr2);
+ if (imm.m_value < 0)
+ m_assembler.addlImm8r(-1, scr2); // Sign extend imm value if needed.
+ m_assembler.addvlRegReg(scr2, scr1);
+ m_assembler.movlRegMem(scr1, scratchReg3); // Update (address + 4) with 32-bit MSB result.
+
+ releaseScratch(scr2);
+ releaseScratch(scr1);
+ }
+
void sub32(TrustedImm32 imm, RegisterID dest)
{
+ if (!imm.m_value)
+ return;
+
if (m_assembler.isImmediate(-imm.m_value)) {
m_assembler.addlImm8r(-imm.m_value, dest);
return;
@@ -428,6 +524,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.xorlRegReg(src, dest);
}
+ void xor32(RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ if (src1 == dest)
+ xor32(src2, dest);
+ else {
+ move(src2, dest);
+ xor32(src1, dest);
+ }
+ }
+
void xor32(TrustedImm32 imm, RegisterID srcDest)
{
if (imm.m_value == -1) {
@@ -437,7 +543,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) {
RegisterID scr = claimScratch();
- m_assembler.loadConstant((imm.m_value), scr);
+ m_assembler.loadConstant(imm.m_value, scr);
m_assembler.xorlRegReg(scr, srcDest);
releaseScratch(scr);
return;
@@ -453,6 +559,11 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
return;
}
+ if (((cond == Equal) || (cond == NotEqual)) && !imm) {
+ m_assembler.testlRegReg(dst, dst);
+ return;
+ }
+
RegisterID scr = claimScratch();
m_assembler.loadConstant(imm, scr);
m_assembler.cmplRegReg(scr, dst, SH4Condition(cond));
@@ -486,20 +597,10 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void testImm(int imm, int offset, RegisterID base)
{
RegisterID scr = claimScratch();
- RegisterID scr1 = claimScratch();
+ load32(base, offset, scr);
- if ((offset < 0) || (offset >= 64)) {
- m_assembler.loadConstant(offset, scr);
- m_assembler.addlRegReg(base, scr);
- m_assembler.movlMemReg(scr, scr);
- } else if (offset)
- m_assembler.movlMemReg(offset >> 2, base, scr);
- else
- m_assembler.movlMemReg(base, scr);
- if (m_assembler.isImmediate(imm))
- m_assembler.movImm8(imm, scr1);
- else
- m_assembler.loadConstant(imm, scr1);
+ RegisterID scr1 = claimScratch();
+ move(TrustedImm32(imm), scr1);
m_assembler.testlRegReg(scr, scr1);
releaseScratch(scr);
@@ -547,41 +648,37 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void compare32(int imm, int offset, RegisterID base, RelationalCondition cond)
{
- if (!offset) {
- RegisterID scr = claimScratch();
- RegisterID scr1 = claimScratch();
- m_assembler.movlMemReg(base, scr);
- m_assembler.loadConstant(imm, scr1);
- m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
- releaseScratch(scr1);
- releaseScratch(scr);
- return;
- }
-
- if ((offset < 0) || (offset >= 64)) {
- RegisterID scr = claimScratch();
- RegisterID scr1 = claimScratch();
- m_assembler.loadConstant(offset, scr);
- m_assembler.addlRegReg(base, scr);
- m_assembler.movlMemReg(scr, scr);
- m_assembler.loadConstant(imm, scr1);
- m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
- releaseScratch(scr1);
- releaseScratch(scr);
- return;
- }
-
RegisterID scr = claimScratch();
+ load32(base, offset, scr);
+
RegisterID scr1 = claimScratch();
- m_assembler.movlMemReg(offset >> 2, base, scr);
- m_assembler.loadConstant(imm, scr1);
+ move(TrustedImm32(imm), scr1);
+
m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
+
releaseScratch(scr1);
releaseScratch(scr);
}
// Memory access operation
+ ALWAYS_INLINE void loadEffectiveAddress(BaseIndex address, RegisterID dest, int extraoffset = 0)
+ {
+ if (dest == address.base) {
+ RegisterID scaledIndex = claimScratch();
+ move(address.index, scaledIndex);
+ lshift32(TrustedImm32(address.scale), scaledIndex);
+ add32(scaledIndex, dest);
+ releaseScratch(scaledIndex);
+ } else {
+ move(address.index, dest);
+ lshift32(TrustedImm32(address.scale), dest);
+ add32(address.base, dest);
+ }
+
+ add32(TrustedImm32(address.offset + extraoffset), dest);
+ }
+
void load32(ImplicitAddress address, RegisterID dest)
{
load32(address.base, address.offset, dest);
@@ -602,6 +699,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scr);
}
+ void load8PostInc(RegisterID base, RegisterID dest)
+ {
+ m_assembler.movbMemRegIn(base, dest);
+ m_assembler.extub(dest, dest);
+ }
+
void load8Signed(BaseIndex address, RegisterID dest)
{
RegisterID scr = claimScratch();
@@ -624,7 +727,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void load32(const void* address, RegisterID dest)
{
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(const_cast<void*>(address)), dest);
+ move(TrustedImmPtr(address), dest);
m_assembler.movlMemReg(dest, dest);
}
@@ -640,20 +743,15 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
return;
}
- if ((dest == SH4Registers::r0) && (dest != base)) {
- m_assembler.loadConstant((offset), dest);
- m_assembler.movlR0mr(base, dest);
- return;
- }
+ RegisterID scr = (dest == base) ? claimScratch() : dest;
- RegisterID scr;
- if (dest == base)
- scr = claimScratch();
- else
- scr = dest;
- m_assembler.loadConstant((offset), scr);
- m_assembler.addlRegReg(base, scr);
- m_assembler.movlMemReg(scr, dest);
+ m_assembler.loadConstant(offset, scr);
+ if (base == SH4Registers::r0)
+ m_assembler.movlR0mr(scr, dest);
+ else {
+ m_assembler.addlRegReg(base, scr);
+ m_assembler.movlMemReg(scr, dest);
+ }
if (dest == base)
releaseScratch(scr);
@@ -666,59 +764,29 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
return;
}
- if ((offset > 0) && (offset < 64) && (dest == SH4Registers::r0)) {
+ if ((offset > 0) && (offset <= 15) && (dest == SH4Registers::r0)) {
m_assembler.movbMemReg(offset, base, dest);
return;
}
- if (base != dest) {
- m_assembler.loadConstant((offset), dest);
- m_assembler.addlRegReg(base, dest);
- m_assembler.movbMemReg(dest, dest);
- return;
+ RegisterID scr = (dest == base) ? claimScratch() : dest;
+
+ m_assembler.loadConstant(offset, scr);
+ if (base == SH4Registers::r0)
+ m_assembler.movbR0mr(scr, dest);
+ else {
+ m_assembler.addlRegReg(base, scr);
+ m_assembler.movbMemReg(scr, dest);
}
- RegisterID scr = claimScratch();
- m_assembler.loadConstant((offset), scr);
- m_assembler.addlRegReg(base, scr);
- m_assembler.movbMemReg(scr, dest);
- releaseScratch(scr);
+ if (dest == base)
+ releaseScratch(scr);
}
void load8(RegisterID base, int offset, RegisterID dest)
{
- if (!offset) {
- m_assembler.movbMemReg(base, dest);
- m_assembler.extub(dest, dest);
- return;
- }
-
- if ((offset > 0) && (offset < 64) && (dest == SH4Registers::r0)) {
- m_assembler.movbMemReg(offset, base, dest);
- m_assembler.extub(dest, dest);
- return;
- }
-
- if (base != dest) {
- m_assembler.loadConstant((offset), dest);
- m_assembler.addlRegReg(base, dest);
- m_assembler.movbMemReg(dest, dest);
- m_assembler.extub(dest, dest);
- return;
- }
-
- RegisterID scr = claimScratch();
- m_assembler.loadConstant((offset), scr);
- m_assembler.addlRegReg(base, scr);
- m_assembler.movbMemReg(scr, dest);
+ load8Signed(base, offset, dest);
m_assembler.extub(dest, dest);
- releaseScratch(scr);
- }
-
- void load32(RegisterID r0, RegisterID src, RegisterID dst)
- {
- ASSERT(r0 == SH4Registers::r0);
- m_assembler.movlR0mr(src, dst);
}
void load32(RegisterID src, RegisterID dst)
@@ -730,47 +798,39 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
if (!address.offset) {
m_assembler.movwMemReg(address.base, dest);
- extuw(dest, dest);
+ m_assembler.extuw(dest, dest);
return;
}
- if ((address.offset > 0) && (address.offset < 64) && (dest == SH4Registers::r0)) {
- m_assembler.movwMemReg(address.offset, address.base, dest);
- extuw(dest, dest);
+ if ((address.offset > 0) && (address.offset <= 30) && (dest == SH4Registers::r0)) {
+ m_assembler.movwMemReg(address.offset >> 1, address.base, dest);
+ m_assembler.extuw(dest, dest);
return;
}
- if (address.base != dest) {
- m_assembler.loadConstant((address.offset), dest);
- m_assembler.addlRegReg(address.base, dest);
- m_assembler.movwMemReg(dest, dest);
- extuw(dest, dest);
- return;
+ RegisterID scr = (dest == address.base) ? claimScratch() : dest;
+
+ m_assembler.loadConstant(address.offset, scr);
+ if (address.base == SH4Registers::r0)
+ m_assembler.movwR0mr(scr, dest);
+ else {
+ m_assembler.addlRegReg(address.base, scr);
+ m_assembler.movwMemReg(scr, dest);
}
+ m_assembler.extuw(dest, dest);
- RegisterID scr = claimScratch();
- m_assembler.loadConstant((address.offset), scr);
- m_assembler.addlRegReg(address.base, scr);
- m_assembler.movwMemReg(scr, dest);
- extuw(dest, dest);
- releaseScratch(scr);
+ if (dest == address.base)
+ releaseScratch(scr);
}
void load16Unaligned(BaseIndex address, RegisterID dest)
{
-
RegisterID scr = claimScratch();
- RegisterID scr1 = claimScratch();
-
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
+ loadEffectiveAddress(address, scr);
- add32(address.base, scr);
- load8(scr, scr1);
- add32(TrustedImm32(1), scr);
+ RegisterID scr1 = claimScratch();
+ load8PostInc(scr, scr1);
load8(scr, dest);
m_assembler.shllImm8r(8, dest);
or32(scr1, dest);
@@ -782,7 +842,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void load16(RegisterID src, RegisterID dest)
{
m_assembler.movwMemReg(src, dest);
- extuw(dest, dest);
+ m_assembler.extuw(dest, dest);
}
void load16Signed(RegisterID src, RegisterID dest)
@@ -790,68 +850,63 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.movwMemReg(src, dest);
}
- void load16(RegisterID r0, RegisterID src, RegisterID dest)
+ void load16(BaseIndex address, RegisterID dest)
{
- ASSERT(r0 == SH4Registers::r0);
- m_assembler.movwR0mr(src, dest);
- extuw(dest, dest);
+ load16Signed(address, dest);
+ m_assembler.extuw(dest, dest);
}
- void load16Signed(RegisterID r0, RegisterID src, RegisterID dest)
+ void load16PostInc(RegisterID base, RegisterID dest)
{
- ASSERT(r0 == SH4Registers::r0);
- m_assembler.movwR0mr(src, dest);
+ m_assembler.movwMemRegIn(base, dest);
+ m_assembler.extuw(dest, dest);
}
- void load16(BaseIndex address, RegisterID dest)
+ void load16Signed(BaseIndex address, RegisterID dest)
{
RegisterID scr = claimScratch();
move(address.index, scr);
lshift32(TrustedImm32(address.scale), scr);
+ add32(TrustedImm32(address.offset), scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
if (address.base == SH4Registers::r0)
- load16(address.base, scr, dest);
+ m_assembler.movwR0mr(scr, dest);
else {
add32(address.base, scr);
- load16(scr, dest);
+ load16Signed(scr, dest);
}
releaseScratch(scr);
}
- void load16Signed(BaseIndex address, RegisterID dest)
+ void store8(RegisterID src, BaseIndex address)
{
RegisterID scr = claimScratch();
move(address.index, scr);
lshift32(TrustedImm32(address.scale), scr);
+ add32(TrustedImm32(address.offset), scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
if (address.base == SH4Registers::r0)
- load16Signed(address.base, scr, dest);
+ m_assembler.movbRegMemr0(src, scr);
else {
add32(address.base, scr);
- load16Signed(scr, dest);
+ m_assembler.movbRegMem(src, scr);
}
releaseScratch(scr);
}
- void store8(RegisterID src, BaseIndex address)
+ void store8(TrustedImm32 imm, void* address)
{
- RegisterID scr = claimScratch();
-
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
-
- m_assembler.movbRegMem(src, scr);
-
- releaseScratch(scr);
+ RegisterID srcval = claimScratch();
+ RegisterID dstptr = claimScratch();
+ move(imm, srcval);
+ m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), dstptr);
+ m_assembler.movbRegMem(srcval, dstptr);
+ releaseScratch(dstptr);
+ releaseScratch(srcval);
}
void store16(RegisterID src, BaseIndex address)
@@ -860,46 +915,39 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
move(address.index, scr);
lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
+ add32(TrustedImm32(address.offset), scr);
- m_assembler.movwRegMem(src, scr);
+ if (address.base == SH4Registers::r0)
+ m_assembler.movwRegMemr0(src, scr);
+ else {
+ add32(address.base, scr);
+ m_assembler.movwRegMem(src, scr);
+ }
releaseScratch(scr);
}
void store32(RegisterID src, ImplicitAddress address)
{
- RegisterID scr = claimScratch();
- store32(src, address.offset, address.base, scr);
- releaseScratch(scr);
- }
-
- void store32(RegisterID src, int offset, RegisterID base, RegisterID scr)
- {
- if (!offset) {
- m_assembler.movlRegMem(src, base);
+ if (!address.offset) {
+ m_assembler.movlRegMem(src, address.base);
return;
}
- if ((offset >=0) && (offset < 64)) {
- m_assembler.movlRegMem(src, offset >> 2, base);
+ if ((address.offset >= 0) && (address.offset < 64)) {
+ m_assembler.movlRegMem(src, address.offset >> 2, address.base);
return;
}
- m_assembler.loadConstant((offset), scr);
- if (scr == SH4Registers::r0) {
- m_assembler.movlRegMemr0(src, base);
- return;
+ RegisterID scr = claimScratch();
+ m_assembler.loadConstant(address.offset, scr);
+ if (address.base == SH4Registers::r0)
+ m_assembler.movlRegMemr0(src, scr);
+ else {
+ m_assembler.addlRegReg(address.base, scr);
+ m_assembler.movlRegMem(src, scr);
}
-
- m_assembler.addlRegReg(base, scr);
- m_assembler.movlRegMem(src, scr);
- }
-
- void store32(RegisterID src, RegisterID offset, RegisterID base)
- {
- ASSERT(offset == SH4Registers::r0);
- m_assembler.movlRegMemr0(src, base);
+ releaseScratch(scr);
}
void store32(RegisterID src, RegisterID dst)
@@ -910,11 +958,9 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void store32(TrustedImm32 imm, ImplicitAddress address)
{
RegisterID scr = claimScratch();
- RegisterID scr1 = claimScratch();
- m_assembler.loadConstant((imm.m_value), scr);
- store32(scr, address.offset, address.base, scr1);
+ m_assembler.loadConstant(imm.m_value, scr);
+ store32(scr, address);
releaseScratch(scr);
- releaseScratch(scr1);
}
void store32(RegisterID src, BaseIndex address)
@@ -933,8 +979,8 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
RegisterID scr = claimScratch();
RegisterID scr1 = claimScratch();
- m_assembler.loadConstant((imm.m_value), scr);
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr1);
+ m_assembler.loadConstant(imm.m_value, scr);
+ move(TrustedImmPtr(address), scr1);
m_assembler.movlRegMem(scr, scr1);
releaseScratch(scr);
releaseScratch(scr1);
@@ -943,11 +989,24 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void store32(RegisterID src, void* address)
{
RegisterID scr = claimScratch();
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr);
+ move(TrustedImmPtr(address), scr);
m_assembler.movlRegMem(src, scr);
releaseScratch(scr);
}
+ void store32(TrustedImm32 imm, BaseIndex address)
+ {
+ RegisterID destptr = claimScratch();
+
+ loadEffectiveAddress(address, destptr);
+
+ RegisterID srcval = claimScratch();
+ move(imm, srcval);
+ m_assembler.movlRegMem(srcval, destptr);
+ releaseScratch(srcval);
+ releaseScratch(destptr);
+ }
+
DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
{
RegisterID scr = claimScratch();
@@ -973,8 +1032,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest)
{
DataLabelCompact dataLabel(this);
- ASSERT(address.offset <= MaximumCompactPtrAlignedAddressOffset);
- ASSERT(address.offset >= 0);
+ ASSERT(isCompactPtrAlignedAddressOffset(address.offset));
m_assembler.movlMemRegCompact(address.offset >> 2, address.base, dest);
return dataLabel;
}
@@ -997,7 +1055,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
static bool supportsFloatingPoint() { return true; }
static bool supportsFloatingPointTruncate() { return true; }
static bool supportsFloatingPointSqrt() { return true; }
- static bool supportsFloatingPointAbs() { return false; }
+ static bool supportsFloatingPointAbs() { return true; }
void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
{
@@ -1007,24 +1065,39 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.stsfpulReg(dest2);
}
- void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch)
+ void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID)
{
- UNUSED_PARAM(scratch);
m_assembler.ldsrmfpul(src1);
m_assembler.fstsfpul((FPRegisterID)(dest + 1));
m_assembler.ldsrmfpul(src2);
m_assembler.fstsfpul(dest);
}
+ void moveDouble(FPRegisterID src, FPRegisterID dest)
+ {
+ if (src != dest) {
+ m_assembler.fmovsRegReg((FPRegisterID)(src + 1), (FPRegisterID)(dest + 1));
+ m_assembler.fmovsRegReg(src, dest);
+ }
+ }
+
+ void swapDouble(FPRegisterID fr1, FPRegisterID fr2)
+ {
+ if (fr1 != fr2) {
+ m_assembler.fldsfpul((FPRegisterID)(fr1 + 1));
+ m_assembler.fmovsRegReg((FPRegisterID)(fr2 + 1), (FPRegisterID)(fr1 + 1));
+ m_assembler.fstsfpul((FPRegisterID)(fr2 + 1));
+ m_assembler.fldsfpul(fr1);
+ m_assembler.fmovsRegReg(fr2, fr1);
+ m_assembler.fstsfpul(fr2);
+ }
+ }
+
void loadFloat(BaseIndex address, FPRegisterID dest)
{
RegisterID scr = claimScratch();
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
+ loadEffectiveAddress(address, scr);
m_assembler.fmovsReadrm(scr, dest);
releaseScratch(scr);
@@ -1034,11 +1107,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
RegisterID scr = claimScratch();
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
+ loadEffectiveAddress(address, scr);
m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
m_assembler.fmovsReadrm(scr, dest);
@@ -1067,7 +1136,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void loadDouble(const void* address, FPRegisterID dest)
{
RegisterID scr = claimScratch();
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr);
+ move(TrustedImmPtr(address), scr);
m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
m_assembler.fmovsReadrm(scr, dest);
releaseScratch(scr);
@@ -1076,26 +1145,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void storeFloat(FPRegisterID src, BaseIndex address)
{
RegisterID scr = claimScratch();
-
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
-
+ loadEffectiveAddress(address, scr);
m_assembler.fmovsWriterm(src, scr);
-
releaseScratch(scr);
}
void storeDouble(FPRegisterID src, ImplicitAddress address)
{
RegisterID scr = claimScratch();
- m_assembler.loadConstant(address.offset, scr);
+ m_assembler.loadConstant(address.offset + 8, scr);
m_assembler.addlRegReg(address.base, scr);
- m_assembler.fmovsWriterm((FPRegisterID)(src + 1), scr);
- m_assembler.addlImm8r(4, scr);
- m_assembler.fmovsWriterm(src, scr);
+ m_assembler.fmovsWriterndec(src, scr);
+ m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr);
releaseScratch(scr);
}
@@ -1103,15 +1164,10 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
RegisterID scr = claimScratch();
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
+ loadEffectiveAddress(address, scr, 8);
- m_assembler.fmovsWriterm((FPRegisterID)(src + 1), scr);
- m_assembler.addlImm8r(4, scr);
- m_assembler.fmovsWriterm(src, scr);
+ m_assembler.fmovsWriterndec(src, scr);
+ m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr);
releaseScratch(scr);
}
@@ -1119,13 +1175,22 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
{
if (op1 == dest)
- m_assembler.daddRegReg(op2, dest);
+ addDouble(op2, dest);
else {
- m_assembler.dmovRegReg(op1, dest);
- m_assembler.daddRegReg(op2, dest);
+ moveDouble(op2, dest);
+ addDouble(op1, dest);
}
}
+ void storeDouble(FPRegisterID src, const void* address)
+ {
+ RegisterID scr = claimScratch();
+ m_assembler.loadConstant(reinterpret_cast<uint32_t>(const_cast<void*>(address)) + 8, scr);
+ m_assembler.fmovsWriterndec(src, scr);
+ m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr);
+ releaseScratch(scr);
+ }
+
void addDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.daddRegReg(src, dest);
@@ -1148,6 +1213,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.dsubRegReg(src, dest);
}
+ void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ if (op2 == dest) {
+ moveDouble(op1, fscratch);
+ subDouble(op2, fscratch);
+ moveDouble(fscratch, dest);
+ } else {
+ moveDouble(op1, dest);
+ subDouble(op2, dest);
+ }
+ }
+
void subDouble(Address address, FPRegisterID dest)
{
loadDouble(address, fscratch);
@@ -1159,6 +1236,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.dmulRegReg(src, dest);
}
+ void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ if (op1 == dest)
+ mulDouble(op2, dest);
+ else {
+ moveDouble(op2, dest);
+ mulDouble(op1, dest);
+ }
+ }
+
void mulDouble(Address address, FPRegisterID dest)
{
loadDouble(address, fscratch);
@@ -1170,6 +1257,24 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.ddivRegReg(src, dest);
}
+ void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ if (op2 == dest) {
+ moveDouble(op1, fscratch);
+ divDouble(op2, fscratch);
+ moveDouble(fscratch, dest);
+ } else {
+ moveDouble(op1, dest);
+ divDouble(op2, dest);
+ }
+ }
+
+ void negateDouble(FPRegisterID src, FPRegisterID dest)
+ {
+ moveDouble(src, dest);
+ m_assembler.dneg(dest);
+ }
+
void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
{
m_assembler.fldsfpul(src);
@@ -1191,7 +1296,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
{
RegisterID scr = claimScratch();
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(src.m_ptr), scr);
+ load32(src.m_ptr, scr);
convertInt32ToDouble(scr, dest);
releaseScratch(scr);
}
@@ -1214,18 +1319,13 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
if (dest != SH4Registers::r0)
move(SH4Registers::r0, scr1);
- move(address.index, scr);
- lshift32(TrustedImm32(address.scale), scr);
- add32(address.base, scr);
-
- if (address.offset)
- add32(TrustedImm32(address.offset), scr);
+ loadEffectiveAddress(address, scr);
- m_assembler.ensureSpace(m_assembler.maxInstructionSize + 68, sizeof(uint32_t));
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 58, sizeof(uint32_t));
move(scr, SH4Registers::r0);
- m_assembler.andlImm8r(0x3, SH4Registers::r0);
- m_assembler.cmpEqImmR0(0x0, SH4Registers::r0);
+ m_assembler.testlImm8r(0x3, SH4Registers::r0);
m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear);
+
if (dest != SH4Registers::r0)
move(scr1, SH4Registers::r0);
@@ -1233,27 +1333,23 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear));
m_assembler.nop();
m_jump.link(this);
- m_assembler.andlImm8r(0x1, SH4Registers::r0);
- m_assembler.cmpEqImmR0(0x0, SH4Registers::r0);
+ m_assembler.testlImm8r(0x1, SH4Registers::r0);
if (dest != SH4Registers::r0)
move(scr1, SH4Registers::r0);
m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear);
- load16(scr, scr1);
- add32(TrustedImm32(2), scr);
+ load16PostInc(scr, scr1);
load16(scr, dest);
m_assembler.shllImm8r(16, dest);
or32(scr1, dest);
end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear));
m_assembler.nop();
m_jump.link(this);
- load8(scr, scr1);
- add32(TrustedImm32(1), scr);
- load16(scr, dest);
+ load8PostInc(scr, scr1);
+ load16PostInc(scr, dest);
m_assembler.shllImm8r(8, dest);
or32(dest, scr1);
- add32(TrustedImm32(2), scr);
load8(scr, dest);
m_assembler.shllImm8r(8, dest);
m_assembler.shllImm8r(16, dest);
@@ -1300,20 +1396,13 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
}
if (cond == DoubleNotEqual) {
- RegisterID scr = claimScratch();
JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
+ m_assembler.dcmppeq(left, left);
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
+ end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
+ m_assembler.dcmppeq(right, right);
+ end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
m_assembler.dcmppeq(right, left);
- releaseScratch(scr);
Jump m_jump = branchFalse();
end.link(this);
return m_jump;
@@ -1325,8 +1414,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
}
if (cond == DoubleGreaterThanOrEqual) {
+ JumpList end;
+ m_assembler.dcmppeq(left, left);
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
+ end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
+ m_assembler.dcmppeq(right, right);
+ end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(left, right);
- return branchFalse();
+ Jump m_jump = branchFalse();
+ end.link(this);
+ return m_jump;
}
if (cond == DoubleLessThan) {
@@ -1335,134 +1432,73 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
}
if (cond == DoubleLessThanOrEqual) {
+ JumpList end;
+ m_assembler.dcmppeq(left, left);
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
+ end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
+ m_assembler.dcmppeq(right, right);
+ end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(right, left);
- return branchFalse();
+ Jump m_jump = branchFalse();
+ end.link(this);
+ return m_jump;
}
if (cond == DoubleEqualOrUnordered) {
- RegisterID scr = claimScratch();
- JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
+ JumpList takeBranch;
+ m_assembler.dcmppeq(left, left);
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
+ takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
+ m_assembler.dcmppeq(right, right);
+ takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
m_assembler.dcmppeq(left, right);
Jump m_jump = Jump(m_assembler.je());
- end.link(this);
- m_assembler.extraInstrForBranch(scr);
- releaseScratch(scr);
+ takeBranch.link(this);
+ m_assembler.extraInstrForBranch(scratchReg3);
return m_jump;
}
if (cond == DoubleGreaterThanOrUnordered) {
- RegisterID scr = claimScratch();
- JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
+ JumpList takeBranch;
+ m_assembler.dcmppeq(left, left);
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
+ takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
+ m_assembler.dcmppeq(right, right);
+ takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(right, left);
Jump m_jump = Jump(m_assembler.je());
- end.link(this);
- m_assembler.extraInstrForBranch(scr);
- releaseScratch(scr);
+ takeBranch.link(this);
+ m_assembler.extraInstrForBranch(scratchReg3);
return m_jump;
}
if (cond == DoubleGreaterThanOrEqualOrUnordered) {
- RegisterID scr = claimScratch();
- JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(left, right);
- Jump m_jump = Jump(m_assembler.jne());
- end.link(this);
- m_assembler.extraInstrForBranch(scr);
- releaseScratch(scr);
- return m_jump;
+ return branchFalse();
}
if (cond == DoubleLessThanOrUnordered) {
- RegisterID scr = claimScratch();
- JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
+ JumpList takeBranch;
+ m_assembler.dcmppeq(left, left);
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
+ takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
+ m_assembler.dcmppeq(right, right);
+ takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(left, right);
Jump m_jump = Jump(m_assembler.je());
- end.link(this);
- m_assembler.extraInstrForBranch(scr);
- releaseScratch(scr);
+ takeBranch.link(this);
+ m_assembler.extraInstrForBranch(scratchReg3);
return m_jump;
}
if (cond == DoubleLessThanOrEqualOrUnordered) {
- RegisterID scr = claimScratch();
- JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(right, left);
- Jump m_jump = Jump(m_assembler.jne());
- end.link(this);
- m_assembler.extraInstrForBranch(scr);
- releaseScratch(scr);
- return m_jump;
+ return branchFalse();
}
ASSERT(cond == DoubleNotEqualOrUnordered);
- RegisterID scr = claimScratch();
- JumpList end;
- m_assembler.loadConstant(0x7fbfffff, scratchReg3);
- m_assembler.dcnvds(right);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
- m_assembler.dcnvds(left);
- m_assembler.stsfpulReg(scr);
- m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppeq(right, left);
- Jump m_jump = Jump(m_assembler.jne());
- end.link(this);
- m_assembler.extraInstrForBranch(scr);
- releaseScratch(scr);
- return m_jump;
+ return branchFalse();
}
Jump branchTrue()
@@ -1498,14 +1534,14 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void sqrtDouble(FPRegisterID src, FPRegisterID dest)
{
- if (dest != src)
- m_assembler.dmovRegReg(src, dest);
+ moveDouble(src, dest);
m_assembler.dsqrt(dest);
}
- void absDouble(FPRegisterID, FPRegisterID)
+ void absDouble(FPRegisterID src, FPRegisterID dest)
{
- ASSERT_NOT_REACHED();
+ moveDouble(src, dest);
+ m_assembler.dabs(dest);
}
Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
@@ -1529,8 +1565,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void signExtend32ToPtr(RegisterID src, RegisterID dest)
{
- if (src != dest)
- move(src, dest);
+ move(src, dest);
+ }
+
+ void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
}
Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
@@ -1550,17 +1590,77 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(addressTempRegister);
}
- Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
+ enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
+ Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
+ {
+ Jump result;
+ truncateDoubleToInt32(src, dest);
+ RegisterID intscr = claimScratch();
+ m_assembler.loadConstant(0x7fffffff, intscr);
+ m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 12, sizeof(uint32_t));
+ if (branchType == BranchIfTruncateFailed) {
+ m_assembler.branch(BT_OPCODE, 2);
+ m_assembler.addlImm8r(1, intscr);
+ m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
+ result = branchTrue();
+ } else {
+ Jump out = Jump(m_assembler.je(), SH4Assembler::JumpNear);
+ m_assembler.addlImm8r(1, intscr);
+ m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
+ result = branchFalse();
+ out.link(this);
+ }
+ releaseScratch(intscr);
+ return result;
+ }
+
+ Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
+ {
+ Jump result;
+ RegisterID intscr = claimScratch();
+ m_assembler.loadConstant(0x80000000, intscr);
+ convertInt32ToDouble(intscr, fscratch);
+ addDouble(src, fscratch);
+ truncateDoubleToInt32(fscratch, dest);
+ m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 16, sizeof(uint32_t));
+ if (branchType == BranchIfTruncateFailed) {
+ m_assembler.branch(BT_OPCODE, 4);
+ m_assembler.addlImm8r(-1, intscr);
+ m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
+ m_assembler.addlImm8r(1, intscr);
+ m_assembler.sublRegReg(intscr, dest);
+ result = branchTrue();
+ } else {
+ Jump out = Jump(m_assembler.je(), SH4Assembler::JumpNear);
+ m_assembler.addlImm8r(-1, intscr);
+ m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal));
+ m_assembler.addlImm8r(1, intscr);
+ m_assembler.sublRegReg(intscr, dest);
+ result = branchFalse();
+ out.link(this);
+ }
+ releaseScratch(intscr);
+ return result;
+ }
+
+ void truncateDoubleToInt32(FPRegisterID src, RegisterID dest)
{
m_assembler.ftrcdrmfpul(src);
m_assembler.stsfpulReg(dest);
- m_assembler.loadConstant(0x7fffffff, scratchReg3);
- m_assembler.cmplRegReg(dest, scratchReg3, SH4Condition(Equal));
- m_assembler.ensureSpace(m_assembler.maxInstructionSize + 14, sizeof(uint32_t));
- m_assembler.branch(BT_OPCODE, 2);
- m_assembler.addlImm8r(1, scratchReg3);
- m_assembler.cmplRegReg(dest, scratchReg3, SH4Condition(Equal));
- return branchTrue();
+ }
+
+ void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
+ {
+ RegisterID intscr = claimScratch();
+ m_assembler.loadConstant(0x80000000, intscr);
+ convertInt32ToDouble(intscr, fscratch);
+ addDouble(src, fscratch);
+ m_assembler.ftrcdrmfpul(fscratch);
+ m_assembler.stsfpulReg(dest);
+ m_assembler.sublRegReg(intscr, dest);
+ releaseScratch(intscr);
}
// Stack manipulation operations
@@ -1575,27 +1675,6 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.pushReg(src);
}
- void push(Address address)
- {
- if (!address.offset) {
- push(address.base);
- return;
- }
-
- if ((address.offset < 0) || (address.offset >= 64)) {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(address.offset, scr);
- m_assembler.addlRegReg(address.base, scr);
- m_assembler.movlMemReg(scr, SH4Registers::sp);
- m_assembler.addlImm8r(-4, SH4Registers::sp);
- releaseScratch(scr);
- return;
- }
-
- m_assembler.movlMemReg(address.offset >> 2, address.base, SH4Registers::sp);
- m_assembler.addlImm8r(-4, SH4Registers::sp);
- }
-
void push(TrustedImm32 imm)
{
RegisterID scr = claimScratch();
@@ -1630,9 +1709,13 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.loadConstant(imm.asIntptr(), dest);
}
- void extuw(RegisterID src, RegisterID dst)
+ void swap(RegisterID reg1, RegisterID reg2)
{
- m_assembler.extuw(src, dst);
+ if (reg1 != reg2) {
+ xor32(reg1, reg2);
+ xor32(reg2, reg1);
+ xor32(reg1, reg2);
+ }
}
void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
@@ -1744,7 +1827,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
RegisterID scr = claimScratch();
- move(TrustedImm32(reinterpret_cast<uint32_t>(left.m_ptr)), scr);
+ load32(left.m_ptr, scr);
m_assembler.cmplRegReg(right, scr, SH4Condition(cond));
releaseScratch(scr);
@@ -1757,7 +1840,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
RegisterID addressTempRegister = claimScratch();
- m_assembler.loadConstant(reinterpret_cast<uint32_t>(left.m_ptr), addressTempRegister);
+ move(TrustedImmPtr(left.m_ptr), addressTempRegister);
m_assembler.movlMemReg(addressTempRegister, addressTempRegister);
compare32(right.m_value, addressTempRegister, cond);
releaseScratch(addressTempRegister);
@@ -1770,21 +1853,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
{
ASSERT(!(right.m_value & 0xFFFFFF00));
- RegisterID scr = claimScratch();
+ RegisterID lefttmp = claimScratch();
- move(left.index, scr);
- lshift32(TrustedImm32(left.scale), scr);
+ loadEffectiveAddress(left, lefttmp);
- if (left.offset)
- add32(TrustedImm32(left.offset), scr);
- add32(left.base, scr);
- load8(scr, scr);
- RegisterID scr1 = claimScratch();
- m_assembler.loadConstant(right.m_value, scr1);
- releaseScratch(scr);
- releaseScratch(scr1);
+ load8(lefttmp, lefttmp);
+ RegisterID righttmp = claimScratch();
+ m_assembler.loadConstant(right.m_value, righttmp);
- return branch32(cond, scr, scr1);
+ Jump result = branch32(cond, lefttmp, righttmp);
+ releaseScratch(lefttmp);
+ releaseScratch(righttmp);
+ return result;
}
Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
@@ -1828,6 +1908,8 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
Jump branchTest32(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
{
+ ASSERT((cond == Zero) || (cond == NonZero));
+
RegisterID scr = claimScratch();
move(address.index, scr);
@@ -1860,60 +1942,102 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void jump(Address address)
{
RegisterID scr = claimScratch();
-
- if ((address.offset < 0) || (address.offset >= 64)) {
- m_assembler.loadConstant(address.offset, scr);
- m_assembler.addlRegReg(address.base, scr);
- m_assembler.movlMemReg(scr, scr);
- } else if (address.offset)
- m_assembler.movlMemReg(address.offset >> 2, address.base, scr);
- else
- m_assembler.movlMemReg(address.base, scr);
+ load32(address, scr);
m_assembler.jmpReg(scr);
+ releaseScratch(scr);
+ }
+ void jump(AbsoluteAddress address)
+ {
+ RegisterID scr = claimScratch();
+
+ move(TrustedImmPtr(address.m_ptr), scr);
+ m_assembler.movlMemReg(scr, scr);
+ m_assembler.jmpReg(scr);
releaseScratch(scr);
}
// Arithmetic control flow operations
- Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
+ Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ if (cond == Overflow)
+ return branchMul32(cond, TrustedImm32(-1), srcDest, srcDest);
+
+ neg32(srcDest);
+
+ if (cond == Signed) {
+ m_assembler.cmppz(srcDest);
+ return branchFalse();
+ }
+
+ compare32(0, srcDest, Equal);
+ return (cond == NonZero) ? branchFalse() : branchTrue();
+ }
+
+ Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
+
if (cond == Overflow) {
m_assembler.addvlRegReg(src, dest);
return branchTrue();
}
- if (cond == Signed) {
- m_assembler.addlRegReg(src, dest);
- // Check if dest is negative
+ m_assembler.addlRegReg(src, dest);
+
+ if ((cond == Signed) || (cond == PositiveOrZero)) {
m_assembler.cmppz(dest);
- return branchFalse();
+ return (cond == Signed) ? branchFalse() : branchTrue();
}
- m_assembler.addlRegReg(src, dest);
compare32(0, dest, Equal);
+ return (cond == NonZero) ? branchFalse() : branchTrue();
+ }
- if (cond == NonZero) // NotEqual
- return branchFalse();
- return branchTrue();
+ Jump branchAdd32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
+
+ if (cond == Overflow) {
+ if (src1 == dest)
+ m_assembler.addvlRegReg(src2, dest);
+ else {
+ move(src2, dest);
+ m_assembler.addvlRegReg(src1, dest);
+ }
+ return branchTrue();
+ }
+
+ add32(src1, src2, dest);
+
+ if ((cond == Signed) || (cond == PositiveOrZero)) {
+ m_assembler.cmppz(dest);
+ return (cond == Signed) ? branchFalse() : branchTrue();
+ }
+
+ compare32(0, dest, Equal);
+ return (cond == NonZero) ? branchFalse() : branchTrue();
}
Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
- move(imm, scratchReg3);
- return branchAdd32(cond, scratchReg3, dest);
+ RegisterID immval = claimScratch();
+ move(imm, immval);
+ Jump result = branchAdd32(cond, immval, dest);
+ releaseScratch(immval);
+ return result;
}
Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
{
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
- if (src != dest)
- move(src, dest);
+ move(src, dest);
if (cond == Overflow) {
move(imm, scratchReg3);
@@ -1923,16 +2047,42 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
add32(imm, dest);
- if (cond == Signed) {
+ if ((cond == Signed) || (cond == PositiveOrZero)) {
m_assembler.cmppz(dest);
- return branchFalse();
+ return (cond == Signed) ? branchFalse() : branchTrue();
}
compare32(0, dest, Equal);
+ return (cond == NonZero) ? branchFalse() : branchTrue();
+ }
- if (cond == NonZero) // NotEqual
- return branchFalse();
- return branchTrue();
+ Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
+ bool result;
+
+ move(imm, scratchReg3);
+ RegisterID destptr = claimScratch();
+ RegisterID destval = claimScratch();
+ move(TrustedImmPtr(dest.m_ptr), destptr);
+ m_assembler.movlMemReg(destptr, destval);
+ if (cond == Overflow) {
+ m_assembler.addvlRegReg(scratchReg3, destval);
+ result = true;
+ } else {
+ m_assembler.addlRegReg(scratchReg3, destval);
+ if ((cond == Signed) || (cond == PositiveOrZero)) {
+ m_assembler.cmppz(destval);
+ result = (cond == PositiveOrZero);
+ } else {
+ m_assembler.testlRegReg(destval, destval);
+ result = (cond != NonZero);
+ }
+ }
+ m_assembler.movlRegMem(destval, destptr);
+ releaseScratch(destval);
+ releaseScratch(destptr);
+ return result ? branchTrue() : branchFalse();
}
Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
@@ -1940,44 +2090,72 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
if (cond == Overflow) {
- RegisterID scr1 = claimScratch();
- RegisterID scr = claimScratch();
- m_assembler.dmullRegReg(src, dest);
+ RegisterID scrsign = claimScratch();
+ RegisterID msbres = claimScratch();
+ m_assembler.dmulslRegReg(src, dest);
m_assembler.stsmacl(dest);
- m_assembler.movImm8(-31, scr);
- m_assembler.movlRegReg(dest, scr1);
- m_assembler.shaRegReg(scr1, scr);
- m_assembler.stsmach(scr);
- m_assembler.cmplRegReg(scr, scr1, SH4Condition(Equal));
- releaseScratch(scr1);
- releaseScratch(scr);
+ m_assembler.cmppz(dest);
+ m_assembler.movt(scrsign);
+ m_assembler.addlImm8r(-1, scrsign);
+ m_assembler.stsmach(msbres);
+ m_assembler.cmplRegReg(msbres, scrsign, SH4Condition(Equal));
+ releaseScratch(msbres);
+ releaseScratch(scrsign);
return branchFalse();
}
- m_assembler.imullRegReg(src, dest);
- m_assembler.stsmacl(dest);
+ mul32(src, dest);
+
if (cond == Signed) {
- // Check if dest is negative
m_assembler.cmppz(dest);
return branchFalse();
}
compare32(0, dest, static_cast<RelationalCondition>(cond));
+ return (cond == NonZero) ? branchFalse() : branchTrue();
+ }
- if (cond == NonZero) // NotEqual
+ Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+
+ if (cond == Overflow) {
+ RegisterID scrsign = claimScratch();
+ RegisterID msbres = claimScratch();
+ m_assembler.dmulslRegReg(src1, src2);
+ m_assembler.stsmacl(dest);
+ m_assembler.cmppz(dest);
+ m_assembler.movt(scrsign);
+ m_assembler.addlImm8r(-1, scrsign);
+ m_assembler.stsmach(msbres);
+ m_assembler.cmplRegReg(msbres, scrsign, SH4Condition(Equal));
+ releaseScratch(msbres);
+ releaseScratch(scrsign);
return branchFalse();
- return branchTrue();
+ }
+
+ mul32(src1, src2, dest);
+
+ if (cond == Signed) {
+ m_assembler.cmppz(dest);
+ return branchFalse();
+ }
+
+ compare32(0, dest, Equal);
+ return (cond == NonZero) ? branchFalse() : branchTrue();
}
Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- move(imm, scratchReg3);
- if (src != dest)
- move(src, dest);
+ if (src == dest) {
+ move(imm, scratchReg3);
+ return branchMul32(cond, scratchReg3, dest);
+ }
- return branchMul32(cond, scratchReg3, dest);
+ move(imm, dest);
+ return branchMul32(cond, src, dest);
}
Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
@@ -1989,76 +2167,92 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
return branchTrue();
}
+ sub32(src, dest);
+
if (cond == Signed) {
- // Check if dest is negative
- m_assembler.sublRegReg(src, dest);
- compare32(0, dest, LessThan);
- return branchTrue();
+ m_assembler.cmppz(dest);
+ return branchFalse();
}
- sub32(src, dest);
compare32(0, dest, static_cast<RelationalCondition>(cond));
-
- if (cond == NonZero) // NotEqual
- return branchFalse();
- return branchTrue();
+ return (cond == NonZero) ? branchFalse() : branchTrue();
}
Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- move(imm, scratchReg3);
- return branchSub32(cond, scratchReg3, dest);
+ RegisterID immval = claimScratch();
+ move(imm, immval);
+ Jump result = branchSub32(cond, immval, dest);
+ releaseScratch(immval);
+ return result;
}
Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
{
- move(imm, scratchReg3);
- if (src != dest)
- move(src, dest);
- return branchSub32(cond, scratchReg3, dest);
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+
+ move(src, dest);
+ return branchSub32(cond, imm, dest);
}
Jump branchSub32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
{
- if (src1 != dest)
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+
+ if (src2 != dest) {
move(src1, dest);
- return branchSub32(cond, src2, dest);
+ return branchSub32(cond, src2, dest);
+ }
+
+ if (cond == Overflow) {
+ RegisterID tmpval = claimScratch();
+ move(src1, tmpval);
+ m_assembler.subvlRegReg(src2, tmpval);
+ move(tmpval, dest);
+ releaseScratch(tmpval);
+ return branchTrue();
+ }
+
+ RegisterID tmpval = claimScratch();
+ move(src1, tmpval);
+ sub32(src2, tmpval);
+ move(tmpval, dest);
+ releaseScratch(tmpval);
+
+ if (cond == Signed) {
+ m_assembler.cmppz(dest);
+ return branchFalse();
+ }
+
+ compare32(0, dest, static_cast<RelationalCondition>(cond));
+ return (cond == NonZero) ? branchFalse() : branchTrue();
}
Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
+ or32(src, dest);
+
if (cond == Signed) {
- or32(src, dest);
- compare32(0, dest, static_cast<RelationalCondition>(LessThan));
- return branchTrue();
+ m_assembler.cmppz(dest);
+ return branchFalse();
}
- or32(src, dest);
compare32(0, dest, static_cast<RelationalCondition>(cond));
-
- if (cond == NonZero) // NotEqual
- return branchFalse();
- return branchTrue();
+ return (cond == NonZero) ? branchFalse() : branchTrue();
}
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true)
{
- m_assembler.ftrcdrmfpul(src);
- m_assembler.stsfpulReg(dest);
+ truncateDoubleToInt32(src, dest);
convertInt32ToDouble(dest, fscratch);
failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fscratch, src));
- if (dest == SH4Registers::r0)
- m_assembler.cmpEqImmR0(0, dest);
- else {
- m_assembler.movImm8(0, scratchReg3);
- m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal));
- }
- failureCases.append(branchTrue());
+ if (negZeroCheck)
+ failureCases.append(branch32(Equal, dest, TrustedImm32(0)));
}
void neg32(RegisterID dst)
@@ -2068,31 +2262,40 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void urshift32(RegisterID shiftamount, RegisterID dest)
{
- if (shiftamount == SH4Registers::r0)
- m_assembler.andlImm8r(0x1f, shiftamount);
- else {
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(0x1f, scr);
- m_assembler.andlRegReg(scr, shiftamount);
- releaseScratch(scr);
- }
- m_assembler.neg(shiftamount, shiftamount);
- m_assembler.shllRegReg(dest, shiftamount);
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(0x1f, shiftTmp);
+ m_assembler.andlRegReg(shiftamount, shiftTmp);
+ m_assembler.neg(shiftTmp, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
+ }
+
+ void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
+ {
+ move(src, dest);
+ urshift32(shiftAmount, dest);
}
void urshift32(TrustedImm32 imm, RegisterID dest)
{
- RegisterID scr = claimScratch();
- m_assembler.loadConstant(-(imm.m_value & 0x1f), scr);
- m_assembler.shaRegReg(dest, scr);
- releaseScratch(scr);
+ int immMasked = imm.m_value & 0x1f;
+ if (!immMasked)
+ return;
+
+ if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) {
+ m_assembler.shlrImm8r(immMasked, dest);
+ return;
+ }
+
+ RegisterID shiftTmp = claimScratch();
+ m_assembler.loadConstant(-immMasked, shiftTmp);
+ m_assembler.shldRegReg(dest, shiftTmp);
+ releaseScratch(shiftTmp);
}
void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
{
- if (src != dest)
- move(src, dest);
-
+ move(src, dest);
urshift32(shiftamount, dest);
}
@@ -2121,6 +2324,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void breakpoint()
{
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 2);
m_assembler.bkpt();
m_assembler.nop();
}
@@ -2129,6 +2333,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
RegisterID dataTempRegister = claimScratch();
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t));
dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
m_assembler.cmplRegReg(dataTempRegister, left, SH4Condition(cond));
releaseScratch(dataTempRegister);
@@ -2146,6 +2351,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.addlRegReg(left.base, scr);
m_assembler.movlMemReg(scr, scr);
RegisterID scr1 = claimScratch();
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t));
dataLabel = moveWithPatch(initialRightValue, scr1);
m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond));
releaseScratch(scr);
@@ -2207,13 +2413,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
{
- ASSERT_NOT_REACHED();
+ SH4Assembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation());
}
static ptrdiff_t maxJumpReplacementSize()
{
- ASSERT_NOT_REACHED();
- return 0;
+ return SH4Assembler::maxJumpReplacementSize();
}
static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; }
@@ -2223,9 +2428,9 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
return label.labelAtOffset(0);
}
- static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID, void* initialValue)
+ static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID rd, void* initialValue)
{
- SH4Assembler::revertJump(instructionStart.dataLocation(), reinterpret_cast<uintptr_t>(initialValue) & 0xffff);
+ SH4Assembler::revertJumpToMove(instructionStart.dataLocation(), rd, reinterpret_cast<int>(initialValue));
}
static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr)
@@ -2253,9 +2458,20 @@ private:
friend class LinkBuffer;
friend class RepatchBuffer;
- static void linkCall(void*, Call, FunctionPtr);
- static void repatchCall(CodeLocationCall, CodeLocationLabel);
- static void repatchCall(CodeLocationCall, FunctionPtr);
+ static void linkCall(void* code, Call call, FunctionPtr function)
+ {
+ SH4Assembler::linkCall(code, call.m_label, function.value());
+ }
+
+ static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+ {
+ SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+ }
+
+ static void repatchCall(CodeLocationCall call, FunctionPtr destination)
+ {
+ SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+ }
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index 53cb80c21..f171dc408 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -68,6 +68,7 @@ public:
enum ResultCondition {
Overflow = X86Assembler::ConditionO,
Signed = X86Assembler::ConditionS,
+ PositiveOrZero = X86Assembler::ConditionNS,
Zero = X86Assembler::ConditionE,
NonZero = X86Assembler::ConditionNE
};
@@ -884,13 +885,14 @@ public:
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
// (specifically, in this case, 0).
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true)
{
ASSERT(isSSE2Present());
m_assembler.cvttsd2si_rr(src, dest);
// If the result is zero, it might have been -0.0, and the double comparison won't catch this!
- failureCases.append(branchTest32(Zero, dest));
+ if (negZeroCheck)
+ failureCases.append(branchTest32(Zero, dest));
// Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
convertInt32ToDouble(dest, fpTemp);
diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h
index 39f5585be..fded7df89 100644
--- a/Source/JavaScriptCore/assembler/SH4Assembler.h
+++ b/Source/JavaScriptCore/assembler/SH4Assembler.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
* Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
@@ -114,7 +115,9 @@ enum {
MOVL_READ_OFFPC_OPCODE = 0xd000,
MOVL_READ_OFFRM_OPCODE = 0x5000,
MOVW_WRITE_RN_OPCODE = 0x2001,
+ MOVW_WRITE_R0RN_OPCODE = 0x0005,
MOVW_READ_RM_OPCODE = 0x6001,
+ MOVW_READ_RMINC_OPCODE = 0x6005,
MOVW_READ_R0RM_OPCODE = 0x000d,
MOVW_READ_OFFRM_OPCODE = 0x8500,
MOVW_READ_OFFPC_OPCODE = 0x9000,
@@ -175,6 +178,7 @@ enum {
STSFPSCR_OPCODE = 0x006a,
LDSRMFPUL_OPCODE = 0x405a,
FSTSFPULFRN_OPCODE = 0xf00d,
+ FABS_OPCODE = 0xf05d,
FSQRT_OPCODE = 0xf06d,
FSCHG_OPCODE = 0xf3fd,
CLRT_OPCODE = 8,
@@ -333,30 +337,33 @@ public:
};
SH4Assembler()
+ : m_claimscratchReg(0x0)
+ , m_indexOfLastWatchpoint(INT_MIN)
+ , m_indexOfTailOfLastWatchpoint(INT_MIN)
{
- m_claimscratchReg = 0x0;
}
// SH4 condition codes
typedef enum {
EQ = 0x0, // Equal
NE = 0x1, // Not Equal
- HS = 0x2, // Unsigend Greater Than equal
- HI = 0x3, // Unsigend Greater Than
- LS = 0x4, // Unsigend Lower or Same
- LI = 0x5, // Unsigend Lower
+ HS = 0x2, // Unsigned Greater Than equal
+ HI = 0x3, // Unsigned Greater Than
+ LS = 0x4, // Unsigned Lower or Same
+ LI = 0x5, // Unsigned Lower
GE = 0x6, // Greater or Equal
LT = 0x7, // Less Than
GT = 0x8, // Greater Than
LE = 0x9, // Less or Equal
OF = 0xa, // OverFlow
SI = 0xb, // Signed
- EQU= 0xc, // Equal or unordered(NaN)
- NEU= 0xd,
- GTU= 0xe,
- GEU= 0xf,
- LTU= 0x10,
- LEU= 0x11,
+ NS = 0xc, // Not Signed
+ EQU= 0xd, // Equal or unordered(NaN)
+ NEU= 0xe,
+ GTU= 0xf,
+ GEU= 0x10,
+ LTU= 0x11,
+ LEU= 0x12,
} Condition;
// Opaque label types
@@ -534,7 +541,7 @@ public:
oneShortOp(getOpcodeGroup2(SHLL16_OPCODE, dst));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -544,28 +551,14 @@ public:
oneShortOp(opc);
}
- void shllRegReg(RegisterID dst, RegisterID rShift)
+ void shldRegReg(RegisterID dst, RegisterID rShift)
{
- uint16_t opc = getOpcodeGroup1(SHLD_OPCODE, dst, rShift);
- oneShortOp(opc);
- }
-
- void shlrRegReg(RegisterID dst, RegisterID rShift)
- {
- neg(rShift, rShift);
- shllRegReg(dst, rShift);
+ oneShortOp(getOpcodeGroup1(SHLD_OPCODE, dst, rShift));
}
- void sharRegReg(RegisterID dst, RegisterID rShift)
+ void shadRegReg(RegisterID dst, RegisterID rShift)
{
- neg(rShift, rShift);
- shaRegReg(dst, rShift);
- }
-
- void shaRegReg(RegisterID dst, RegisterID rShift)
- {
- uint16_t opc = getOpcodeGroup1(SHAD_OPCODE, dst, rShift);
- oneShortOp(opc);
+ oneShortOp(getOpcodeGroup1(SHAD_OPCODE, dst, rShift));
}
void shlrImm8r(int imm, RegisterID dst)
@@ -584,7 +577,29 @@ public:
oneShortOp(getOpcodeGroup2(SHLR16_OPCODE, dst));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+
+ void shalImm8r(int imm, RegisterID dst)
+ {
+ switch (imm) {
+ case 1:
+ oneShortOp(getOpcodeGroup2(SHAL_OPCODE, dst));
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+
+ void sharImm8r(int imm, RegisterID dst)
+ {
+ switch (imm) {
+ case 1:
+ oneShortOp(getOpcodeGroup2(SHAR_OPCODE, dst));
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -654,7 +669,7 @@ public:
oneShortOp(getOpcodeGroup1(CMPGT_OPCODE, left, right));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -731,7 +746,7 @@ public:
oneShortOp(getOpcodeGroup5(BF_OPCODE, label));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -751,7 +766,7 @@ public:
oneShortOp(getOpcodeGroup2(BSRF_OPCODE, reg));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -817,6 +832,12 @@ public:
oneShortOp(opc, true, false);
}
+ void fmovsRegReg(FPRegisterID src, FPRegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup1(FMOV_OPCODE, dst, src);
+ oneShortOp(opc, true, false);
+ }
+
void fmovsReadrm(RegisterID src, FPRegisterID dst)
{
uint16_t opc = getOpcodeGroup1(FMOVS_READ_RM_OPCODE, dst, src);
@@ -939,6 +960,12 @@ public:
oneShortOp(opc);
}
+ void dabs(FPRegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup7(FABS_OPCODE, dst >> 1);
+ oneShortOp(opc);
+ }
+
void dsqrt(FPRegisterID dst)
{
uint16_t opc = getOpcodeGroup7(FSQRT_OPCODE, dst >> 1);
@@ -1027,6 +1054,12 @@ public:
oneShortOp(opc);
}
+ void movwMemRegIn(RegisterID base, RegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup1(MOVW_READ_RMINC_OPCODE, dst, base);
+ oneShortOp(opc);
+ }
+
void movwPCReg(int offset, RegisterID base, RegisterID dst)
{
ASSERT(base == SH4Registers::pc);
@@ -1050,6 +1083,12 @@ public:
oneShortOp(opc);
}
+ void movwRegMemr0(RegisterID src, RegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup1(MOVW_WRITE_R0RN_OPCODE, dst, src);
+ oneShortOp(opc);
+ }
+
void movlRegMem(RegisterID src, int offset, RegisterID base)
{
ASSERT((offset <= 15) && (offset >= 0));
@@ -1116,6 +1155,18 @@ public:
oneShortOp(opc);
}
+ void movbMemRegIn(RegisterID base, RegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup1(MOVB_READ_RMINC_OPCODE, dst, base);
+ oneShortOp(opc);
+ }
+
+ void movbRegMemr0(RegisterID src, RegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup1(MOVB_WRITE_R0RN_OPCODE, dst, src);
+ oneShortOp(opc);
+ }
+
void movlMemReg(RegisterID base, RegisterID dst)
{
uint16_t opc = getOpcodeGroup1(MOVL_READ_RM_OPCODE, dst, base);
@@ -1140,14 +1191,6 @@ public:
oneShortOp(opc);
}
- void movlImm8r(int imm8, RegisterID dst)
- {
- ASSERT((imm8 <= 127) && (imm8 >= -128));
-
- uint16_t opc = getOpcodeGroup3(MOVIMM_OPCODE, dst, imm8);
- oneShortOp(opc);
- }
-
void loadConstant(uint32_t constant, RegisterID dst)
{
if (((int)constant <= 0x7f) && ((int)constant >= -0x80)) {
@@ -1259,10 +1302,25 @@ public:
return m_buffer.label();
}
- AssemblerLabel label()
+ AssemblerLabel labelForWatchpoint()
{
m_buffer.ensureSpaceForAnyInstruction();
- return m_buffer.label();
+ AssemblerLabel result = m_buffer.label();
+ if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
+ result = label();
+ m_indexOfLastWatchpoint = result.m_offset;
+ m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
+ return result;
+ }
+
+ AssemblerLabel label()
+ {
+ AssemblerLabel result = labelIgnoringWatchpoints();
+ while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
+ nop();
+ result = labelIgnoringWatchpoints();
+ }
+ return result;
}
int sizeOfConstantPool()
@@ -1282,12 +1340,14 @@ public:
static void changePCrelativeAddress(int offset, uint16_t* instructionPtr, uint32_t newAddress)
{
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
uint32_t address = (offset << 2) + ((reinterpret_cast<uint32_t>(instructionPtr) + 4) &(~0x3));
*reinterpret_cast<uint32_t*>(address) = newAddress;
}
static uint32_t readPCrelativeAddress(int offset, uint16_t* instructionPtr)
{
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
uint32_t address = (offset << 2) + ((reinterpret_cast<uint32_t>(instructionPtr) + 4) &(~0x3));
return *reinterpret_cast<uint32_t*>(address);
}
@@ -1325,17 +1385,9 @@ public:
braf @reg braf @reg
nop nop
*/
- ASSERT((*(instructionPtr + 1) & BRAF_OPCODE) == BRAF_OPCODE);
-
- offsetBits -= 4;
- if (offsetBits >= -4096 && offsetBits <= 4094) {
- *instructionPtr = getOpcodeGroup6(BRA_OPCODE, offsetBits >> 1);
- *(++instructionPtr) = NOP_OPCODE;
- printBlockInstr(instructionPtr - 1, from.m_offset, 2);
- return;
- }
-
- changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 2);
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
+ ASSERT((instructionPtr[1] & 0xf0ff) == BRAF_OPCODE);
+ changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 6);
printInstr(*instructionPtr, from.m_offset + 2);
}
@@ -1343,12 +1395,14 @@ public:
{
uint16_t* instructionPtr = getInstructionPtr(code, from.m_offset);
instructionPtr -= 3;
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, reinterpret_cast<uint32_t>(to));
}
static void linkPointer(void* code, AssemblerLabel where, void* value)
{
uint16_t* instructionPtr = getInstructionPtr(code, where.m_offset);
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, reinterpret_cast<uint32_t>(value));
}
@@ -1370,7 +1424,7 @@ public:
static SH4Buffer::TwoShorts placeConstantPoolBarrier(int offset)
{
- ASSERT(((offset >> 1) <=2047) && ((offset >> 1) >= -2048));
+ ASSERT(((offset >> 1) <= 2047) && ((offset >> 1) >= -2048));
SH4Buffer::TwoShorts m_barrier;
m_barrier.high = (BRA_OPCODE | (offset >> 1));
@@ -1392,7 +1446,7 @@ public:
ASSERT((((reinterpret_cast<uint32_t>(constPoolAddr) - reinterpret_cast<uint32_t>(loadAddr)) + index * 4)) < 1024);
int offset = reinterpret_cast<uint32_t>(constPoolAddr) + (index * 4) - ((reinterpret_cast<uint32_t>(instructionPtr) & ~0x03) + 4);
- instruction &=0xf00;
+ instruction &= 0x0f00;
instruction |= 0xd000;
offset &= 0x03ff;
instruction |= (offset >> 2);
@@ -1413,6 +1467,7 @@ public:
static void repatchInt32(void* where, int32_t value)
{
uint16_t* instructionPtr = reinterpret_cast<uint16_t*>(where);
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, value);
}
@@ -1428,6 +1483,7 @@ public:
{
uint16_t* instructionPtr = reinterpret_cast<uint16_t*>(from);
instructionPtr -= 3;
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, reinterpret_cast<uint32_t>(to));
}
@@ -1440,40 +1496,68 @@ public:
if (((*instructionPtr & 0xff00) == BT_OPCODE) || ((*instructionPtr & 0xff00) == BF_OPCODE)) {
offsetBits -= 8;
instructionPtr++;
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits);
instruction = (BRAF_OPCODE | (*instructionPtr++ & 0xf00));
*instructionPtr = instruction;
printBlockInstr(instructionPtr, reinterpret_cast<uint32_t>(from) + 1, 3);
+ cacheFlush(instructionPtr, sizeof(SH4Word));
return;
}
- ASSERT((*(instructionPtr + 1) & BRAF_OPCODE) == BRAF_OPCODE);
- offsetBits -= 4;
- if (offsetBits >= -4096 && offsetBits <= 4094) {
- *instructionPtr = getOpcodeGroup6(BRA_OPCODE, offsetBits >> 1);
- *(++instructionPtr) = NOP_OPCODE;
- printBlockInstr(instructionPtr - 2, reinterpret_cast<uint32_t>(from), 2);
- return;
- }
-
- changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 2);
+ ASSERT((instructionPtr[1] & 0xf0ff) == BRAF_OPCODE);
+ changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 6);
printInstr(*instructionPtr, reinterpret_cast<uint32_t>(from));
}
// Linking & patching
- static void revertJump(void* instructionStart, SH4Word imm)
+ static ptrdiff_t maxJumpReplacementSize()
{
- SH4Word *insn = reinterpret_cast<SH4Word*>(instructionStart);
- SH4Word disp;
+ return sizeof(SH4Word) * 6;
+ }
+ static void replaceWithJump(void *instructionStart, void *to)
+ {
+ SH4Word* instruction = reinterpret_cast<SH4Word*>(instructionStart);
+ intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + 2 * sizeof(SH4Word));
+
+ if ((instruction[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE) {
+ instruction[1] = (BRAF_OPCODE | (instruction[0] & 0x0f00));
+ instruction[2] = NOP_OPCODE;
+ cacheFlush(&instruction[1], 2 * sizeof(SH4Word));
+ } else {
+ instruction[0] = getOpcodeGroup3(MOVL_READ_OFFPC_OPCODE, SH4Registers::r13, 1);
+ instruction[1] = getOpcodeGroup2(BRAF_OPCODE, SH4Registers::r13);
+ instruction[2] = NOP_OPCODE;
+ cacheFlush(instruction, 3 * sizeof(SH4Word));
+ }
+
+ changePCrelativeAddress(instruction[0] & 0x00ff, instruction, difference - 2);
+ }
+
+ static void revertJumpToMove(void* instructionStart, RegisterID rd, int imm)
+ {
+ SH4Word *insn = reinterpret_cast<SH4Word*>(instructionStart);
ASSERT((insn[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
- disp = insn[0] & 0x00ff;
- insn += 2 + (disp << 1); // PC += 4 + (disp*4)
- insn = (SH4Word *) ((unsigned) insn & (~3));
- insn[0] = imm;
- cacheFlush(insn, sizeof(SH4Word));
+ if ((insn[1] & 0xf000) == CMPEQ_OPCODE) {
+ insn[0] = getOpcodeGroup3(MOVL_READ_OFFPC_OPCODE, SH4Registers::r13, insn[0] & 0x00ff);
+ insn[1] = (insn[1] & 0xf00f) | (rd << 8) | (SH4Registers::r13 << 4);
+ cacheFlush(insn, 2 * sizeof(SH4Word));
+ changePCrelativeAddress(insn[0] & 0x00ff, insn, imm);
+ return;
+ }
+
+ if ((insn[0] & 0x00ff) == 1)
+ insn[1] = getOpcodeGroup6(BRA_OPCODE, 3);
+ else
+ insn[1] = NOP_OPCODE;
+
+ insn[2] = NOP_OPCODE;
+ cacheFlush(&insn[1], 2 * sizeof(SH4Word));
+
+ changePCrelativeAddress(insn[0] & 0x00ff, insn, imm);
}
void linkJump(AssemblerLabel from, AssemblerLabel to, JumpType type = JumpFar)
@@ -1486,8 +1570,9 @@ public:
int offsetBits;
if (type == JumpNear) {
- ASSERT((instruction == BT_OPCODE) || (instruction == BF_OPCODE) || (instruction == BRA_OPCODE));
int offset = (codeSize() - from.m_offset) - 4;
+ ASSERT((((instruction == BT_OPCODE) || (instruction == BF_OPCODE)) && (offset >= -256) && (offset <= 254))
+ || ((instruction == BRA_OPCODE) && (offset >= -4096) && (offset <= 4094)));
*instructionPtr++ = instruction | (offset >> 1);
printInstr(*instructionPtr, from.m_offset + 2);
return;
@@ -1502,7 +1587,7 @@ public:
offsetBits = (to.m_offset - from.m_offset) - 8;
instruction ^= 0x0202;
*instructionPtr++ = instruction;
- if ((*instructionPtr & 0xf000) == 0xe000) {
+ if ((*instructionPtr & 0xf000) == MOVIMM_OPCODE) {
uint32_t* addr = getLdrImmAddressOnPool(instructionPtr, m_buffer.poolAddress());
*addr = offsetBits;
} else
@@ -1518,23 +1603,18 @@ public:
nop nop
*/
ASSERT((*(instructionPtr + 1) & BRAF_OPCODE) == BRAF_OPCODE);
- offsetBits = (to.m_offset - from.m_offset) - 4;
- if (offsetBits >= -4096 && offsetBits <= 4094) {
- *instructionPtr = getOpcodeGroup6(BRA_OPCODE, offsetBits >> 1);
- *(++instructionPtr) = NOP_OPCODE;
- printBlockInstr(instructionPtr - 1, from.m_offset, 2);
- return;
- }
+ offsetBits = (to.m_offset - from.m_offset) - 6;
instruction = *instructionPtr;
- if ((instruction & 0xf000) == 0xe000) {
+ if ((instruction & 0xf000) == MOVIMM_OPCODE) {
uint32_t* addr = getLdrImmAddressOnPool(instructionPtr, m_buffer.poolAddress());
- *addr = offsetBits - 2;
+ *addr = offsetBits;
printInstr(*instructionPtr, from.m_offset + 2);
return;
}
- changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 2);
+ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
+ changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits);
printInstr(*instructionPtr, from.m_offset + 2);
}
@@ -1575,19 +1655,27 @@ public:
return reinterpret_cast<void*>(readPCrelativeAddress((*instructionPtr & 0xff), instructionPtr));
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
{
- return m_buffer.executableCopy(globalData, ownerUID, effort);
+ return m_buffer.executableCopy(vm, ownerUID, effort);
}
static void cacheFlush(void* code, size_t size)
{
-#if !OS(LINUX)
-#error "The cacheFlush support is missing on this platform."
-#elif defined CACHEFLUSH_D_L2
- syscall(__NR_cacheflush, reinterpret_cast<unsigned>(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I | CACHEFLUSH_D_L2);
+#if OS(LINUX)
+ // Flush each page separately, otherwise the whole flush will fail if an uncommited page is in the area.
+ unsigned currentPage = reinterpret_cast<unsigned>(code) & ~(pageSize() - 1);
+ unsigned lastPage = (reinterpret_cast<unsigned>(code) + size - 1) & ~(pageSize() - 1);
+ do {
+#if defined CACHEFLUSH_D_L2
+ syscall(__NR_cacheflush, currentPage, pageSize(), CACHEFLUSH_D_WB | CACHEFLUSH_I | CACHEFLUSH_D_L2);
+#else
+ syscall(__NR_cacheflush, currentPage, pageSize(), CACHEFLUSH_D_WB | CACHEFLUSH_I);
+#endif
+ currentPage += pageSize();
+ } while (lastPage >= currentPage);
#else
- syscall(__NR_cacheflush, reinterpret_cast<unsigned>(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I);
+#error "The cacheFlush support is missing on this platform."
#endif
}
@@ -1619,6 +1707,8 @@ public:
void* data() const { return m_buffer.data(); }
size_t codeSize() const { return m_buffer.codeSize(); }
+ unsigned debugOffset() { return m_buffer.debugOffset(); }
+
#ifdef SH4_ASSEMBLER_TRACING
static void printInstr(uint16_t opc, unsigned size, bool isdoubleInst = true)
{
@@ -1763,6 +1853,9 @@ public:
case FTRC_OPCODE:
format = " FTRC FR%d, FPUL\n";
break;
+ case FABS_OPCODE:
+ format = " FABS FR%d\n";
+ break;
case FSQRT_OPCODE:
format = " FSQRT FR%d\n";
break;
@@ -1897,9 +1990,15 @@ public:
case MOVW_READ_RM_OPCODE:
format = " MOV.W @R%d, R%d\n";
break;
+ case MOVW_READ_RMINC_OPCODE:
+ format = " MOV.W @R%d+, R%d\n";
+ break;
case MOVW_READ_R0RM_OPCODE:
format = " MOV.W @(R0, R%d), R%d\n";
break;
+ case MOVW_WRITE_R0RN_OPCODE:
+ format = " MOV.W R%d, @(R0, R%d)\n";
+ break;
case EXTUB_OPCODE:
format = " EXTU.B R%d, R%d\n";
break;
@@ -2143,6 +2242,8 @@ public:
private:
SH4Buffer m_buffer;
int m_claimscratchReg;
+ int m_indexOfLastWatchpoint;
+ int m_indexOfTailOfLastWatchpoint;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index 25ff6f0a5..2883e0a4c 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -1952,7 +1952,7 @@ public:
*ptr = OP_MOV_GvEv;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -1970,7 +1970,7 @@ public:
case OP_LEA:
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -1991,9 +1991,9 @@ public:
return b.m_offset - a.m_offset;
}
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
{
- return m_formatter.executableCopy(globalData, ownerUID, effort);
+ return m_formatter.executableCopy(vm, ownerUID, effort);
}
unsigned debugOffset() { return m_formatter.debugOffset(); }
@@ -2349,9 +2349,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, JITCompilationEffort effort)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(VM& vm, void* ownerUID, JITCompilationEffort effort)
{
- return m_buffer.executableCopy(globalData, ownerUID, effort);
+ return m_buffer.executableCopy(vm, ownerUID, effort);
}
unsigned debugOffset() { return m_buffer.debugOffset(); }
diff --git a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp
index aa682da86..6d9afda28 100644
--- a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "ArrayAllocationProfile.h"
+#include "Operations.h"
+
namespace JSC {
void ArrayAllocationProfile::updateIndexingType()
diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
index 51baf332f..ae3c8f94a 100644
--- a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
@@ -28,41 +28,50 @@
#include "CodeBlock.h"
#include <wtf/StringExtras.h>
+#include <wtf/StringPrintStream.h>
namespace JSC {
-const char* arrayModesToString(ArrayModes arrayModes)
+void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
{
- if (!arrayModes)
- return "0:<empty>";
+ if (!arrayModes) {
+ out.print("0:<empty>");
+ return;
+ }
- if (arrayModes == ALL_ARRAY_MODES)
- return "TOP";
-
- bool isNonArray = !!(arrayModes & asArrayModes(NonArray));
- bool isNonArrayWithContiguous = !!(arrayModes & asArrayModes(NonArrayWithContiguous));
- bool isNonArrayWithArrayStorage = !!(arrayModes & asArrayModes(NonArrayWithArrayStorage));
- bool isNonArrayWithSlowPutArrayStorage = !!(arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage));
- bool isArray = !!(arrayModes & asArrayModes(ArrayClass));
- bool isArrayWithContiguous = !!(arrayModes & asArrayModes(ArrayWithContiguous));
- bool isArrayWithArrayStorage = !!(arrayModes & asArrayModes(ArrayWithArrayStorage));
- bool isArrayWithSlowPutArrayStorage = !!(arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage));
-
- static char result[256];
- snprintf(
- result, sizeof(result),
- "%u:%s%s%s%s%s%s%s%s",
- arrayModes,
- isNonArray ? "NonArray" : "",
- isNonArrayWithContiguous ? "NonArrayWithContiguous" : "",
- isNonArrayWithArrayStorage ? " NonArrayWithArrayStorage" : "",
- isNonArrayWithSlowPutArrayStorage ? "NonArrayWithSlowPutArrayStorage" : "",
- isArray ? "ArrayClass" : "",
- isArrayWithContiguous ? "ArrayWithContiguous" : "",
- isArrayWithArrayStorage ? " ArrayWithArrayStorage" : "",
- isArrayWithSlowPutArrayStorage ? "ArrayWithSlowPutArrayStorage" : "");
-
- return result;
+ if (arrayModes == ALL_ARRAY_MODES) {
+ out.print("TOP");
+ return;
+ }
+
+ out.print(arrayModes, ":");
+
+ if (arrayModes & asArrayModes(NonArray))
+ out.print("NonArray");
+ if (arrayModes & asArrayModes(NonArrayWithInt32))
+ out.print("NonArrayWithInt32");
+ if (arrayModes & asArrayModes(NonArrayWithDouble))
+ out.print("NonArrayWithDouble");
+ if (arrayModes & asArrayModes(NonArrayWithContiguous))
+ out.print("NonArrayWithContiguous");
+ if (arrayModes & asArrayModes(NonArrayWithArrayStorage))
+ out.print("NonArrayWithArrayStorage");
+ if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage))
+ out.print("NonArrayWithSlowPutArrayStorage");
+ if (arrayModes & asArrayModes(ArrayClass))
+ out.print("ArrayClass");
+ if (arrayModes & asArrayModes(ArrayWithUndecided))
+ out.print("ArrayWithUndecided");
+ if (arrayModes & asArrayModes(ArrayWithInt32))
+ out.print("ArrayWithInt32");
+ if (arrayModes & asArrayModes(ArrayWithDouble))
+ out.print("ArrayWithDouble");
+ if (arrayModes & asArrayModes(ArrayWithContiguous))
+ out.print("ArrayWithContiguous");
+ if (arrayModes & asArrayModes(ArrayWithArrayStorage))
+ out.print("ArrayWithArrayStorage");
+ if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
+ out.print("ArrayWithSlowPutArrayStorage");
}
ArrayModes ArrayProfile::updatedObservedArrayModes() const
@@ -74,34 +83,99 @@ ArrayModes ArrayProfile::updatedObservedArrayModes() const
void ArrayProfile::computeUpdatedPrediction(CodeBlock* codeBlock, OperationInProgress operation)
{
+ const bool verbose = false;
+
if (m_lastSeenStructure) {
m_observedArrayModes |= arrayModeFromStructure(m_lastSeenStructure);
m_mayInterceptIndexedAccesses |=
m_lastSeenStructure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero();
if (!codeBlock->globalObject()->isOriginalArrayStructure(m_lastSeenStructure))
m_usesOriginalArrayStructures = false;
- if (!m_structureIsPolymorphic) {
+ if (!structureIsPolymorphic()) {
if (!m_expectedStructure)
m_expectedStructure = m_lastSeenStructure;
else if (m_expectedStructure != m_lastSeenStructure) {
- m_expectedStructure = 0;
- m_structureIsPolymorphic = true;
+ if (verbose)
+ dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure polymorphic because ", RawPointer(m_expectedStructure), " (", m_expectedStructure->classInfo()->className, ") != ", RawPointer(m_lastSeenStructure), " (", m_lastSeenStructure->classInfo()->className, ")\n");
+ m_expectedStructure = polymorphicStructure();
}
}
m_lastSeenStructure = 0;
}
if (hasTwoOrMoreBitsSet(m_observedArrayModes)) {
- m_structureIsPolymorphic = true;
- m_expectedStructure = 0;
+ if (verbose)
+ dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure polymorphic because two or more bits are set in m_observedArrayModes\n");
+ m_expectedStructure = polymorphicStructure();
}
if (operation == Collection
- && m_expectedStructure
+ && expectedStructure()
&& !Heap::isMarked(m_expectedStructure)) {
- m_expectedStructure = 0;
- m_structureIsPolymorphic = true;
+ if (verbose)
+ dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure during GC\n");
+ m_expectedStructure = polymorphicStructure();
+ }
+}
+
+CString ArrayProfile::briefDescription(CodeBlock* codeBlock)
+{
+ computeUpdatedPrediction(codeBlock);
+
+ StringPrintStream out;
+
+ bool hasPrinted = false;
+
+ if (m_observedArrayModes) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print(ArrayModesDump(m_observedArrayModes));
+ hasPrinted = true;
}
+
+ if (structureIsPolymorphic()) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print("struct = TOP");
+ hasPrinted = true;
+ } else if (m_expectedStructure) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print("struct = ", RawPointer(m_expectedStructure));
+ hasPrinted = true;
+ }
+
+ if (m_mayStoreToHole) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print("Hole");
+ hasPrinted = true;
+ }
+
+ if (m_outOfBounds) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print("OutOfBounds");
+ hasPrinted = true;
+ }
+
+ if (m_mayInterceptIndexedAccesses) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print("Intercept");
+ hasPrinted = true;
+ }
+
+ if (m_usesOriginalArrayStructures) {
+ if (hasPrinted)
+ out.print(", ");
+ out.print("Original");
+ hasPrinted = true;
+ }
+
+ UNUSED_PARAM(hasPrinted);
+
+ return out.toCString();
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.h b/Source/JavaScriptCore/bytecode/ArrayProfile.h
index 5116cd36f..384275689 100644
--- a/Source/JavaScriptCore/bytecode/ArrayProfile.h
+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.h
@@ -67,7 +67,8 @@ inline ArrayModes arrayModeFromStructure(Structure* structure)
return asArrayModes(structure->indexingType());
}
-const char* arrayModesToString(ArrayModes);
+void dumpArrayModes(PrintStream&, ArrayModes);
+MAKE_PRINT_ADAPTOR(ArrayModesDump, ArrayModes, dumpArrayModes);
inline bool mergeArrayModes(ArrayModes& left, ArrayModes right)
{
@@ -114,14 +115,24 @@ inline bool shouldUseInt32(ArrayModes arrayModes)
return arrayModesInclude(arrayModes, Int32Shape);
}
+inline bool hasSeenArray(ArrayModes arrayModes)
+{
+ return arrayModes & ALL_ARRAY_ARRAY_MODES;
+}
+
+inline bool hasSeenNonArray(ArrayModes arrayModes)
+{
+ return arrayModes & ALL_NON_ARRAY_ARRAY_MODES;
+}
+
class ArrayProfile {
public:
ArrayProfile()
: m_bytecodeOffset(std::numeric_limits<unsigned>::max())
, m_lastSeenStructure(0)
, m_expectedStructure(0)
- , m_structureIsPolymorphic(false)
, m_mayStoreToHole(false)
+ , m_outOfBounds(false)
, m_mayInterceptIndexedAccesses(false)
, m_usesOriginalArrayStructures(true)
, m_observedArrayModes(0)
@@ -132,8 +143,8 @@ public:
: m_bytecodeOffset(bytecodeOffset)
, m_lastSeenStructure(0)
, m_expectedStructure(0)
- , m_structureIsPolymorphic(false)
, m_mayStoreToHole(false)
+ , m_outOfBounds(false)
, m_mayInterceptIndexedAccesses(false)
, m_usesOriginalArrayStructures(true)
, m_observedArrayModes(0)
@@ -145,6 +156,7 @@ public:
Structure** addressOfLastSeenStructure() { return &m_lastSeenStructure; }
ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; }
bool* addressOfMayStoreToHole() { return &m_mayStoreToHole; }
+ bool* addressOfOutOfBounds() { return &m_outOfBounds; }
void observeStructure(Structure* structure)
{
@@ -153,10 +165,15 @@ public:
void computeUpdatedPrediction(CodeBlock*, OperationInProgress = NoOperation);
- Structure* expectedStructure() const { return m_expectedStructure; }
+ Structure* expectedStructure() const
+ {
+ if (structureIsPolymorphic())
+ return 0;
+ return m_expectedStructure;
+ }
bool structureIsPolymorphic() const
{
- return m_structureIsPolymorphic;
+ return m_expectedStructure == polymorphicStructure();
}
bool hasDefiniteStructure() const
{
@@ -167,17 +184,22 @@ public:
bool mayInterceptIndexedAccesses() const { return m_mayInterceptIndexedAccesses; }
bool mayStoreToHole() const { return m_mayStoreToHole; }
+ bool outOfBounds() const { return m_outOfBounds; }
bool usesOriginalArrayStructures() const { return m_usesOriginalArrayStructures; }
+ CString briefDescription(CodeBlock*);
+
private:
friend class LLIntOffsetsExtractor;
+ static Structure* polymorphicStructure() { return static_cast<Structure*>(reinterpret_cast<void*>(1)); }
+
unsigned m_bytecodeOffset;
Structure* m_lastSeenStructure;
Structure* m_expectedStructure;
- bool m_structureIsPolymorphic;
bool m_mayStoreToHole; // This flag may become overloaded to indicate other special cases that were encountered during array access, as it depends on indexing type. Since we currently have basically just one indexing type (two variants of ArrayStorage), this flag for now just means exactly what its name implies.
+ bool m_outOfBounds;
bool m_mayInterceptIndexedAccesses;
bool m_usesOriginalArrayStructures;
ArrayModes m_observedArrayModes;
diff --git a/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp b/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
index 762dca12a..5b2661f06 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
@@ -33,19 +33,19 @@
#if ENABLE(JIT)
namespace JSC {
-void CallLinkInfo::unlink(JSGlobalData& globalData, RepatchBuffer& repatchBuffer)
+void CallLinkInfo::unlink(VM& vm, RepatchBuffer& repatchBuffer)
{
ASSERT(isLinked());
repatchBuffer.revertJumpReplacementToBranchPtrWithPatch(RepatchBuffer::startOfBranchPtrWithPatchOnRegister(hotPathBegin), static_cast<MacroAssembler::RegisterID>(calleeGPR), 0);
if (isDFG) {
#if ENABLE(DFG_JIT)
- repatchBuffer.relink(callReturnLocation, (callType == Construct ? globalData.getCTIStub(DFG::linkConstructThunkGenerator) : globalData.getCTIStub(DFG::linkCallThunkGenerator)).code());
+ repatchBuffer.relink(callReturnLocation, (callType == Construct ? vm.getCTIStub(DFG::linkConstructThunkGenerator) : vm.getCTIStub(DFG::linkCallThunkGenerator)).code());
#else
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif
} else
- repatchBuffer.relink(callReturnLocation, callType == Construct ? globalData.jitStubs->ctiVirtualConstructLink() : globalData.jitStubs->ctiVirtualCallLink());
+ repatchBuffer.relink(callReturnLocation, callType == Construct ? vm.getCTIStub(linkConstructGenerator).code() : vm.getCTIStub(linkCallGenerator).code());
hasSeenShouldRepatch = false;
callee.clear();
stub.clear();
diff --git a/Source/JavaScriptCore/bytecode/CallLinkInfo.h b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
index 57608435c..36eb84bee 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkInfo.h
+++ b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
@@ -57,6 +57,7 @@ struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
CallLinkInfo()
: hasSeenShouldRepatch(false)
, isDFG(false)
+ , hasSeenClosure(false)
, callType(None)
{
}
@@ -80,12 +81,13 @@ struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
RefPtr<ClosureCallStubRoutine> stub;
bool hasSeenShouldRepatch : 1;
bool isDFG : 1;
- CallType callType : 6;
+ bool hasSeenClosure : 1;
+ CallType callType : 5;
unsigned calleeGPR : 8;
CodeOrigin codeOrigin;
bool isLinked() { return stub || callee; }
- void unlink(JSGlobalData&, RepatchBuffer&);
+ void unlink(VM&, RepatchBuffer&);
bool seenOnce()
{
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
index 7f9e9ee8a..509b15aaf 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,9 +28,59 @@
#include "CodeBlock.h"
#include "LLIntCallLinkInfo.h"
+#include "Operations.h"
+#include <wtf/CommaPrinter.h>
namespace JSC {
+CallLinkStatus::CallLinkStatus(JSValue value)
+ : m_callTarget(value)
+ , m_executable(0)
+ , m_structure(0)
+ , m_couldTakeSlowPath(false)
+ , m_isProved(false)
+{
+ if (!value || !value.isCell())
+ return;
+
+ m_structure = value.asCell()->structure();
+
+ if (!value.asCell()->inherits(&JSFunction::s_info))
+ return;
+
+ m_executable = jsCast<JSFunction*>(value.asCell())->executable();
+}
+
+JSFunction* CallLinkStatus::function() const
+{
+ if (!m_callTarget || !m_callTarget.isCell())
+ return 0;
+
+ if (!m_callTarget.asCell()->inherits(&JSFunction::s_info))
+ return 0;
+
+ return jsCast<JSFunction*>(m_callTarget.asCell());
+}
+
+InternalFunction* CallLinkStatus::internalFunction() const
+{
+ if (!m_callTarget || !m_callTarget.isCell())
+ return 0;
+
+ if (!m_callTarget.asCell()->inherits(&InternalFunction::s_info))
+ return 0;
+
+ return jsCast<InternalFunction*>(m_callTarget.asCell());
+}
+
+Intrinsic CallLinkStatus::intrinsicFor(CodeSpecializationKind kind) const
+{
+ if (!m_executable)
+ return NoIntrinsic;
+
+ return m_executable->intrinsicFor(kind);
+}
+
CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex)
{
UNUSED_PARAM(profiledBlock);
@@ -39,9 +89,9 @@ CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsign
Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo;
- return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false);
+ return CallLinkStatus(callLinkInfo->lastSeenCallee.get());
#else
- return CallLinkStatus(0, false);
+ return CallLinkStatus();
#endif
}
@@ -54,17 +104,49 @@ CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned byt
return computeFromLLInt(profiledBlock, bytecodeIndex);
if (profiledBlock->couldTakeSlowCase(bytecodeIndex))
- return CallLinkStatus(0, true);
+ return CallLinkStatus::takesSlowPath();
- JSFunction* target = profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get();
+ CallLinkInfo& callLinkInfo = profiledBlock->getCallLinkInfo(bytecodeIndex);
+ if (callLinkInfo.stub)
+ return CallLinkStatus(callLinkInfo.stub->executable(), callLinkInfo.stub->structure());
+
+ JSFunction* target = callLinkInfo.lastSeenCallee.get();
if (!target)
return computeFromLLInt(profiledBlock, bytecodeIndex);
- return CallLinkStatus(target, false);
+ if (callLinkInfo.hasSeenClosure)
+ return CallLinkStatus(target->executable(), target->structure());
+
+ return CallLinkStatus(target);
#else
- return CallLinkStatus(0, false);
+ return CallLinkStatus();
#endif
}
+void CallLinkStatus::dump(PrintStream& out) const
+{
+ if (!isSet()) {
+ out.print("Not Set");
+ return;
+ }
+
+ CommaPrinter comma;
+
+ if (m_isProved)
+ out.print(comma, "Statically Proved");
+
+ if (m_couldTakeSlowPath)
+ out.print(comma, "Could Take Slow Path");
+
+ if (m_callTarget)
+ out.print(comma, "Known target: ", m_callTarget);
+
+ if (m_executable)
+ out.print(comma, "Executable/CallHash: ", RawPointer(m_executable), "/", m_executable->hashFor(CodeForCall));
+
+ if (m_structure)
+ out.print(comma, "Structure: ", RawPointer(m_structure));
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/CallLinkStatus.h b/Source/JavaScriptCore/bytecode/CallLinkStatus.h
index 5f7201905..51965fe4a 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkStatus.h
+++ b/Source/JavaScriptCore/bytecode/CallLinkStatus.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,40 +26,106 @@
#ifndef CallLinkStatus_h
#define CallLinkStatus_h
+#include "CodeSpecializationKind.h"
+#include "Intrinsic.h"
+#include "JSCJSValue.h"
+
namespace JSC {
-class JSFunction;
class CodeBlock;
+class ExecutableBase;
+class InternalFunction;
+class JSFunction;
+class Structure;
class CallLinkStatus {
public:
CallLinkStatus()
- : m_callTarget(0)
+ : m_executable(0)
+ , m_structure(0)
+ , m_couldTakeSlowPath(false)
+ , m_isProved(false)
+ {
+ }
+
+ static CallLinkStatus takesSlowPath()
+ {
+ CallLinkStatus result;
+ result.m_couldTakeSlowPath = true;
+ return result;
+ }
+
+ explicit CallLinkStatus(JSValue);
+
+ CallLinkStatus(ExecutableBase* executable, Structure* structure)
+ : m_executable(executable)
+ , m_structure(structure)
, m_couldTakeSlowPath(false)
+ , m_isProved(false)
{
+ ASSERT(!!executable == !!structure);
}
- CallLinkStatus(JSFunction* callTarget, bool couldTakeSlowPath)
- : m_callTarget(callTarget)
- , m_couldTakeSlowPath(couldTakeSlowPath)
+ CallLinkStatus& setIsProved(bool isProved)
{
+ m_isProved = isProved;
+ return *this;
}
static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex);
- bool isSet() const { return !!m_callTarget || m_couldTakeSlowPath; }
+ CallLinkStatus& setHasBadFunctionExitSite(bool didHaveExitSite)
+ {
+ ASSERT(!m_isProved);
+ if (didHaveExitSite) {
+ // Turn this into a closure call.
+ m_callTarget = JSValue();
+ }
+ return *this;
+ }
+
+ CallLinkStatus& setHasBadCacheExitSite(bool didHaveExitSite)
+ {
+ ASSERT(!m_isProved);
+ if (didHaveExitSite)
+ *this = takesSlowPath();
+ return *this;
+ }
+
+ CallLinkStatus& setHasBadExecutableExitSite(bool didHaveExitSite)
+ {
+ ASSERT(!m_isProved);
+ if (didHaveExitSite)
+ *this = takesSlowPath();
+ return *this;
+ }
+
+ bool isSet() const { return m_callTarget || m_executable || m_couldTakeSlowPath; }
bool operator!() const { return !isSet(); }
bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
+ bool isClosureCall() const { return m_executable && !m_callTarget; }
+
+ JSValue callTarget() const { return m_callTarget; }
+ JSFunction* function() const;
+ InternalFunction* internalFunction() const;
+ Intrinsic intrinsicFor(CodeSpecializationKind) const;
+ ExecutableBase* executable() const { return m_executable; }
+ Structure* structure() const { return m_structure; }
+ bool isProved() const { return m_isProved; }
+ bool canOptimize() const { return (m_callTarget || m_executable) && !m_couldTakeSlowPath; }
- JSFunction* callTarget() const { return m_callTarget; }
+ void dump(PrintStream&) const;
private:
static CallLinkStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex);
- JSFunction* m_callTarget;
+ JSValue m_callTarget;
+ ExecutableBase* m_executable;
+ Structure* m_structure;
bool m_couldTakeSlowPath;
+ bool m_isProved;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index fe9f6ac7c..904e40a4c 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
#include "CodeBlock.h"
#include "BytecodeGenerator.h"
+#include "CallLinkStatus.h"
#include "DFGCapabilities.h"
#include "DFGCommon.h"
#include "DFGNode.h"
@@ -40,15 +41,18 @@
#include "JIT.h"
#include "JITStubs.h"
#include "JSActivation.h"
+#include "JSCJSValue.h"
#include "JSFunction.h"
#include "JSNameScope.h"
-#include "JSValue.h"
#include "LowLevelInterpreter.h"
+#include "Operations.h"
+#include "ReduceWhitespace.h"
#include "RepatchBuffer.h"
#include "SlotVisitorInlines.h"
#include <stdio.h>
+#include <wtf/CommaPrinter.h>
#include <wtf/StringExtras.h>
-#include <wtf/UnusedParam.h>
+#include <wtf/StringPrintStream.h>
#if ENABLE(DFG_JIT)
#include "DFGOperations.h"
@@ -62,16 +66,57 @@ namespace JSC {
using namespace DFG;
#endif
+String CodeBlock::inferredName() const
+{
+ switch (codeType()) {
+ case GlobalCode:
+ return "<global>";
+ case EvalCode:
+ return "<eval>";
+ case FunctionCode:
+ return jsCast<FunctionExecutable*>(ownerExecutable())->inferredName().string();
+ default:
+ CRASH();
+ return String();
+ }
+}
+
CodeBlockHash CodeBlock::hash() const
{
return CodeBlockHash(ownerExecutable()->source(), specializationKind());
}
+String CodeBlock::sourceCodeForTools() const
+{
+ if (codeType() != FunctionCode)
+ return ownerExecutable()->source().toString();
+
+ SourceProvider* provider = source();
+ FunctionExecutable* executable = jsCast<FunctionExecutable*>(ownerExecutable());
+ UnlinkedFunctionExecutable* unlinked = executable->unlinkedExecutable();
+ unsigned unlinkedStartOffset = unlinked->startOffset();
+ unsigned linkedStartOffset = executable->source().startOffset();
+ int delta = linkedStartOffset - unlinkedStartOffset;
+ StringBuilder builder;
+ builder.append("function ");
+ builder.append(provider->getRange(
+ delta + unlinked->functionStartOffset(),
+ delta + unlinked->startOffset() + unlinked->sourceLength()));
+ return builder.toString();
+}
+
+String CodeBlock::sourceCodeOnOneLine() const
+{
+ return reduceWhitespace(sourceCodeForTools());
+}
+
void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const
{
- out.print("#", hash(), ":[", RawPointer(this), ", ", jitType, codeType());
+ out.print(inferredName(), "#", hash(), ":[", RawPointer(this), "->", RawPointer(ownerExecutable()), ", ", jitType, codeType());
if (codeType() == FunctionCode)
out.print(specializationKind());
+ if (ownerExecutable()->neverInline())
+ out.print(" (NeverInline)");
out.print("]");
}
@@ -99,7 +144,7 @@ static String valueToSourceString(ExecState* exec, JSValue val)
if (val.isString())
return makeString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\"");
- return val.description();
+ return toString(val);
}
static CString constantName(ExecState* exec, int k, JSValue value)
@@ -112,18 +157,6 @@ static CString idName(int id0, const Identifier& ident)
return makeString(ident.string(), "(@id", String::number(id0), ")").utf8();
}
-void CodeBlock::dumpBytecodeCommentAndNewLine(int location)
-{
-#if ENABLE(BYTECODE_COMMENTS)
- const char* comment = commentForBytecodeOffset(location);
- if (comment)
- dataLogF("\t\t ; %s", comment);
-#else
- UNUSED_PARAM(location);
-#endif
- dataLogF("\n");
-}
-
CString CodeBlock::registerName(ExecState* exec, int r) const
{
if (r == missingThisObjectMarker())
@@ -178,37 +211,34 @@ NEVER_INLINE static const char* debugHookName(int debugHookID)
return "didReachBreakpoint";
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return "";
}
-void CodeBlock::printUnaryOp(ExecState* exec, int location, const Instruction*& it, const char* op)
+void CodeBlock::printUnaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
{
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] %s\t\t %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] %s\t\t %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data());
}
-void CodeBlock::printBinaryOp(ExecState* exec, int location, const Instruction*& it, const char* op)
+void CodeBlock::printBinaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
{
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] %s\t\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] %s\t\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
}
-void CodeBlock::printConditionalJump(ExecState* exec, const Instruction*, const Instruction*& it, int location, const char* op)
+void CodeBlock::printConditionalJump(PrintStream& out, ExecState* exec, const Instruction*, const Instruction*& it, int location, const char* op)
{
int r0 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] %s\t\t %s, %d(->%d)", location, op, registerName(exec, r0).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] %s\t\t %s, %d(->%d)", location, op, registerName(exec, r0).data(), offset, location + offset);
}
-void CodeBlock::printGetByIdOp(ExecState* exec, int location, const Instruction*& it)
+void CodeBlock::printGetByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it)
{
const char* op;
switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
@@ -255,34 +285,34 @@ void CodeBlock::printGetByIdOp(ExecState* exec, int location, const Instruction*
op = "string_length";
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
op = 0;
}
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int id0 = (++it)->u.operand;
- dataLogF("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
- it += 5;
+ out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
+ it += 4; // Increment up to the value profiler.
}
#if ENABLE(JIT) || ENABLE(LLINT) // unused in some configurations
-static void dumpStructure(const char* name, ExecState* exec, Structure* structure, Identifier& ident)
+static void dumpStructure(PrintStream& out, const char* name, ExecState* exec, Structure* structure, Identifier& ident)
{
if (!structure)
return;
- dataLogF("%s = %p", name, structure);
+ out.printf("%s = %p", name, structure);
- PropertyOffset offset = structure->get(exec->globalData(), ident);
+ PropertyOffset offset = structure->get(exec->vm(), ident);
if (offset != invalidOffset)
- dataLogF(" (offset = %d)", offset);
+ out.printf(" (offset = %d)", offset);
}
#endif
#if ENABLE(JIT) // unused when not ENABLE(JIT), leading to silly warnings
-static void dumpChain(ExecState* exec, StructureChain* chain, Identifier& ident)
+static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain, Identifier& ident)
{
- dataLogF("chain = %p: [", chain);
+ out.printf("chain = %p: [", chain);
bool first = true;
for (WriteBarrier<Structure>* currentStructure = chain->head();
*currentStructure;
@@ -290,14 +320,14 @@ static void dumpChain(ExecState* exec, StructureChain* chain, Identifier& ident)
if (first)
first = false;
else
- dataLogF(", ");
- dumpStructure("struct", exec, currentStructure->get(), ident);
+ out.printf(", ");
+ dumpStructure(out, "struct", exec, currentStructure->get(), ident);
}
- dataLogF("]");
+ out.printf("]");
}
#endif
-void CodeBlock::printGetByIdCacheStatus(ExecState* exec, int location)
+void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int location)
{
Instruction* instruction = instructions().begin() + location;
@@ -307,22 +337,20 @@ void CodeBlock::printGetByIdCacheStatus(ExecState* exec, int location)
#if ENABLE(LLINT)
if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_array_length)
- dataLogF(" llint(array_length)");
- else {
- Structure* structure = instruction[4].u.structure.get();
- dataLogF(" llint(");
- dumpStructure("struct", exec, structure, ident);
- dataLogF(")");
+ out.printf(" llint(array_length)");
+ else if (Structure* structure = instruction[4].u.structure.get()) {
+ out.printf(" llint(");
+ dumpStructure(out, "struct", exec, structure, ident);
+ out.printf(")");
}
#endif
#if ENABLE(JIT)
if (numberOfStructureStubInfos()) {
- dataLogF(" jit(");
StructureStubInfo& stubInfo = getStubInfo(location);
- if (!stubInfo.seen)
- dataLogF("not seen");
- else {
+ if (stubInfo.seen) {
+ out.printf(" jit(");
+
Structure* baseStructure = 0;
Structure* prototypeStructure = 0;
StructureChain* chain = 0;
@@ -331,166 +359,163 @@ void CodeBlock::printGetByIdCacheStatus(ExecState* exec, int location)
switch (stubInfo.accessType) {
case access_get_by_id_self:
- dataLogF("self");
+ out.printf("self");
baseStructure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
break;
case access_get_by_id_proto:
- dataLogF("proto");
+ out.printf("proto");
baseStructure = stubInfo.u.getByIdProto.baseObjectStructure.get();
prototypeStructure = stubInfo.u.getByIdProto.prototypeStructure.get();
break;
case access_get_by_id_chain:
- dataLogF("chain");
+ out.printf("chain");
baseStructure = stubInfo.u.getByIdChain.baseObjectStructure.get();
chain = stubInfo.u.getByIdChain.chain.get();
break;
case access_get_by_id_self_list:
- dataLogF("self_list");
+ out.printf("self_list");
structureList = stubInfo.u.getByIdSelfList.structureList;
listSize = stubInfo.u.getByIdSelfList.listSize;
break;
case access_get_by_id_proto_list:
- dataLogF("proto_list");
+ out.printf("proto_list");
structureList = stubInfo.u.getByIdProtoList.structureList;
listSize = stubInfo.u.getByIdProtoList.listSize;
break;
case access_unset:
- dataLogF("unset");
+ out.printf("unset");
break;
case access_get_by_id_generic:
- dataLogF("generic");
+ out.printf("generic");
break;
case access_get_array_length:
- dataLogF("array_length");
+ out.printf("array_length");
break;
case access_get_string_length:
- dataLogF("string_length");
+ out.printf("string_length");
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
if (baseStructure) {
- dataLogF(", ");
- dumpStructure("struct", exec, baseStructure, ident);
+ out.printf(", ");
+ dumpStructure(out, "struct", exec, baseStructure, ident);
}
if (prototypeStructure) {
- dataLogF(", ");
- dumpStructure("prototypeStruct", exec, baseStructure, ident);
+ out.printf(", ");
+ dumpStructure(out, "prototypeStruct", exec, baseStructure, ident);
}
if (chain) {
- dataLogF(", ");
- dumpChain(exec, chain, ident);
+ out.printf(", ");
+ dumpChain(out, exec, chain, ident);
}
if (structureList) {
- dataLogF(", list = %p: [", structureList);
+ out.printf(", list = %p: [", structureList);
for (int i = 0; i < listSize; ++i) {
if (i)
- dataLogF(", ");
- dataLogF("(");
- dumpStructure("base", exec, structureList->list[i].base.get(), ident);
+ out.printf(", ");
+ out.printf("(");
+ dumpStructure(out, "base", exec, structureList->list[i].base.get(), ident);
if (structureList->list[i].isChain) {
if (structureList->list[i].u.chain.get()) {
- dataLogF(", ");
- dumpChain(exec, structureList->list[i].u.chain.get(), ident);
+ out.printf(", ");
+ dumpChain(out, exec, structureList->list[i].u.chain.get(), ident);
}
} else {
if (structureList->list[i].u.proto.get()) {
- dataLogF(", ");
- dumpStructure("proto", exec, structureList->list[i].u.proto.get(), ident);
+ out.printf(", ");
+ dumpStructure(out, "proto", exec, structureList->list[i].u.proto.get(), ident);
}
}
- dataLogF(")");
+ out.printf(")");
}
- dataLogF("]");
+ out.printf("]");
}
+ out.printf(")");
}
- dataLogF(")");
}
#endif
}
-void CodeBlock::printCallOp(ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode)
+void CodeBlock::printCallOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode)
{
int func = (++it)->u.operand;
int argCount = (++it)->u.operand;
int registerOffset = (++it)->u.operand;
- dataLogF("[%4d] %s\t %s, %d, %d", location, op, registerName(exec, func).data(), argCount, registerOffset);
+ out.printf("[%4d] %s\t %s, %d, %d", location, op, registerName(exec, func).data(), argCount, registerOffset);
if (cacheDumpMode == DumpCaches) {
#if ENABLE(LLINT)
LLIntCallLinkInfo* callLinkInfo = it[1].u.callLinkInfo;
if (callLinkInfo->lastSeenCallee) {
- dataLogF(" llint(%p, exec %p)",
- callLinkInfo->lastSeenCallee.get(),
- callLinkInfo->lastSeenCallee->executable());
- } else
- dataLogF(" llint(not set)");
+ out.printf(
+ " llint(%p, exec %p)",
+ callLinkInfo->lastSeenCallee.get(),
+ callLinkInfo->lastSeenCallee->executable());
+ }
#endif
#if ENABLE(JIT)
if (numberOfCallLinkInfos()) {
JSFunction* target = getCallLinkInfo(location).lastSeenCallee.get();
if (target)
- dataLogF(" jit(%p, exec %p)", target, target->executable());
- else
- dataLogF(" jit(not set)");
+ out.printf(" jit(%p, exec %p)", target, target->executable());
}
#endif
+ out.print(" status(", CallLinkStatus::computeFor(this, location), ")");
}
- dumpBytecodeCommentAndNewLine(location);
it += 2;
}
-void CodeBlock::printPutByIdOp(ExecState* exec, int location, const Instruction*& it, const char* op)
+void CodeBlock::printPutByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
{
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
it += 5;
}
-void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand)
+void CodeBlock::printStructure(PrintStream& out, const char* name, const Instruction* vPC, int operand)
{
unsigned instructionOffset = vPC - instructions().begin();
- dataLogF(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data());
+ out.printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data());
}
-void CodeBlock::printStructures(const Instruction* vPC)
+void CodeBlock::printStructures(PrintStream& out, const Instruction* vPC)
{
- Interpreter* interpreter = m_globalData->interpreter;
+ Interpreter* interpreter = m_vm->interpreter;
unsigned instructionOffset = vPC - instructions().begin();
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) {
- printStructure("get_by_id", vPC, 4);
+ printStructure(out, "get_by_id", vPC, 4);
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
- printStructure("get_by_id_self", vPC, 4);
+ printStructure(out, "get_by_id_self", vPC, 4);
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
- dataLogF(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data());
+ out.printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data());
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
- dataLogF(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data(), pointerToSourceString(vPC[6].u.structureChain).utf8().data());
+ out.printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data(), pointerToSourceString(vPC[6].u.structureChain).utf8().data());
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
- dataLogF(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data());
+ out.printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data());
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {
- printStructure("put_by_id", vPC, 4);
+ printStructure(out, "put_by_id", vPC, 4);
return;
}
if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
- printStructure("put_by_id_replace", vPC, 4);
+ printStructure(out, "put_by_id_replace", vPC, 4);
return;
}
@@ -498,7 +523,7 @@ void CodeBlock::printStructures(const Instruction* vPC)
ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
}
-void CodeBlock::dumpBytecode()
+void CodeBlock::dumpBytecode(PrintStream& out)
{
// We only use the ExecState* for things that don't actually lead to JS execution,
// like converting a JSString to a String. Hence the globalExec is appropriate.
@@ -509,92 +534,95 @@ void CodeBlock::dumpBytecode()
for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
++instructionCount;
- dataLog(*this);
- dataLogF(
+ out.print(*this);
+ out.printf(
": %lu m_instructions; %lu bytes; %d parameter(s); %d callee register(s); %d variable(s)",
static_cast<unsigned long>(instructions().size()),
static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
m_numParameters, m_numCalleeRegisters, m_numVars);
- if (symbolTable() && symbolTable()->captureCount())
- dataLogF("; %d captured var(s)", symbolTable()->captureCount());
+ if (symbolTable() && symbolTable()->captureCount()) {
+ out.printf(
+ "; %d captured var(s) (from r%d to r%d, inclusive)",
+ symbolTable()->captureCount(), symbolTable()->captureStart(), symbolTable()->captureEnd() - 1);
+ }
if (usesArguments()) {
- dataLogF(
+ out.printf(
"; uses arguments, in r%d, r%d",
argumentsRegister(),
unmodifiedArgumentsRegister(argumentsRegister()));
}
if (needsFullScopeChain() && codeType() == FunctionCode)
- dataLogF("; activation in r%d", activationRegister());
- dataLogF("\n\n");
+ out.printf("; activation in r%d", activationRegister());
+ out.print("\n\nSource: ", sourceCodeOnOneLine(), "\n\n");
const Instruction* begin = instructions().begin();
const Instruction* end = instructions().end();
for (const Instruction* it = begin; it != end; ++it)
- dumpBytecode(exec, begin, it);
+ dumpBytecode(out, exec, begin, it);
if (!m_identifiers.isEmpty()) {
- dataLogF("\nIdentifiers:\n");
+ out.printf("\nIdentifiers:\n");
size_t i = 0;
do {
- dataLogF(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].string().utf8().data());
+ out.printf(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].string().utf8().data());
++i;
} while (i != m_identifiers.size());
}
if (!m_constantRegisters.isEmpty()) {
- dataLogF("\nConstants:\n");
+ out.printf("\nConstants:\n");
size_t i = 0;
do {
- dataLogF(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data());
+ out.printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data());
++i;
} while (i < m_constantRegisters.size());
}
if (size_t count = m_unlinkedCode->numberOfRegExps()) {
- dataLogF("\nm_regexps:\n");
+ out.printf("\nm_regexps:\n");
size_t i = 0;
do {
- dataLogF(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_unlinkedCode->regexp(i)).utf8().data());
+ out.printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_unlinkedCode->regexp(i)).utf8().data());
++i;
} while (i < count);
}
#if ENABLE(JIT)
if (!m_structureStubInfos.isEmpty())
- dataLogF("\nStructures:\n");
+ out.printf("\nStructures:\n");
#endif
if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
- dataLogF("\nException Handlers:\n");
+ out.printf("\nException Handlers:\n");
unsigned i = 0;
do {
- dataLogF("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target, m_rareData->m_exceptionHandlers[i].scopeDepth);
+ out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target, m_rareData->m_exceptionHandlers[i].scopeDepth);
++i;
} while (i < m_rareData->m_exceptionHandlers.size());
}
if (m_rareData && !m_rareData->m_immediateSwitchJumpTables.isEmpty()) {
- dataLogF("Immediate Switch Jump Tables:\n");
+ out.printf("Immediate Switch Jump Tables:\n");
unsigned i = 0;
do {
- dataLogF(" %1d = {\n", i);
+ out.printf(" %1d = {\n", i);
int entry = 0;
Vector<int32_t>::const_iterator end = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.end();
for (Vector<int32_t>::const_iterator iter = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
if (!*iter)
continue;
- dataLogF("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter);
+ out.printf("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter);
}
- dataLogF(" }\n");
+ out.printf(" }\n");
++i;
} while (i < m_rareData->m_immediateSwitchJumpTables.size());
}
if (m_rareData && !m_rareData->m_characterSwitchJumpTables.isEmpty()) {
- dataLogF("\nCharacter Switch Jump Tables:\n");
+ out.printf("\nCharacter Switch Jump Tables:\n");
unsigned i = 0;
do {
- dataLogF(" %1d = {\n", i);
+ out.printf(" %1d = {\n", i);
int entry = 0;
Vector<int32_t>::const_iterator end = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.end();
for (Vector<int32_t>::const_iterator iter = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
@@ -602,96 +630,143 @@ void CodeBlock::dumpBytecode()
continue;
ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF));
UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min);
- dataLogF("\t\t\"%s\" => %04d\n", String(&ch, 1).utf8().data(), *iter);
- }
- dataLogF(" }\n");
+ out.printf("\t\t\"%s\" => %04d\n", String(&ch, 1).utf8().data(), *iter);
+ }
+ out.printf(" }\n");
++i;
} while (i < m_rareData->m_characterSwitchJumpTables.size());
}
if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) {
- dataLogF("\nString Switch Jump Tables:\n");
+ out.printf("\nString Switch Jump Tables:\n");
unsigned i = 0;
do {
- dataLogF(" %1d = {\n", i);
+ out.printf(" %1d = {\n", i);
StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end();
for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter)
- dataLogF("\t\t\"%s\" => %04d\n", String(iter->key).utf8().data(), iter->value.branchOffset);
- dataLogF(" }\n");
+ out.printf("\t\t\"%s\" => %04d\n", String(iter->key).utf8().data(), iter->value.branchOffset);
+ out.printf(" }\n");
++i;
} while (i < m_rareData->m_stringSwitchJumpTables.size());
}
- dataLogF("\n");
+ out.printf("\n");
+}
+
+void CodeBlock::beginDumpProfiling(PrintStream& out, bool& hasPrintedProfiling)
+{
+ if (hasPrintedProfiling) {
+ out.print("; ");
+ return;
+ }
+
+ out.print(" ");
+ hasPrintedProfiling = true;
}
-void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const Instruction*& it)
+void CodeBlock::dumpValueProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
+{
+ ++it;
+#if ENABLE(VALUE_PROFILER)
+ CString description = it->u.profile->briefDescription();
+ if (!description.length())
+ return;
+ beginDumpProfiling(out, hasPrintedProfiling);
+ out.print(description);
+#else
+ UNUSED_PARAM(out);
+ UNUSED_PARAM(hasPrintedProfiling);
+#endif
+}
+
+void CodeBlock::dumpArrayProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
+{
+ ++it;
+#if ENABLE(VALUE_PROFILER)
+ CString description = it->u.arrayProfile->briefDescription(this);
+ if (!description.length())
+ return;
+ beginDumpProfiling(out, hasPrintedProfiling);
+ out.print(description);
+#else
+ UNUSED_PARAM(out);
+ UNUSED_PARAM(hasPrintedProfiling);
+#endif
+}
+
+#if ENABLE(VALUE_PROFILER)
+void CodeBlock::dumpRareCaseProfile(PrintStream& out, const char* name, RareCaseProfile* profile, bool& hasPrintedProfiling)
+{
+ if (!profile || !profile->m_counter)
+ return;
+
+ beginDumpProfiling(out, hasPrintedProfiling);
+ out.print(name, profile->m_counter);
+}
+#endif
+
+void CodeBlock::dumpBytecode(PrintStream& out, ExecState* exec, const Instruction* begin, const Instruction*& it)
{
int location = it - begin;
+ bool hasPrintedProfiling = false;
switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
case op_enter: {
- dataLogF("[%4d] enter", location);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] enter", location);
break;
}
case op_create_activation: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] create_activation %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] create_activation %s", location, registerName(exec, r0).data());
break;
}
case op_create_arguments: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] create_arguments\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] create_arguments\t %s", location, registerName(exec, r0).data());
break;
}
case op_init_lazy_reg: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] init_lazy_reg\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] init_lazy_reg\t %s", location, registerName(exec, r0).data());
break;
}
case op_get_callee: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data());
+ out.printf("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data());
++it;
break;
}
case op_create_this: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] create_this %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ unsigned inferredInlineCapacity = (++it)->u.operand;
+ out.printf("[%4d] create_this %s, %s, %u", location, registerName(exec, r0).data(), registerName(exec, r1).data(), inferredInlineCapacity);
break;
}
case op_convert_this: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] convert_this\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] convert_this\t %s", location, registerName(exec, r0).data());
++it; // Skip value profile.
break;
}
case op_new_object: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] new_object\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ unsigned inferredInlineCapacity = (++it)->u.operand;
+ out.printf("[%4d] new_object\t %s, %u", location, registerName(exec, r0).data(), inferredInlineCapacity);
+ ++it; // Skip object allocation profile.
break;
}
case op_new_array: {
int dst = (++it)->u.operand;
int argv = (++it)->u.operand;
int argc = (++it)->u.operand;
- dataLogF("[%4d] new_array\t %s, %s, %d", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] new_array\t %s, %s, %d", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
++it; // Skip array allocation profile.
break;
}
case op_new_array_with_size: {
int dst = (++it)->u.operand;
int length = (++it)->u.operand;
- dataLogF("[%4d] new_array_with_size\t %s, %s", location, registerName(exec, dst).data(), registerName(exec, length).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] new_array_with_size\t %s, %s", location, registerName(exec, dst).data(), registerName(exec, length).data());
++it; // Skip array allocation profile.
break;
}
@@ -699,149 +774,136 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int dst = (++it)->u.operand;
int argv = (++it)->u.operand;
int argc = (++it)->u.operand;
- dataLogF("[%4d] new_array_buffer\t %s, %d, %d", location, registerName(exec, dst).data(), argv, argc);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] new_array_buffer\t %s, %d, %d", location, registerName(exec, dst).data(), argv, argc);
++it; // Skip array allocation profile.
break;
}
case op_new_regexp: {
int r0 = (++it)->u.operand;
int re0 = (++it)->u.operand;
- dataLogF("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data());
+ out.printf("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data());
if (r0 >=0 && r0 < (int)m_unlinkedCode->numberOfRegExps())
- dataLogF("%s", regexpName(re0, regexp(re0)).data());
+ out.printf("%s", regexpName(re0, regexp(re0)).data());
else
- dataLogF("bad_regexp(%d)", re0);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("bad_regexp(%d)", re0);
break;
}
case op_mov: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] mov\t\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] mov\t\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
break;
}
case op_not: {
- printUnaryOp(exec, location, it, "not");
+ printUnaryOp(out, exec, location, it, "not");
break;
}
case op_eq: {
- printBinaryOp(exec, location, it, "eq");
+ printBinaryOp(out, exec, location, it, "eq");
break;
}
case op_eq_null: {
- printUnaryOp(exec, location, it, "eq_null");
+ printUnaryOp(out, exec, location, it, "eq_null");
break;
}
case op_neq: {
- printBinaryOp(exec, location, it, "neq");
+ printBinaryOp(out, exec, location, it, "neq");
break;
}
case op_neq_null: {
- printUnaryOp(exec, location, it, "neq_null");
+ printUnaryOp(out, exec, location, it, "neq_null");
break;
}
case op_stricteq: {
- printBinaryOp(exec, location, it, "stricteq");
+ printBinaryOp(out, exec, location, it, "stricteq");
break;
}
case op_nstricteq: {
- printBinaryOp(exec, location, it, "nstricteq");
+ printBinaryOp(out, exec, location, it, "nstricteq");
break;
}
case op_less: {
- printBinaryOp(exec, location, it, "less");
+ printBinaryOp(out, exec, location, it, "less");
break;
}
case op_lesseq: {
- printBinaryOp(exec, location, it, "lesseq");
+ printBinaryOp(out, exec, location, it, "lesseq");
break;
}
case op_greater: {
- printBinaryOp(exec, location, it, "greater");
+ printBinaryOp(out, exec, location, it, "greater");
break;
}
case op_greatereq: {
- printBinaryOp(exec, location, it, "greatereq");
+ printBinaryOp(out, exec, location, it, "greatereq");
break;
}
- case op_pre_inc: {
+ case op_inc: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] pre_inc\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] pre_inc\t\t %s", location, registerName(exec, r0).data());
break;
}
- case op_pre_dec: {
+ case op_dec: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] pre_dec\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] pre_dec\t\t %s", location, registerName(exec, r0).data());
break;
}
- case op_post_inc: {
- printUnaryOp(exec, location, it, "post_inc");
- break;
- }
- case op_post_dec: {
- printUnaryOp(exec, location, it, "post_dec");
- break;
- }
- case op_to_jsnumber: {
- printUnaryOp(exec, location, it, "to_jsnumber");
+ case op_to_number: {
+ printUnaryOp(out, exec, location, it, "to_number");
break;
}
case op_negate: {
- printUnaryOp(exec, location, it, "negate");
+ printUnaryOp(out, exec, location, it, "negate");
break;
}
case op_add: {
- printBinaryOp(exec, location, it, "add");
+ printBinaryOp(out, exec, location, it, "add");
++it;
break;
}
case op_mul: {
- printBinaryOp(exec, location, it, "mul");
+ printBinaryOp(out, exec, location, it, "mul");
++it;
break;
}
case op_div: {
- printBinaryOp(exec, location, it, "div");
+ printBinaryOp(out, exec, location, it, "div");
++it;
break;
}
case op_mod: {
- printBinaryOp(exec, location, it, "mod");
+ printBinaryOp(out, exec, location, it, "mod");
break;
}
case op_sub: {
- printBinaryOp(exec, location, it, "sub");
+ printBinaryOp(out, exec, location, it, "sub");
++it;
break;
}
case op_lshift: {
- printBinaryOp(exec, location, it, "lshift");
+ printBinaryOp(out, exec, location, it, "lshift");
break;
}
case op_rshift: {
- printBinaryOp(exec, location, it, "rshift");
+ printBinaryOp(out, exec, location, it, "rshift");
break;
}
case op_urshift: {
- printBinaryOp(exec, location, it, "urshift");
+ printBinaryOp(out, exec, location, it, "urshift");
break;
}
case op_bitand: {
- printBinaryOp(exec, location, it, "bitand");
+ printBinaryOp(out, exec, location, it, "bitand");
++it;
break;
}
case op_bitxor: {
- printBinaryOp(exec, location, it, "bitxor");
+ printBinaryOp(out, exec, location, it, "bitxor");
++it;
break;
}
case op_bitor: {
- printBinaryOp(exec, location, it, "bitor");
+ printBinaryOp(out, exec, location, it, "bitor");
++it;
break;
}
@@ -850,48 +912,46 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] check_has_instance\t\t %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] check_has_instance\t\t %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), offset, location + offset);
break;
}
case op_instanceof: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] instanceof\t\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] instanceof\t\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
break;
}
case op_typeof: {
- printUnaryOp(exec, location, it, "typeof");
+ printUnaryOp(out, exec, location, it, "typeof");
break;
}
case op_is_undefined: {
- printUnaryOp(exec, location, it, "is_undefined");
+ printUnaryOp(out, exec, location, it, "is_undefined");
break;
}
case op_is_boolean: {
- printUnaryOp(exec, location, it, "is_boolean");
+ printUnaryOp(out, exec, location, it, "is_boolean");
break;
}
case op_is_number: {
- printUnaryOp(exec, location, it, "is_number");
+ printUnaryOp(out, exec, location, it, "is_number");
break;
}
case op_is_string: {
- printUnaryOp(exec, location, it, "is_string");
+ printUnaryOp(out, exec, location, it, "is_string");
break;
}
case op_is_object: {
- printUnaryOp(exec, location, it, "is_object");
+ printUnaryOp(out, exec, location, it, "is_object");
break;
}
case op_is_function: {
- printUnaryOp(exec, location, it, "is_function");
+ printUnaryOp(out, exec, location, it, "is_function");
break;
}
case op_in: {
- printBinaryOp(exec, location, it, "in");
+ printBinaryOp(out, exec, location, it, "in");
break;
}
case op_put_to_base_variable:
@@ -900,8 +960,7 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int id0 = (++it)->u.operand;
int value = (++it)->u.operand;
int resolveInfo = (++it)->u.operand;
- dataLogF("[%4d] put_to_base\t %s, %s, %s, %d", location, registerName(exec, base).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, value).data(), resolveInfo);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] put_to_base\t %s, %s, %s, %d", location, registerName(exec, base).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, value).data(), resolveInfo);
break;
}
case op_resolve:
@@ -913,14 +972,27 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
int resolveInfo = (++it)->u.operand;
- dataLogF("[%4d] resolve\t\t %s, %s, %d", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
- dumpBytecodeCommentAndNewLine(location);
- it++;
+ out.printf("[%4d] resolve\t\t %s, %s, %d", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
+ break;
+ }
+ case op_get_scoped_var: {
+ int r0 = (++it)->u.operand;
+ int index = (++it)->u.operand;
+ int skipLevels = (++it)->u.operand;
+ out.printf("[%4d] get_scoped_var\t %s, %d, %d", location, registerName(exec, r0).data(), index, skipLevels);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
+ break;
+ }
+ case op_put_scoped_var: {
+ int index = (++it)->u.operand;
+ int skipLevels = (++it)->u.operand;
+ int r0 = (++it)->u.operand;
+ out.printf("[%4d] put_scoped_var\t %d, %d, %s", location, index, skipLevels, registerName(exec, r0).data());
break;
}
case op_init_global_const_nop: {
- dataLogF("[%4d] init_global_const_nop\t", location);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] init_global_const_nop\t", location);
it++;
it++;
it++;
@@ -930,8 +1002,7 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
case op_init_global_const: {
WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
int r0 = (++it)->u.operand;
- dataLogF("[%4d] init_global_const\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] init_global_const\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
it++;
it++;
break;
@@ -939,8 +1010,7 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
case op_init_global_const_check: {
WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
int r0 = (++it)->u.operand;
- dataLogF("[%4d] init_global_const_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] init_global_const_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
it++;
it++;
break;
@@ -955,16 +1025,8 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int isStrict = (++it)->u.operand;
int resolveInfo = (++it)->u.operand;
int putToBaseInfo = (++it)->u.operand;
- dataLogF("[%4d] resolve_base%s\t %s, %s, %d, %d", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
- dumpBytecodeCommentAndNewLine(location);
- it++;
- break;
- }
- case op_ensure_property_exists: {
- int r0 = (++it)->u.operand;
- int id0 = (++it)->u.operand;
- dataLogF("[%4d] ensure_property_exists\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] resolve_base%s\t %s, %s, %d, %d", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_resolve_with_base: {
@@ -973,9 +1035,8 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int id0 = (++it)->u.operand;
int resolveInfo = (++it)->u.operand;
int putToBaseInfo = (++it)->u.operand;
- dataLogF("[%4d] resolve_with_base %s, %s, %s, %d, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
- dumpBytecodeCommentAndNewLine(location);
- it++;
+ out.printf("[%4d] resolve_with_base %s, %s, %s, %d, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_resolve_with_this: {
@@ -983,9 +1044,8 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int r1 = (++it)->u.operand;
int id0 = (++it)->u.operand;
int resolveInfo = (++it)->u.operand;
- dataLogF("[%4d] resolve_with_this %s, %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
- dumpBytecodeCommentAndNewLine(location);
- it++;
+ out.printf("[%4d] resolve_with_this %s, %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_get_by_id:
@@ -1002,50 +1062,50 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
case op_get_by_id_generic:
case op_get_array_length:
case op_get_string_length: {
- printGetByIdOp(exec, location, it);
- printGetByIdCacheStatus(exec, location);
- dumpBytecodeCommentAndNewLine(location);
+ printGetByIdOp(out, exec, location, it);
+ printGetByIdCacheStatus(out, exec, location);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_get_arguments_length: {
- printUnaryOp(exec, location, it, "get_arguments_length");
+ printUnaryOp(out, exec, location, it, "get_arguments_length");
it++;
break;
}
case op_put_by_id: {
- printPutByIdOp(exec, location, it, "put_by_id");
+ printPutByIdOp(out, exec, location, it, "put_by_id");
break;
}
case op_put_by_id_out_of_line: {
- printPutByIdOp(exec, location, it, "put_by_id_out_of_line");
+ printPutByIdOp(out, exec, location, it, "put_by_id_out_of_line");
break;
}
case op_put_by_id_replace: {
- printPutByIdOp(exec, location, it, "put_by_id_replace");
+ printPutByIdOp(out, exec, location, it, "put_by_id_replace");
break;
}
case op_put_by_id_transition: {
- printPutByIdOp(exec, location, it, "put_by_id_transition");
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition");
break;
}
case op_put_by_id_transition_direct: {
- printPutByIdOp(exec, location, it, "put_by_id_transition_direct");
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct");
break;
}
case op_put_by_id_transition_direct_out_of_line: {
- printPutByIdOp(exec, location, it, "put_by_id_transition_direct_out_of_line");
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct_out_of_line");
break;
}
case op_put_by_id_transition_normal: {
- printPutByIdOp(exec, location, it, "put_by_id_transition_normal");
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal");
break;
}
case op_put_by_id_transition_normal_out_of_line: {
- printPutByIdOp(exec, location, it, "put_by_id_transition_normal_out_of_line");
+ printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal_out_of_line");
break;
}
case op_put_by_id_generic: {
- printPutByIdOp(exec, location, it, "put_by_id_generic");
+ printPutByIdOp(out, exec, location, it, "put_by_id_generic");
break;
}
case op_put_getter_setter: {
@@ -1053,36 +1113,32 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int id0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] put_getter_setter\t %s, %s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] put_getter_setter\t %s, %s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
break;
}
case op_del_by_id: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int id0 = (++it)->u.operand;
- dataLogF("[%4d] del_by_id\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] del_by_id\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
break;
}
case op_get_by_val: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] get_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
- it++;
- it++;
+ out.printf("[%4d] get_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
+ dumpArrayProfiling(out, it, hasPrintedProfiling);
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_get_argument_by_val: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] get_argument_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
- ++it;
+ out.printf("[%4d] get_argument_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
++it;
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_get_by_pname: {
@@ -1092,225 +1148,159 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int r3 = (++it)->u.operand;
int r4 = (++it)->u.operand;
int r5 = (++it)->u.operand;
- dataLogF("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), registerName(exec, r4).data(), registerName(exec, r5).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), registerName(exec, r4).data(), registerName(exec, r5).data());
break;
}
case op_put_by_val: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] put_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
- ++it;
+ out.printf("[%4d] put_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
+ dumpArrayProfiling(out, it, hasPrintedProfiling);
break;
}
case op_del_by_val: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
- dataLogF("[%4d] del_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] del_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
break;
}
case op_put_by_index: {
int r0 = (++it)->u.operand;
unsigned n0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] put_by_index\t %s, %u, %s", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] put_by_index\t %s, %u, %s", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data());
break;
}
case op_jmp: {
int offset = (++it)->u.operand;
- dataLogF("[%4d] jmp\t\t %d(->%d)", location, offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
- break;
- }
- case op_loop: {
- int offset = (++it)->u.operand;
- dataLogF("[%4d] loop\t\t %d(->%d)", location, offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jmp\t\t %d(->%d)", location, offset, location + offset);
break;
}
case op_jtrue: {
- printConditionalJump(exec, begin, it, location, "jtrue");
- break;
- }
- case op_loop_if_true: {
- printConditionalJump(exec, begin, it, location, "loop_if_true");
- break;
- }
- case op_loop_if_false: {
- printConditionalJump(exec, begin, it, location, "loop_if_false");
+ printConditionalJump(out, exec, begin, it, location, "jtrue");
break;
}
case op_jfalse: {
- printConditionalJump(exec, begin, it, location, "jfalse");
+ printConditionalJump(out, exec, begin, it, location, "jfalse");
break;
}
case op_jeq_null: {
- printConditionalJump(exec, begin, it, location, "jeq_null");
+ printConditionalJump(out, exec, begin, it, location, "jeq_null");
break;
}
case op_jneq_null: {
- printConditionalJump(exec, begin, it, location, "jneq_null");
+ printConditionalJump(out, exec, begin, it, location, "jneq_null");
break;
}
case op_jneq_ptr: {
int r0 = (++it)->u.operand;
Special::Pointer pointer = (++it)->u.specialPointer;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jneq_ptr\t\t %s, %d (%p), %d(->%d)", location, registerName(exec, r0).data(), pointer, m_globalObject->actualPointerFor(pointer), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jneq_ptr\t\t %s, %d (%p), %d(->%d)", location, registerName(exec, r0).data(), pointer, m_globalObject->actualPointerFor(pointer), offset, location + offset);
break;
}
case op_jless: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jlesseq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jgreater: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jgreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jgreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jgreatereq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jgreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jgreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jnless: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jnless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jnless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jnlesseq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jnlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jngreater: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jngreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jngreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_jngreatereq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- dataLogF("[%4d] jngreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
- break;
- }
- case op_loop_if_less: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- dataLogF("[%4d] loop_if_less\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
- break;
- }
- case op_loop_if_lesseq: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- dataLogF("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
- break;
- }
- case op_loop_if_greater: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- dataLogF("[%4d] loop_if_greater\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
- break;
- }
- case op_loop_if_greatereq: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- dataLogF("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] jngreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
break;
}
case op_loop_hint: {
- dataLogF("[%4d] loop_hint", location);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] loop_hint", location);
break;
}
case op_switch_imm: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;
int scrutineeRegister = (++it)->u.operand;
- dataLogF("[%4d] switch_imm\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] switch_imm\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
break;
}
case op_switch_char: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;
int scrutineeRegister = (++it)->u.operand;
- dataLogF("[%4d] switch_char\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] switch_char\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
break;
}
case op_switch_string: {
int tableIndex = (++it)->u.operand;
int defaultTarget = (++it)->u.operand;
int scrutineeRegister = (++it)->u.operand;
- dataLogF("[%4d] switch_string\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] switch_string\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
break;
}
case op_new_func: {
int r0 = (++it)->u.operand;
int f0 = (++it)->u.operand;
int shouldCheck = (++it)->u.operand;
- dataLogF("[%4d] new_func\t\t %s, f%d, %s", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] new_func\t\t %s, f%d, %s", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
break;
}
case op_new_func_exp: {
int r0 = (++it)->u.operand;
int f0 = (++it)->u.operand;
- dataLogF("[%4d] new_func_exp\t %s, f%d", location, registerName(exec, r0).data(), f0);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] new_func_exp\t %s, f%d", location, registerName(exec, r0).data(), f0);
break;
}
case op_call: {
- printCallOp(exec, location, it, "call", DumpCaches);
+ printCallOp(out, exec, location, it, "call", DumpCaches);
break;
}
case op_call_eval: {
- printCallOp(exec, location, it, "call_eval", DontDumpCaches);
+ printCallOp(out, exec, location, it, "call_eval", DontDumpCaches);
break;
}
case op_call_varargs: {
@@ -1318,60 +1308,52 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int thisValue = (++it)->u.operand;
int arguments = (++it)->u.operand;
int firstFreeRegister = (++it)->u.operand;
- dataLogF("[%4d] call_varargs\t %s, %s, %s, %d", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] call_varargs\t %s, %s, %s, %d", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister);
break;
}
case op_tear_off_activation: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] tear_off_activation\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] tear_off_activation\t %s", location, registerName(exec, r0).data());
break;
}
case op_tear_off_arguments: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] tear_off_arguments %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] tear_off_arguments %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
break;
}
case op_ret: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] ret\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] ret\t\t %s", location, registerName(exec, r0).data());
break;
}
case op_call_put_result: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] call_put_result\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
- it++;
+ out.printf("[%4d] call_put_result\t\t %s", location, registerName(exec, r0).data());
+ dumpValueProfiling(out, it, hasPrintedProfiling);
break;
}
case op_ret_object_or_this: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] constructor_ret\t\t %s %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] constructor_ret\t\t %s %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
break;
}
case op_construct: {
- printCallOp(exec, location, it, "construct", DumpCaches);
+ printCallOp(out, exec, location, it, "construct", DumpCaches);
break;
}
case op_strcat: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int count = (++it)->u.operand;
- dataLogF("[%4d] strcat\t\t %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] strcat\t\t %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count);
break;
}
case op_to_primitive: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- dataLogF("[%4d] to_primitive\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] to_primitive\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
break;
}
case op_get_pnames: {
@@ -1380,8 +1362,7 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int r2 = it[3].u.operand;
int r3 = it[4].u.operand;
int offset = it[5].u.operand;
- dataLogF("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset);
it += OPCODE_LENGTH(op_get_pnames) - 1;
break;
}
@@ -1392,54 +1373,40 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int size = it[4].u.operand;
int iter = it[5].u.operand;
int offset = it[6].u.operand;
- dataLogF("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset);
it += OPCODE_LENGTH(op_next_pname) - 1;
break;
}
case op_push_with_scope: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] push_with_scope\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] push_with_scope\t %s", location, registerName(exec, r0).data());
break;
}
case op_pop_scope: {
- dataLogF("[%4d] pop_scope", location);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] pop_scope", location);
break;
}
case op_push_name_scope: {
int id0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
unsigned attributes = (++it)->u.operand;
- dataLogF("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), attributes);
- dumpBytecodeCommentAndNewLine(location);
- break;
- }
- case op_jmp_scopes: {
- int scopeDelta = (++it)->u.operand;
- int offset = (++it)->u.operand;
- dataLogF("[%4d] jmp_scopes\t^%d, %d(->%d)", location, scopeDelta, offset, location + offset);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), attributes);
break;
}
case op_catch: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] catch\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] catch\t\t %s", location, registerName(exec, r0).data());
break;
}
case op_throw: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] throw\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] throw\t\t %s", location, registerName(exec, r0).data());
break;
}
case op_throw_static_error: {
int k0 = (++it)->u.operand;
int k1 = (++it)->u.operand;
- dataLogF("[%4d] throw_static_error\t %s, %s", location, constantName(exec, k0, getConstant(k0)).data(), k1 ? "true" : "false");
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] throw_static_error\t %s, %s", location, constantName(exec, k0, getConstant(k0)).data(), k1 ? "true" : "false");
break;
}
case op_debug: {
@@ -1447,40 +1414,54 @@ void CodeBlock::dumpBytecode(ExecState* exec, const Instruction* begin, const In
int firstLine = (++it)->u.operand;
int lastLine = (++it)->u.operand;
int column = (++it)->u.operand;
- dataLogF("[%4d] debug\t\t %s, %d, %d, %d", location, debugHookName(debugHookID), firstLine, lastLine, column);
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] debug\t\t %s, %d, %d, %d", location, debugHookName(debugHookID), firstLine, lastLine, column);
break;
}
case op_profile_will_call: {
int function = (++it)->u.operand;
- dataLogF("[%4d] profile_will_call %s", location, registerName(exec, function).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] profile_will_call %s", location, registerName(exec, function).data());
break;
}
case op_profile_did_call: {
int function = (++it)->u.operand;
- dataLogF("[%4d] profile_did_call\t %s", location, registerName(exec, function).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] profile_did_call\t %s", location, registerName(exec, function).data());
break;
}
case op_end: {
int r0 = (++it)->u.operand;
- dataLogF("[%4d] end\t\t %s", location, registerName(exec, r0).data());
- dumpBytecodeCommentAndNewLine(location);
+ out.printf("[%4d] end\t\t %s", location, registerName(exec, r0).data());
break;
}
#if ENABLE(LLINT_C_LOOP)
default:
- ASSERT(false); // We should never get here.
+ RELEASE_ASSERT_NOT_REACHED();
+#endif
+ }
+
+#if ENABLE(VALUE_PROFILER)
+ dumpRareCaseProfile(out, "rare case: ", rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
+ dumpRareCaseProfile(out, "special fast case: ", specialFastCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
#endif
+
+#if ENABLE(DFG_JIT)
+ Vector<FrequentExitSite> exitSites = exitProfile().exitSitesFor(location);
+ if (!exitSites.isEmpty()) {
+ out.print(" !! frequent exits: ");
+ CommaPrinter comma;
+ for (unsigned i = 0; i < exitSites.size(); ++i)
+ out.print(comma, exitSites[i].kind());
}
+#else // ENABLE(DFG_JIT)
+ UNUSED_PARAM(location);
+#endif // ENABLE(DFG_JIT)
+ out.print("\n");
}
-void CodeBlock::dumpBytecode(unsigned bytecodeOffset)
+void CodeBlock::dumpBytecode(PrintStream& out, unsigned bytecodeOffset)
{
ExecState* exec = m_globalObject->globalExec();
const Instruction* it = instructions().begin() + bytecodeOffset;
- dumpBytecode(exec, instructions().begin(), it);
+ dumpBytecode(out, exec, instructions().begin(), it);
}
#if DUMP_CODE_BLOCK_STATISTICS
@@ -1613,19 +1594,19 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
, m_numCalleeRegisters(other.m_numCalleeRegisters)
, m_numVars(other.m_numVars)
, m_isConstructor(other.m_isConstructor)
- , m_unlinkedCode(*other.m_globalData, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
- , m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
- , m_globalData(other.m_globalData)
+ , m_unlinkedCode(*other.m_vm, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
+ , m_ownerExecutable(*other.m_vm, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
+ , m_vm(other.m_vm)
, m_instructions(other.m_instructions)
, m_thisRegister(other.m_thisRegister)
, m_argumentsRegister(other.m_argumentsRegister)
, m_activationRegister(other.m_activationRegister)
, m_isStrictMode(other.m_isStrictMode)
+ , m_needsActivation(other.m_needsActivation)
, m_source(other.m_source)
, m_sourceOffset(other.m_sourceOffset)
-#if ENABLE(VALUE_PROFILER)
- , m_executionEntryCount(0)
-#endif
+ , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
+ , m_codeType(other.m_codeType)
, m_identifiers(other.m_identifiers)
, m_constantRegisters(other.m_constantRegisters)
, m_functionDecls(other.m_functionDecls)
@@ -1635,9 +1616,6 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
, m_reoptimizationRetryCounter(0)
, m_resolveOperations(other.m_resolveOperations)
, m_putToBaseOperations(other.m_putToBaseOperations)
-#if ENABLE(BYTECODE_COMMENTS)
- , m_bytecodeCommentIterator(0)
-#endif
#if ENABLE(JIT)
, m_canCompileWithDFGState(DFG::CapabilityLevelNotSet)
#endif
@@ -1657,56 +1635,53 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
}
}
-CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
- : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject)
- , m_heap(&m_globalObject->globalData().heap)
+CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset, PassOwnPtr<CodeBlock> alternative)
+ : m_globalObject(globalObject->vm(), ownerExecutable, globalObject)
+ , m_heap(&m_globalObject->vm().heap)
, m_numCalleeRegisters(unlinkedCodeBlock->m_numCalleeRegisters)
, m_numVars(unlinkedCodeBlock->m_numVars)
, m_isConstructor(unlinkedCodeBlock->isConstructor())
- , m_unlinkedCode(globalObject->globalData(), ownerExecutable, unlinkedCodeBlock)
- , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
- , m_globalData(unlinkedCodeBlock->globalData())
+ , m_unlinkedCode(globalObject->vm(), ownerExecutable, unlinkedCodeBlock)
+ , m_ownerExecutable(globalObject->vm(), ownerExecutable, ownerExecutable)
+ , m_vm(unlinkedCodeBlock->vm())
, m_thisRegister(unlinkedCodeBlock->thisRegister())
, m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
, m_activationRegister(unlinkedCodeBlock->activationRegister())
, m_isStrictMode(unlinkedCodeBlock->isStrictMode())
+ , m_needsActivation(unlinkedCodeBlock->needsFullScopeChain())
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
-#if ENABLE(VALUE_PROFILER)
- , m_executionEntryCount(0)
-#endif
+ , m_firstLineColumnOffset(firstLineColumnOffset)
+ , m_codeType(unlinkedCodeBlock->codeType())
, m_alternative(alternative)
, m_osrExitCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
-#if ENABLE(BYTECODE_COMMENTS)
- , m_bytecodeCommentIterator(0)
-#endif
{
- m_globalData->startedCompiling(this);
+ m_vm->startedCompiling(this);
ASSERT(m_source);
setNumParameters(unlinkedCodeBlock->numParameters());
- optimizeAfterWarmUp();
- jitAfterWarmUp();
-
#if DUMP_CODE_BLOCK_STATISTICS
liveCodeBlockSet.add(this);
#endif
setIdentifiers(unlinkedCodeBlock->identifiers());
setConstantRegisters(unlinkedCodeBlock->constantRegisters());
-
+ if (unlinkedCodeBlock->usesGlobalObject())
+ m_constantRegisters[unlinkedCodeBlock->globalObjectRegister()].set(*m_vm, ownerExecutable, globalObject);
m_functionDecls.grow(unlinkedCodeBlock->numberOfFunctionDecls());
for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
unsigned lineCount = unlinkedExecutable->lineCount();
unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
+ unsigned startColumn = unlinkedExecutable->functionStartColumn();
+ startColumn += (unlinkedExecutable->firstLineOffset() ? 1 : ownerExecutable->startColumn());
unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
unsigned sourceLength = unlinkedExecutable->sourceLength();
- SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine);
- FunctionExecutable* executable = FunctionExecutable::create(*m_globalData, code, unlinkedExecutable, firstLine, firstLine + lineCount);
- m_functionDecls[i].set(*m_globalData, ownerExecutable, executable);
+ SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
+ FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn);
+ m_functionDecls[i].set(*m_vm, ownerExecutable, executable);
}
m_functionExprs.grow(unlinkedCodeBlock->numberOfFunctionExprs());
@@ -1714,11 +1689,13 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
unsigned lineCount = unlinkedExecutable->lineCount();
unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
+ unsigned startColumn = unlinkedExecutable->functionStartColumn();
+ startColumn += (unlinkedExecutable->firstLineOffset() ? 1 : ownerExecutable->startColumn());
unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
unsigned sourceLength = unlinkedExecutable->sourceLength();
- SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine);
- FunctionExecutable* executable = FunctionExecutable::create(*m_globalData, code, unlinkedExecutable, firstLine, firstLine + lineCount);
- m_functionExprs[i].set(*m_globalData, ownerExecutable, executable);
+ SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
+ FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn);
+ m_functionExprs[i].set(*m_vm, ownerExecutable, executable);
}
if (unlinkedCodeBlock->hasRareData()) {
@@ -1791,22 +1768,23 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
if (size_t size = unlinkedCodeBlock->numberOfValueProfiles())
m_valueProfiles.grow(size);
#endif
+ if (size_t size = unlinkedCodeBlock->numberOfObjectAllocationProfiles())
+ m_objectAllocationProfiles.grow(size);
if (size_t size = unlinkedCodeBlock->numberOfResolveOperations())
m_resolveOperations.grow(size);
- size_t putToBaseCount = unlinkedCodeBlock->numberOfPutToBaseOperations();
- m_putToBaseOperations.reserveCapacity(putToBaseCount);
- for (size_t i = 0; i < putToBaseCount; ++i)
- m_putToBaseOperations.append(PutToBaseOperation(isStrictMode()));
-
- ASSERT(m_putToBaseOperations.capacity() == putToBaseCount);
+ if (size_t putToBaseCount = unlinkedCodeBlock->numberOfPutToBaseOperations()) {
+ m_putToBaseOperations.reserveInitialCapacity(putToBaseCount);
+ for (size_t i = 0; i < putToBaseCount; ++i)
+ m_putToBaseOperations.uncheckedAppend(PutToBaseOperation(isStrictMode()));
+ }
// Copy and translate the UnlinkedInstructions
size_t instructionCount = unlinkedCodeBlock->instructions().size();
UnlinkedInstruction* pc = unlinkedCodeBlock->instructions().data();
- Vector<Instruction> instructions(instructionCount);
+ Vector<Instruction, 0, UnsafeVectorOverflow> instructions(instructionCount);
for (size_t i = 0; i < unlinkedCodeBlock->instructions().size(); ) {
unsigned opLength = opcodeLength(pc[i].u.opcode);
- instructions[i] = globalData()->interpreter->getOpcode(pc[i].u.opcode);
+ instructions[i] = vm()->interpreter->getOpcode(pc[i].u.opcode);
for (size_t j = 1; j < opLength; ++j) {
if (sizeof(int32_t) != sizeof(intptr_t))
instructions[i + j].u.pointer = 0;
@@ -1823,10 +1801,6 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
// fallthrough
}
case op_convert_this:
- case op_resolve:
- case op_resolve_base:
- case op_resolve_with_base:
- case op_resolve_with_this:
case op_get_by_id:
case op_call_put_result:
case op_get_callee: {
@@ -1851,6 +1825,79 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
break;
}
#endif
+ case op_resolve_base:
+ case op_resolve_base_to_global:
+ case op_resolve_base_to_global_dynamic:
+ case op_resolve_base_to_scope:
+ case op_resolve_base_to_scope_with_top_scope_check: {
+ instructions[i + 4].u.resolveOperations = &m_resolveOperations[pc[i + 4].u.operand];
+ instructions[i + 5].u.putToBaseOperation = &m_putToBaseOperations[pc[i + 5].u.operand];
+#if ENABLE(DFG_JIT)
+ ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
+ ASSERT(profile->m_bytecodeOffset == -1);
+ profile->m_bytecodeOffset = i;
+ ASSERT((opLength - 1) > 5);
+ instructions[i + opLength - 1] = profile;
+#endif
+ break;
+ }
+ case op_resolve_global_property:
+ case op_resolve_global_var:
+ case op_resolve_scoped_var:
+ case op_resolve_scoped_var_on_top_scope:
+ case op_resolve_scoped_var_with_top_scope_check: {
+ instructions[i + 3].u.resolveOperations = &m_resolveOperations[pc[i + 3].u.operand];
+ break;
+ }
+ case op_put_to_base:
+ case op_put_to_base_variable: {
+ instructions[i + 4].u.putToBaseOperation = &m_putToBaseOperations[pc[i + 4].u.operand];
+ break;
+ }
+ case op_resolve: {
+#if ENABLE(DFG_JIT)
+ ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
+ ASSERT(profile->m_bytecodeOffset == -1);
+ profile->m_bytecodeOffset = i;
+ ASSERT((opLength - 1) > 3);
+ instructions[i + opLength - 1] = profile;
+#endif
+ instructions[i + 3].u.resolveOperations = &m_resolveOperations[pc[i + 3].u.operand];
+ break;
+ }
+ case op_resolve_with_base:
+ case op_resolve_with_this: {
+ instructions[i + 4].u.resolveOperations = &m_resolveOperations[pc[i + 4].u.operand];
+ if (pc[i].u.opcode != op_resolve_with_this)
+ instructions[i + 5].u.putToBaseOperation = &m_putToBaseOperations[pc[i + 5].u.operand];
+#if ENABLE(DFG_JIT)
+ ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
+ ASSERT(profile->m_bytecodeOffset == -1);
+ profile->m_bytecodeOffset = i;
+ instructions[i + opLength - 1] = profile;
+#endif
+ break;
+ }
+ case op_new_object: {
+ int objectAllocationProfileIndex = pc[i + opLength - 1].u.operand;
+ ObjectAllocationProfile* objectAllocationProfile = &m_objectAllocationProfiles[objectAllocationProfileIndex];
+ int inferredInlineCapacity = pc[i + opLength - 2].u.operand;
+
+ instructions[i + opLength - 1] = objectAllocationProfile;
+ objectAllocationProfile->initialize(*vm(),
+ m_ownerExecutable.get(), m_globalObject->objectPrototype(), inferredInlineCapacity);
+ break;
+ }
+
+ case op_get_scoped_var: {
+#if ENABLE(DFG_JIT)
+ ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
+ ASSERT(profile->m_bytecodeOffset == -1);
+ profile->m_bytecodeOffset = i;
+ instructions[i + opLength - 1] = profile;
+#endif
+ break;
+ }
case op_call:
case op_call_eval: {
@@ -1892,16 +1939,22 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
break;
if (entry.couldBeWatched()) {
- instructions[i + 0] = globalData()->interpreter->getOpcode(op_init_global_const_check);
+ instructions[i + 0] = vm()->interpreter->getOpcode(op_init_global_const_check);
instructions[i + 1] = &globalObject->registerAt(entry.getIndex());
instructions[i + 3] = entry.addressOfIsWatched();
break;
}
- instructions[i + 0] = globalData()->interpreter->getOpcode(op_init_global_const);
+ instructions[i + 0] = vm()->interpreter->getOpcode(op_init_global_const);
instructions[i + 1] = &globalObject->registerAt(entry.getIndex());
break;
}
+
+ case op_debug: {
+ instructions[i + 4] = columnNumberForBytecodeOffset(i);
+ break;
+ }
+
default:
break;
}
@@ -1909,17 +1962,26 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
}
m_instructions = WTF::RefCountedArray<Instruction>(instructions);
+ // Set optimization thresholds only after m_instructions is initialized, since these
+ // rely on the instruction count (and are in theory permitted to also inspect the
+ // instruction stream to more accurate assess the cost of tier-up).
+ optimizeAfterWarmUp();
+ jitAfterWarmUp();
+
if (Options::dumpGeneratedBytecodes())
dumpBytecode();
- m_globalData->finishedCompiling(this);
+ m_vm->finishedCompiling(this);
}
CodeBlock::~CodeBlock()
{
+ if (m_vm->m_perBytecodeProfiler)
+ m_vm->m_perBytecodeProfiler->notifyDestruction(this);
+
#if ENABLE(DFG_JIT)
// Remove myself from the set of DFG code blocks. Note that I may not be in this set
// (because I'm not a DFG code block), in which case this is a no-op anyway.
- m_globalData->heap.m_dfgCodeBlocks.m_set.remove(this);
+ m_vm->heap.m_dfgCodeBlocks.m_set.remove(this);
#endif
#if ENABLE(VERBOSE_VALUE_PROFILE)
@@ -1958,13 +2020,13 @@ void CodeBlock::setNumParameters(int newValue)
m_numParameters = newValue;
#if ENABLE(VALUE_PROFILER)
- m_argumentValueProfiles.resize(newValue);
+ m_argumentValueProfiles.resizeToFit(newValue);
#endif
}
void CodeBlock::visitStructures(SlotVisitor& visitor, Instruction* vPC)
{
- Interpreter* interpreter = m_globalData->interpreter;
+ Interpreter* interpreter = m_vm->interpreter;
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) && vPC[4].u.structure) {
visitor.append(&vPC[4].u.structure);
@@ -2081,7 +2143,7 @@ void CodeBlock::visitAggregate(SlotVisitor& visitor)
visitor.addWeakReferenceHarvester(this);
#else // ENABLE(DFG_JIT)
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif // ENABLE(DFG_JIT)
}
@@ -2158,7 +2220,7 @@ static const bool verboseUnlinking = false;
void CodeBlock::finalizeUnconditionally()
{
#if ENABLE(LLINT)
- Interpreter* interpreter = m_globalData->interpreter;
+ Interpreter* interpreter = m_vm->interpreter;
if (!!numberOfInstructions()) {
const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
@@ -2197,7 +2259,7 @@ void CodeBlock::finalizeUnconditionally()
case op_get_array_length:
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -2219,12 +2281,8 @@ void CodeBlock::finalizeUnconditionally()
if (verboseUnlinking)
dataLog(*this, " has dead weak references, jettisoning during GC.\n");
- // Make sure that the baseline JIT knows that it should re-warm-up before
- // optimizing.
- alternative()->optimizeAfterWarmUp();
-
if (DFG::shouldShowDisassembly()) {
- dataLog(*this, "will be jettisoned because of the following dead references:\n");
+ dataLog(*this, " will be jettisoned because of the following dead references:\n");
for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) {
WeakReferenceTransition& transition = m_dfgData->transitions[i];
JSCell* origin = transition.m_codeOrigin.get();
@@ -2232,15 +2290,13 @@ void CodeBlock::finalizeUnconditionally()
JSCell* to = transition.m_to.get();
if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from))
continue;
- dataLogF(" Transition under %s, ", JSValue(origin).description());
- dataLogF("%s -> ", JSValue(from).description());
- dataLogF("%s.\n", JSValue(to).description());
+ dataLog(" Transition under ", JSValue(origin), ", ", JSValue(from), " -> ", JSValue(to), ".\n");
}
for (unsigned i = 0; i < m_dfgData->weakReferences.size(); ++i) {
JSCell* weak = m_dfgData->weakReferences[i].get();
if (Heap::isMarked(weak))
continue;
- dataLogF(" Weak reference %s.\n", JSValue(weak).description());
+ dataLog(" Weak reference ", JSValue(weak), ".\n");
}
}
@@ -2286,7 +2342,7 @@ void CodeBlock::finalizeUnconditionally()
stub->executable()->hashFor(callLinkInfo(i).specializationKind()),
", stub routine ", RawPointer(stub), ".\n");
}
- callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
+ callLinkInfo(i).unlink(*m_vm, repatchBuffer);
}
} else if (!Heap::isMarked(callLinkInfo(i).callee.get())) {
if (verboseUnlinking) {
@@ -2297,7 +2353,7 @@ void CodeBlock::finalizeUnconditionally()
callLinkInfo(i).specializationKind()),
").\n");
}
- callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
+ callLinkInfo(i).unlink(*m_vm, repatchBuffer);
}
}
if (!!callLinkInfo(i).lastSeenCallee
@@ -2310,7 +2366,7 @@ void CodeBlock::finalizeUnconditionally()
if (stubInfo.visitWeakReferences())
continue;
- resetStubInternal(repatchBuffer, stubInfo);
+ resetStubDuringGCInternal(repatchBuffer, stubInfo);
}
}
#endif
@@ -2348,6 +2404,12 @@ void CodeBlock::resetStubInternal(RepatchBuffer& repatchBuffer, StructureStubInf
stubInfo.reset();
}
+
+void CodeBlock::resetStubDuringGCInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
+{
+ resetStubInternal(repatchBuffer, stubInfo);
+ stubInfo.resetByGC = true;
+}
#endif
void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
@@ -2362,6 +2424,8 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
visitor.append(&m_functionExprs[i]);
for (size_t i = 0; i < m_functionDecls.size(); ++i)
visitor.append(&m_functionDecls[i]);
+ for (unsigned i = 0; i < m_objectAllocationProfiles.size(); ++i)
+ m_objectAllocationProfiles[i].visitAggregate(visitor);
updateAllPredictions(Collection);
}
@@ -2386,85 +2450,9 @@ void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
#endif
}
-#if ENABLE(BYTECODE_COMMENTS)
-// Finds the comment string for the specified bytecode offset/PC is available.
-const char* CodeBlock::commentForBytecodeOffset(unsigned bytecodeOffset)
-{
- ASSERT(bytecodeOffset < instructions().size());
-
- Vector<Comment>& comments = m_bytecodeComments;
- size_t numberOfComments = comments.size();
- const char* result = 0;
-
- if (!numberOfComments)
- return 0; // No comments to match with.
-
- // The next match is most likely the next comment in the list.
- // Do a quick check to see if that is a match first.
- // m_bytecodeCommentIterator should already be pointing to the
- // next comment we should check.
-
- ASSERT(m_bytecodeCommentIterator < comments.size());
-
- size_t i = m_bytecodeCommentIterator;
- size_t commentPC = comments[i].pc;
- if (commentPC == bytecodeOffset) {
- // We've got a match. All done!
- m_bytecodeCommentIterator = i;
- result = comments[i].string;
- } else if (commentPC > bytecodeOffset) {
- // The current comment is already greater than the requested PC.
- // Start searching from the first comment.
- i = 0;
- } else {
- // Otherwise, the current comment's PC is less than the requested PC.
- // Hence, we can just start searching from the next comment in the
- // list.
- i++;
- }
-
- // If the result is still not found, do a linear search in the range
- // that we've determined above.
- if (!result) {
- for (; i < comments.size(); ++i) {
- commentPC = comments[i].pc;
- if (commentPC == bytecodeOffset) {
- result = comments[i].string;
- break;
- }
- if (comments[i].pc > bytecodeOffset) {
- // The current comment PC is already past the requested
- // bytecodeOffset. Hence, there are no more possible
- // matches. Just fail.
- break;
- }
- }
- }
-
- // Update the iterator to point to the next comment.
- if (++i >= numberOfComments) {
- // At most point to the last comment entry. This ensures that the
- // next time we call this function, the quick checks will at least
- // have one entry to check and can fail fast if appropriate.
- i = numberOfComments - 1;
- }
- m_bytecodeCommentIterator = i;
- return result;
-}
-
-void CodeBlock::dumpBytecodeComments()
-{
- Vector<Comment>& comments = m_bytecodeComments;
- printf("Comments for codeblock %p: size %lu\n", this, comments.size());
- for (size_t i = 0; i < comments.size(); ++i)
- printf(" pc %lu : '%s'\n", comments[i].pc, comments[i].string);
- printf("End of comments for codeblock %p\n", this);
-}
-#endif // ENABLE_BYTECODE_COMMENTS
-
HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(bytecodeOffset < instructions().size());
+ RELEASE_ASSERT(bytecodeOffset < instructions().size());
if (!m_rareData)
return 0;
@@ -2480,16 +2468,29 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
return 0;
}
-int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
+unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
{
- ASSERT(bytecodeOffset < instructions().size());
+ RELEASE_ASSERT(bytecodeOffset < instructions().size());
return m_ownerExecutable->lineNo() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
}
-void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
+unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset)
{
- m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset);
+ int divot;
+ int startOffset;
+ int endOffset;
+ unsigned line;
+ unsigned column;
+ expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
+ return column;
+}
+
+void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
+{
+ m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
divot += m_sourceOffset;
+ column += line ? 1 : firstLineColumnOffset();
+ line += m_ownerExecutable->lineNo();
}
void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
@@ -2502,8 +2503,6 @@ void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
m_callLinkInfos.shrinkToFit();
#endif
#if ENABLE(VALUE_PROFILER)
- if (shrinkMode == EarlyShrink)
- m_argumentValueProfiles.shrinkToFit();
m_rareCaseProfiles.shrinkToFit();
m_specialFastCaseProfiles.shrinkToFit();
#endif
@@ -2547,7 +2546,7 @@ void CodeBlock::createActivation(CallFrame* callFrame)
ASSERT(codeType() == FunctionCode);
ASSERT(needsFullScopeChain());
ASSERT(!callFrame->uncheckedR(activationRegister()).jsValue());
- JSActivation* activation = JSActivation::create(callFrame->globalData(), callFrame, this);
+ JSActivation* activation = JSActivation::create(callFrame->vm(), callFrame, this);
callFrame->uncheckedR(activationRegister()) = JSValue(activation);
callFrame->setScope(activation);
}
@@ -2575,13 +2574,13 @@ void CodeBlock::unlinkCalls()
#endif
if (!m_callLinkInfos.size())
return;
- if (!m_globalData->canUseJIT())
+ if (!m_vm->canUseJIT())
return;
RepatchBuffer repatchBuffer(this);
for (size_t i = 0; i < m_callLinkInfos.size(); i++) {
if (!m_callLinkInfos[i].isLinked())
continue;
- m_callLinkInfos[i].unlink(*m_globalData, repatchBuffer);
+ m_callLinkInfos[i].unlink(*m_vm, repatchBuffer);
}
}
@@ -2595,7 +2594,7 @@ void CodeBlock::unlinkIncomingCalls()
return;
RepatchBuffer repatchBuffer(this);
while (m_incomingCalls.begin() != m_incomingCalls.end())
- m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
+ m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer);
}
#endif // ENABLE(JIT)
@@ -2662,12 +2661,13 @@ ClosureCallStubRoutine* CodeBlock::findClosureCallForReturnPC(ReturnAddressPtr r
continue;
if (!info.stub->code().executableMemory()->contains(returnAddress.value()))
continue;
-
+
+ RELEASE_ASSERT(info.stub->codeOrigin().bytecodeIndex < CodeOrigin::maximumBytecodeIndex);
return info.stub.get();
}
// The stub routine may have been jettisoned. This is rare, but we have to handle it.
- const JITStubRoutineSet& set = m_globalData->heap.jitStubRoutines();
+ const JITStubRoutineSet& set = m_vm->heap.jitStubRoutines();
for (unsigned i = set.size(); i--;) {
GCAwareJITStubRoutine* genericStub = set.at(i);
if (!genericStub->isClosureCall())
@@ -2675,6 +2675,7 @@ ClosureCallStubRoutine* CodeBlock::findClosureCallForReturnPC(ReturnAddressPtr r
ClosureCallStubRoutine* stub = static_cast<ClosureCallStubRoutine*>(genericStub);
if (!stub->code().executableMemory()->contains(returnAddress.value()))
continue;
+ RELEASE_ASSERT(stub->codeOrigin().bytecodeIndex < CodeOrigin::maximumBytecodeIndex);
return stub;
}
@@ -2702,11 +2703,11 @@ unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddre
&& returnAddress.value() <= LLInt::getCodePtr(llint_end))
#endif
{
- ASSERT(exec->codeBlock());
- ASSERT(exec->codeBlock() == this);
- ASSERT(JITCode::isBaselineCode(getJITType()));
+ RELEASE_ASSERT(exec->codeBlock());
+ RELEASE_ASSERT(exec->codeBlock() == this);
+ RELEASE_ASSERT(JITCode::isBaselineCode(getJITType()));
Instruction* instruction = exec->currentVPC();
- ASSERT(instruction);
+ RELEASE_ASSERT(instruction);
instruction = adjustPCIfAtCallSite(instruction);
return bytecodeOffset(instruction);
@@ -2716,19 +2717,31 @@ unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddre
#if ENABLE(JIT)
if (!m_rareData)
return 1;
- Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
+ Vector<CallReturnOffsetToBytecodeOffset, 0, UnsafeVectorOverflow>& callIndices = m_rareData->m_callReturnIndexVector;
if (!callIndices.size())
return 1;
if (getJITCode().getExecutableMemory()->contains(returnAddress.value())) {
unsigned callReturnOffset = getJITCode().offsetOf(returnAddress.value());
CallReturnOffsetToBytecodeOffset* result =
- binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), callReturnOffset);
- ASSERT(result->callReturnOffset == callReturnOffset);
+ binarySearch<CallReturnOffsetToBytecodeOffset, unsigned>(
+ callIndices, callIndices.size(), callReturnOffset, getCallReturnOffset);
+ RELEASE_ASSERT(result->callReturnOffset == callReturnOffset);
+ RELEASE_ASSERT(result->bytecodeOffset < instructionCount());
return result->bytecodeOffset;
}
-
- return findClosureCallForReturnPC(returnAddress)->codeOrigin().bytecodeIndex;
+ ClosureCallStubRoutine* closureInfo = findClosureCallForReturnPC(returnAddress);
+ CodeOrigin origin = closureInfo->codeOrigin();
+ while (InlineCallFrame* inlineCallFrame = origin.inlineCallFrame) {
+ if (inlineCallFrame->baselineCodeBlock() == this)
+ break;
+ origin = inlineCallFrame->caller;
+ RELEASE_ASSERT(origin.bytecodeIndex < CodeOrigin::maximumBytecodeIndex);
+ }
+ RELEASE_ASSERT(origin.bytecodeIndex < CodeOrigin::maximumBytecodeIndex);
+ unsigned bytecodeIndex = origin.bytecodeIndex;
+ RELEASE_ASSERT(bytecodeIndex < instructionCount());
+ return bytecodeIndex;
#endif // ENABLE(JIT)
#if !ENABLE(LLINT) && !ENABLE(JIT)
@@ -2743,13 +2756,20 @@ bool CodeBlock::codeOriginForReturn(ReturnAddressPtr returnAddress, CodeOrigin&
return false;
if (!getJITCode().getExecutableMemory()->contains(returnAddress.value())) {
- codeOrigin = findClosureCallForReturnPC(returnAddress)->codeOrigin();
+ ClosureCallStubRoutine* stub = findClosureCallForReturnPC(returnAddress);
+ ASSERT(stub);
+ if (!stub)
+ return false;
+ codeOrigin = stub->codeOrigin();
return true;
}
unsigned offset = getJITCode().offsetOf(returnAddress.value());
- CodeOriginAtCallReturnOffset* entry = binarySearch<CodeOriginAtCallReturnOffset, unsigned, getCallReturnOffsetForCodeOrigin>(codeOrigins().begin(), codeOrigins().size(), offset, WTF::KeyMustNotBePresentInArray);
- if (entry->callReturnOffset != offset)
+ CodeOriginAtCallReturnOffset* entry =
+ tryBinarySearch<CodeOriginAtCallReturnOffset, unsigned>(
+ codeOrigins(), codeOrigins().size(), offset,
+ getCallReturnOffsetForCodeOrigin);
+ if (!entry)
return false;
codeOrigin = entry->codeOrigin;
return true;
@@ -2765,8 +2785,8 @@ void CodeBlock::clearEvalCache()
m_rareData->m_evalCodeCache.clear();
}
-template<typename T>
-inline void replaceExistingEntries(Vector<T>& target, Vector<T>& source)
+template<typename T, size_t inlineCapacity, typename U, typename V>
+inline void replaceExistingEntries(Vector<T, inlineCapacity, U>& target, Vector<T, inlineCapacity, V>& source)
{
ASSERT(target.size() <= source.size());
for (size_t i = 0; i < target.size(); ++i)
@@ -2795,12 +2815,10 @@ void CodeBlock::reoptimize()
{
ASSERT(replacement() != this);
ASSERT(replacement()->alternative() == this);
- replacement()->tallyFrequentExitSites();
if (DFG::shouldShowDisassembly())
dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
replacement()->jettison();
countReoptimization();
- optimizeAfterWarmUp();
}
CodeBlock* ProgramCodeBlock::replacement()
@@ -2859,31 +2877,30 @@ DFG::CapabilityLevel FunctionCodeBlock::canCompileWithDFGInternal()
return DFG::canCompileFunctionForCall(this);
}
-void ProgramCodeBlock::jettison()
+void CodeBlock::jettison()
{
ASSERT(JITCode::isOptimizingJIT(getJITType()));
ASSERT(this == replacement());
+ alternative()->optimizeAfterWarmUp();
+ tallyFrequentExitSites();
if (DFG::shouldShowDisassembly())
dataLog("Jettisoning ", *this, ".\n");
- static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
+ jettisonImpl();
}
-void EvalCodeBlock::jettison()
+void ProgramCodeBlock::jettisonImpl()
{
- ASSERT(JITCode::isOptimizingJIT(getJITType()));
- ASSERT(this == replacement());
- if (DFG::shouldShowDisassembly())
- dataLog("Jettisoning ", *this, ".\n");
- static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
+ static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*vm());
}
-void FunctionCodeBlock::jettison()
+void EvalCodeBlock::jettisonImpl()
{
- ASSERT(JITCode::isOptimizingJIT(getJITType()));
- ASSERT(this == replacement());
- if (DFG::shouldShowDisassembly())
- dataLog("Jettisoning ", *this, ".\n");
- static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
+ static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*vm());
+}
+
+void FunctionCodeBlock::jettisonImpl()
+{
+ static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall);
}
bool ProgramCodeBlock::jitCompileImpl(ExecState* exec)
@@ -2908,6 +2925,217 @@ bool FunctionCodeBlock::jitCompileImpl(ExecState* exec)
}
#endif
+JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
+{
+ if (!codeOrigin.inlineCallFrame)
+ return globalObject();
+ return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->generatedBytecode().globalObject();
+}
+
+unsigned CodeBlock::reoptimizationRetryCounter() const
+{
+ ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
+ return m_reoptimizationRetryCounter;
+}
+
+void CodeBlock::countReoptimization()
+{
+ m_reoptimizationRetryCounter++;
+ if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
+ m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
+}
+
+unsigned CodeBlock::numberOfDFGCompiles()
+{
+ ASSERT(JITCode::isBaselineCode(getJITType()));
+ return (JITCode::isOptimizingJIT(replacement()->getJITType()) ? 1 : 0) + m_reoptimizationRetryCounter;
+}
+
+int32_t CodeBlock::codeTypeThresholdMultiplier() const
+{
+ if (codeType() == EvalCode)
+ return Options::evalThresholdMultiplier();
+
+ return 1;
+}
+
+double CodeBlock::optimizationThresholdScalingFactor()
+{
+ // This expression arises from doing a least-squares fit of
+ //
+ // F[x_] =: a * Sqrt[x + b] + Abs[c * x] + d
+ //
+ // against the data points:
+ //
+ // x F[x_]
+ // 10 0.9 (smallest reasonable code block)
+ // 200 1.0 (typical small-ish code block)
+ // 320 1.2 (something I saw in 3d-cube that I wanted to optimize)
+ // 1268 5.0 (something I saw in 3d-cube that I didn't want to optimize)
+ // 4000 5.5 (random large size, used to cause the function to converge to a shallow curve of some sort)
+ // 10000 6.0 (similar to above)
+ //
+ // I achieve the minimization using the following Mathematica code:
+ //
+ // MyFunctionTemplate[x_, a_, b_, c_, d_] := a*Sqrt[x + b] + Abs[c*x] + d
+ //
+ // samples = {{10, 0.9}, {200, 1}, {320, 1.2}, {1268, 5}, {4000, 5.5}, {10000, 6}}
+ //
+ // solution =
+ // Minimize[Plus @@ ((MyFunctionTemplate[#[[1]], a, b, c, d] - #[[2]])^2 & /@ samples),
+ // {a, b, c, d}][[2]]
+ //
+ // And the code below (to initialize a, b, c, d) is generated by:
+ //
+ // Print["const double " <> ToString[#[[1]]] <> " = " <>
+ // If[#[[2]] < 0.00001, "0.0", ToString[#[[2]]]] <> ";"] & /@ solution
+ //
+ // We've long known the following to be true:
+ // - Small code blocks are cheap to optimize and so we should do it sooner rather
+ // than later.
+ // - Large code blocks are expensive to optimize and so we should postpone doing so,
+ // and sometimes have a large enough threshold that we never optimize them.
+ // - The difference in cost is not totally linear because (a) just invoking the
+ // DFG incurs some base cost and (b) for large code blocks there is enough slop
+ // in the correlation between instruction count and the actual compilation cost
+ // that for those large blocks, the instruction count should not have a strong
+ // influence on our threshold.
+ //
+ // I knew the goals but I didn't know how to achieve them; so I picked an interesting
+ // example where the heuristics were right (code block in 3d-cube with instruction
+ // count 320, which got compiled early as it should have been) and one where they were
+ // totally wrong (code block in 3d-cube with instruction count 1268, which was expensive
+ // to compile and didn't run often enough to warrant compilation in my opinion), and
+ // then threw in additional data points that represented my own guess of what our
+ // heuristics should do for some round-numbered examples.
+ //
+ // The expression to which I decided to fit the data arose because I started with an
+ // affine function, and then did two things: put the linear part in an Abs to ensure
+ // that the fit didn't end up choosing a negative value of c (which would result in
+ // the function turning over and going negative for large x) and I threw in a Sqrt
+ // term because Sqrt represents my intution that the function should be more sensitive
+ // to small changes in small values of x, but less sensitive when x gets large.
+
+ // Note that the current fit essentially eliminates the linear portion of the
+ // expression (c == 0.0).
+ const double a = 0.061504;
+ const double b = 1.02406;
+ const double c = 0.0;
+ const double d = 0.825914;
+
+ double instructionCount = this->instructionCount();
+
+ ASSERT(instructionCount); // Make sure this is called only after we have an instruction stream; otherwise it'll just return the value of d, which makes no sense.
+
+ double result = d + a * sqrt(instructionCount + b) + c * instructionCount;
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog(*this, ": instruction count is ", instructionCount, ", scaling execution counter by ", result, " * ", codeTypeThresholdMultiplier(), "\n");
+#endif
+ return result * codeTypeThresholdMultiplier();
+}
+
+static int32_t clipThreshold(double threshold)
+{
+ if (threshold < 1.0)
+ return 1;
+
+ if (threshold > static_cast<double>(std::numeric_limits<int32_t>::max()))
+ return std::numeric_limits<int32_t>::max();
+
+ return static_cast<int32_t>(threshold);
+}
+
+int32_t CodeBlock::counterValueForOptimizeAfterWarmUp()
+{
+ return clipThreshold(
+ Options::thresholdForOptimizeAfterWarmUp() *
+ optimizationThresholdScalingFactor() *
+ (1 << reoptimizationRetryCounter()));
+}
+
+int32_t CodeBlock::counterValueForOptimizeAfterLongWarmUp()
+{
+ return clipThreshold(
+ Options::thresholdForOptimizeAfterLongWarmUp() *
+ optimizationThresholdScalingFactor() *
+ (1 << reoptimizationRetryCounter()));
+}
+
+int32_t CodeBlock::counterValueForOptimizeSoon()
+{
+ return clipThreshold(
+ Options::thresholdForOptimizeSoon() *
+ optimizationThresholdScalingFactor() *
+ (1 << reoptimizationRetryCounter()));
+}
+
+bool CodeBlock::checkIfOptimizationThresholdReached()
+{
+ return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this);
+}
+
+void CodeBlock::optimizeNextInvocation()
+{
+ m_jitExecuteCounter.setNewThreshold(0, this);
+}
+
+void CodeBlock::dontOptimizeAnytimeSoon()
+{
+ m_jitExecuteCounter.deferIndefinitely();
+}
+
+void CodeBlock::optimizeAfterWarmUp()
+{
+ m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterWarmUp(), this);
+}
+
+void CodeBlock::optimizeAfterLongWarmUp()
+{
+ m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterLongWarmUp(), this);
+}
+
+void CodeBlock::optimizeSoon()
+{
+ m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeSoon(), this);
+}
+
+#if ENABLE(JIT)
+uint32_t CodeBlock::adjustedExitCountThreshold(uint32_t desiredThreshold)
+{
+ ASSERT(getJITType() == JITCode::DFGJIT);
+ // Compute this the lame way so we don't saturate. This is called infrequently
+ // enough that this loop won't hurt us.
+ unsigned result = desiredThreshold;
+ for (unsigned n = baselineVersion()->reoptimizationRetryCounter(); n--;) {
+ unsigned newResult = result << 1;
+ if (newResult < result)
+ return std::numeric_limits<uint32_t>::max();
+ result = newResult;
+ }
+ return result;
+}
+
+uint32_t CodeBlock::exitCountThresholdForReoptimization()
+{
+ return adjustedExitCountThreshold(Options::osrExitCountForReoptimization() * codeTypeThresholdMultiplier());
+}
+
+uint32_t CodeBlock::exitCountThresholdForReoptimizationFromLoop()
+{
+ return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop() * codeTypeThresholdMultiplier());
+}
+
+bool CodeBlock::shouldReoptimizeNow()
+{
+ return osrExitCounter() >= exitCountThresholdForReoptimization();
+}
+
+bool CodeBlock::shouldReoptimizeFromLoopNow()
+{
+ return osrExitCounter() >= exitCountThresholdForReoptimizationFromLoop();
+}
+#endif
+
#if ENABLE(VALUE_PROFILER)
ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset)
{
@@ -3020,11 +3248,11 @@ void CodeBlock::tallyFrequentExitSites()
for (unsigned i = 0; i < m_dfgData->osrExit.size(); ++i) {
DFG::OSRExit& exit = m_dfgData->osrExit[i];
- if (!exit.considerAddingAsFrequentExitSite(this, profiledBlock))
+ if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
continue;
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("OSR exit #", i, " (bc#", exit.m_codeOrigin.bytecodeIndex, ", @", exit.m_nodeIndex, ", ", DFG::exitKindToString(exit.m_kind), ") for ", *this, " occurred frequently: counting as frequent exit site.\n");
+ dataLog("OSR exit #", i, " (bc#", exit.m_codeOrigin.bytecodeIndex, ", ", exit.m_kind, ") for ", *this, " occurred frequently: counting as frequent exit site.\n");
#endif
}
}
@@ -3063,18 +3291,18 @@ void CodeBlock::dumpValueProfiles()
size_t CodeBlock::predictedMachineCodeSize()
{
- // This will be called from CodeBlock::CodeBlock before either m_globalData or the
+ // This will be called from CodeBlock::CodeBlock before either m_vm 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)
+ if (!m_vm)
return 0;
- if (!m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT)
+ if (!m_vm->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();
+ double multiplier = m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.mean() +
+ m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.standardDeviation();
// Be paranoid: silently reject bogus multipiers. Silently doing the "wrong" thing
// here is OK, since this whole method is just a heuristic.
@@ -3095,7 +3323,7 @@ size_t CodeBlock::predictedMachineCodeSize()
bool CodeBlock::usesOpcode(OpcodeID opcodeID)
{
- Interpreter* interpreter = globalData()->interpreter;
+ Interpreter* interpreter = vm()->interpreter;
Instruction* instructionsBegin = instructions().begin();
unsigned instructionCount = instructions().size();
@@ -3110,7 +3338,7 @@ bool CodeBlock::usesOpcode(OpcodeID opcodeID)
FOR_EACH_OPCODE_ID(DEFINE_OP)
#undef DEFINE_OP
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index eec95cac1..0b3d18e17 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,6 @@
#include "CodeBlockHash.h"
#include "CodeOrigin.h"
#include "CodeType.h"
-#include "Comment.h"
#include "CompactJITCodeMap.h"
#include "DFGCodeBlocks.h"
#include "DFGCommon.h"
@@ -51,6 +50,7 @@
#include "ExecutionCounter.h"
#include "ExpressionRangeInfo.h"
#include "HandlerInfo.h"
+#include "ObjectAllocationProfile.h"
#include "Options.h"
#include "Instruction.h"
#include "JITCode.h"
@@ -61,7 +61,7 @@
#include "LLIntCallLinkInfo.h"
#include "LazyOperandValueProfile.h"
#include "LineInfo.h"
-#include "Nodes.h"
+#include "ProfilerCompilation.h"
#include "RegExpObject.h"
#include "ResolveOperation.h"
#include "StructureStubInfo.h"
@@ -77,1511 +77,1407 @@
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
-// Set ENABLE_BYTECODE_COMMENTS to 1 to enable recording bytecode generator
-// comments for the bytecodes that it generates. This will allow
-// CodeBlock::dump() to provide some contextual info about the bytecodes.
-//
-// The way this comment system works is as follows:
-// 1. The BytecodeGenerator calls prependComment() with a constant comment
-// string in .text. The string must not be a stack or heap allocated
-// string.
-// 2. When the BytecodeGenerator's emitOpcode() is called, the last
-// prepended comment will be recorded with the PC of the opcode being
-// emitted. This comment is being recorded in the CodeBlock's
-// m_bytecodeComments.
-// 3. When CodeBlock::dump() is called, it will pair up the comments with
-// their corresponding bytecodes based on the bytecode and comment's
-// PC. If a matching pair is found, the comment will be printed after
-// the bytecode. If not, no comment is printed.
-//
-// NOTE: Enabling this will consume additional memory at runtime to store
-// the comments. Since these comments are only useful for VM debugging
-// (as opposed to app debugging), this feature is to be disabled by default,
-// and can be enabled as needed for VM development use only.
-
-#define ENABLE_BYTECODE_COMMENTS 0
-
namespace JSC {
- class DFGCodeBlocks;
- class ExecState;
- class LLIntOffsetsExtractor;
- class RepatchBuffer;
+class DFGCodeBlocks;
+class ExecState;
+class LLIntOffsetsExtractor;
+class RepatchBuffer;
- inline int unmodifiedArgumentsRegister(int argumentsRegister) { return argumentsRegister - 1; }
+inline int unmodifiedArgumentsRegister(int argumentsRegister) { return argumentsRegister - 1; }
- static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
+static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
- class CodeBlock : public UnconditionalFinalizer, public WeakReferenceHarvester {
- WTF_MAKE_FAST_ALLOCATED;
- friend class JIT;
- friend class LLIntOffsetsExtractor;
- public:
- enum CopyParsedBlockTag { CopyParsedBlock };
- protected:
- CodeBlock(CopyParsedBlockTag, CodeBlock& other);
+class CodeBlock : public UnconditionalFinalizer, public WeakReferenceHarvester {
+ WTF_MAKE_FAST_ALLOCATED;
+ friend class JIT;
+ friend class LLIntOffsetsExtractor;
+public:
+ enum CopyParsedBlockTag { CopyParsedBlock };
+protected:
+ CodeBlock(CopyParsedBlockTag, CodeBlock& other);
- CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSGlobalObject*, unsigned baseScopeDepth, PassRefPtr<SourceProvider>, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative);
+ CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSGlobalObject*, unsigned baseScopeDepth, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset, PassOwnPtr<CodeBlock> alternative);
- WriteBarrier<JSGlobalObject> m_globalObject;
- Heap* m_heap;
+ WriteBarrier<JSGlobalObject> m_globalObject;
+ Heap* m_heap;
- public:
- JS_EXPORT_PRIVATE virtual ~CodeBlock();
+public:
+ JS_EXPORT_PRIVATE virtual ~CodeBlock();
+
+ UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
- CodeBlockHash hash() const;
- void dumpAssumingJITType(PrintStream&, JITCode::JITType) const;
- void dump(PrintStream&) const;
+ String inferredName() const;
+ CodeBlockHash hash() const;
+ String sourceCodeForTools() const; // Not quite the actual source we parsed; this will do things like prefix the source for a function with a reified signature.
+ String sourceCodeOnOneLine() const; // As sourceCodeForTools(), but replaces all whitespace runs with a single space.
+ void dumpAssumingJITType(PrintStream&, JITCode::JITType) const;
+ void dump(PrintStream&) const;
- int numParameters() const { return m_numParameters; }
- void setNumParameters(int newValue);
+ int numParameters() const { return m_numParameters; }
+ void setNumParameters(int newValue);
- int* addressOfNumParameters() { return &m_numParameters; }
- static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }
+ int* addressOfNumParameters() { return &m_numParameters; }
+ static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }
- CodeBlock* alternative() { return m_alternative.get(); }
- PassOwnPtr<CodeBlock> releaseAlternative() { return m_alternative.release(); }
- void setAlternative(PassOwnPtr<CodeBlock> alternative) { m_alternative = alternative; }
+ CodeBlock* alternative() { return m_alternative.get(); }
+ PassOwnPtr<CodeBlock> releaseAlternative() { return m_alternative.release(); }
+ void setAlternative(PassOwnPtr<CodeBlock> alternative) { m_alternative = alternative; }
- CodeSpecializationKind specializationKind() const
- {
- return specializationFromIsConstruct(m_isConstructor);
- }
+ CodeSpecializationKind specializationKind() const
+ {
+ return specializationFromIsConstruct(m_isConstructor);
+ }
#if ENABLE(JIT)
- CodeBlock* baselineVersion()
- {
- CodeBlock* result = replacement();
- if (!result)
- return 0; // This can happen if we're in the process of creating the baseline version.
- while (result->alternative())
- result = result->alternative();
- ASSERT(result);
- ASSERT(JITCode::isBaselineCode(result->getJITType()));
- return result;
- }
+ CodeBlock* baselineVersion()
+ {
+ CodeBlock* result = replacement();
+ if (!result)
+ return 0; // This can happen if we're in the process of creating the baseline version.
+ while (result->alternative())
+ result = result->alternative();
+ ASSERT(result);
+ ASSERT(JITCode::isBaselineCode(result->getJITType()));
+ return result;
+ }
+#else
+ CodeBlock* baselineVersion()
+ {
+ return this;
+ }
#endif
- void visitAggregate(SlotVisitor&);
+ void visitAggregate(SlotVisitor&);
- static void dumpStatistics();
+ static void dumpStatistics();
- void dumpBytecode();
- void dumpBytecode(unsigned bytecodeOffset);
- void printStructures(const Instruction*);
- void printStructure(const char* name, const Instruction*, int operand);
+ void dumpBytecode(PrintStream& = WTF::dataFile());
+ void dumpBytecode(PrintStream&, unsigned bytecodeOffset);
+ void printStructures(PrintStream&, const Instruction*);
+ void printStructure(PrintStream&, const char* name, const Instruction*, int operand);
- bool isStrictMode() const { return m_isStrictMode; }
-
- inline bool isKnownNotImmediate(int index)
- {
- if (index == m_thisRegister && !m_isStrictMode)
- return true;
+ bool isStrictMode() const { return m_isStrictMode; }
- if (isConstantRegisterIndex(index))
- return getConstant(index).isCell();
-
- return false;
- }
-
- ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
- {
- return index >= m_numVars;
- }
-
- void dumpBytecodeCommentAndNewLine(int location);
-#if ENABLE(BYTECODE_COMMENTS)
- const char* commentForBytecodeOffset(unsigned bytecodeOffset);
- void dumpBytecodeComments();
-#endif
-
- HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
- int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
- void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
+ inline bool isKnownNotImmediate(int index)
+ {
+ if (index == m_thisRegister && !m_isStrictMode)
+ return true;
- uint32_t addResolve()
- {
- m_resolveOperations.grow(m_resolveOperations.size() + 1);
- return m_resolveOperations.size() - 1;
- }
- uint32_t addPutToBase()
- {
- m_putToBaseOperations.append(PutToBaseOperation(isStrictMode()));
- return m_putToBaseOperations.size() - 1;
- }
+ if (isConstantRegisterIndex(index))
+ return getConstant(index).isCell();
- ResolveOperations* resolveOperations(uint32_t i)
- {
- return &m_resolveOperations[i];
- }
+ return false;
+ }
- PutToBaseOperation* putToBaseOperation(uint32_t i)
- {
- return &m_putToBaseOperations[i];
- }
+ ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
+ {
+ return index >= m_numVars;
+ }
- size_t numberOfResolveOperations() const { return m_resolveOperations.size(); }
- size_t numberOfPutToBaseOperations() const { return m_putToBaseOperations.size(); }
+ HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
+ unsigned lineNumberForBytecodeOffset(unsigned bytecodeOffset);
+ unsigned columnNumberForBytecodeOffset(unsigned bytecodeOffset);
+ void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
+ int& startOffset, int& endOffset, unsigned& line, unsigned& column);
#if ENABLE(JIT)
- StructureStubInfo& getStubInfo(ReturnAddressPtr returnAddress)
- {
- return *(binarySearch<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value()));
- }
+ StructureStubInfo& getStubInfo(ReturnAddressPtr returnAddress)
+ {
+ return *(binarySearch<StructureStubInfo, void*>(m_structureStubInfos, m_structureStubInfos.size(), returnAddress.value(), getStructureStubInfoReturnLocation));
+ }
- StructureStubInfo& getStubInfo(unsigned bytecodeIndex)
- {
- return *(binarySearch<StructureStubInfo, unsigned, getStructureStubInfoBytecodeIndex>(m_structureStubInfos.begin(), m_structureStubInfos.size(), bytecodeIndex));
- }
+ StructureStubInfo& getStubInfo(unsigned bytecodeIndex)
+ {
+ return *(binarySearch<StructureStubInfo, unsigned>(m_structureStubInfos, m_structureStubInfos.size(), bytecodeIndex, getStructureStubInfoBytecodeIndex));
+ }
- void resetStub(StructureStubInfo&);
+ void resetStub(StructureStubInfo&);
- ByValInfo& getByValInfo(unsigned bytecodeIndex)
- {
- return *(binarySearch<ByValInfo, unsigned, getByValInfoBytecodeIndex>(m_byValInfos.begin(), m_byValInfos.size(), bytecodeIndex));
- }
+ ByValInfo& getByValInfo(unsigned bytecodeIndex)
+ {
+ return *(binarySearch<ByValInfo, unsigned>(m_byValInfos, m_byValInfos.size(), bytecodeIndex, getByValInfoBytecodeIndex));
+ }
- CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress)
- {
- return *(binarySearch<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value()));
- }
+ CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress)
+ {
+ return *(binarySearch<CallLinkInfo, void*>(m_callLinkInfos, m_callLinkInfos.size(), returnAddress.value(), getCallLinkInfoReturnLocation));
+ }
- CallLinkInfo& getCallLinkInfo(unsigned bytecodeIndex)
- {
- ASSERT(JITCode::isBaselineCode(getJITType()));
- return *(binarySearch<CallLinkInfo, unsigned, getCallLinkInfoBytecodeIndex>(m_callLinkInfos.begin(), m_callLinkInfos.size(), bytecodeIndex));
- }
+ CallLinkInfo& getCallLinkInfo(unsigned bytecodeIndex)
+ {
+ ASSERT(JITCode::isBaselineCode(getJITType()));
+ return *(binarySearch<CallLinkInfo, unsigned>(m_callLinkInfos, m_callLinkInfos.size(), bytecodeIndex, getCallLinkInfoBytecodeIndex));
+ }
#endif // ENABLE(JIT)
#if ENABLE(LLINT)
- Instruction* adjustPCIfAtCallSite(Instruction*);
+ Instruction* adjustPCIfAtCallSite(Instruction*);
#endif
- unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
+ unsigned bytecodeOffset(ExecState*, ReturnAddressPtr);
#if ENABLE(JIT)
- unsigned bytecodeOffsetForCallAtIndex(unsigned index)
- {
- if (!m_rareData)
- return 1;
- Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
- if (!callIndices.size())
- return 1;
- ASSERT(index < m_rareData->m_callReturnIndexVector.size());
- return m_rareData->m_callReturnIndexVector[index].bytecodeOffset;
- }
+ unsigned bytecodeOffsetForCallAtIndex(unsigned index)
+ {
+ if (!m_rareData)
+ return 1;
+ Vector<CallReturnOffsetToBytecodeOffset, 0, UnsafeVectorOverflow>& callIndices = m_rareData->m_callReturnIndexVector;
+ if (!callIndices.size())
+ return 1;
+ // FIXME: Fix places in DFG that call out to C that don't set the CodeOrigin. https://bugs.webkit.org/show_bug.cgi?id=118315
+ ASSERT(index < m_rareData->m_callReturnIndexVector.size());
+ if (index >= m_rareData->m_callReturnIndexVector.size())
+ return 1;
+ return m_rareData->m_callReturnIndexVector[index].bytecodeOffset;
+ }
- void unlinkCalls();
+ void unlinkCalls();
- bool hasIncomingCalls() { return m_incomingCalls.begin() != m_incomingCalls.end(); }
+ bool hasIncomingCalls() { return m_incomingCalls.begin() != m_incomingCalls.end(); }
- void linkIncomingCall(CallLinkInfo* incoming)
- {
- m_incomingCalls.push(incoming);
- }
+ void linkIncomingCall(CallLinkInfo* incoming)
+ {
+ m_incomingCalls.push(incoming);
+ }
- bool isIncomingCallAlreadyLinked(CallLinkInfo* incoming)
- {
- return m_incomingCalls.isOnList(incoming);
- }
+ bool isIncomingCallAlreadyLinked(CallLinkInfo* incoming)
+ {
+ return m_incomingCalls.isOnList(incoming);
+ }
#endif // ENABLE(JIT)
#if ENABLE(LLINT)
- void linkIncomingCall(LLIntCallLinkInfo* incoming)
- {
- m_incomingLLIntCalls.push(incoming);
- }
+ void linkIncomingCall(LLIntCallLinkInfo* incoming)
+ {
+ m_incomingLLIntCalls.push(incoming);
+ }
#endif // ENABLE(LLINT)
- void unlinkIncomingCalls();
+ void unlinkIncomingCalls();
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
- void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
- {
- m_jitCodeMap = jitCodeMap;
- }
- CompactJITCodeMap* jitCodeMap()
- {
- return m_jitCodeMap.get();
- }
+ void setJITCodeMap(PassOwnPtr<CompactJITCodeMap> jitCodeMap)
+ {
+ m_jitCodeMap = jitCodeMap;
+ }
+ CompactJITCodeMap* jitCodeMap()
+ {
+ return m_jitCodeMap.get();
+ }
#endif
#if ENABLE(DFG_JIT)
- void createDFGDataIfNecessary()
- {
- if (!!m_dfgData)
- return;
+ void createDFGDataIfNecessary()
+ {
+ if (!!m_dfgData)
+ return;
- m_dfgData = adoptPtr(new DFGData);
- }
+ m_dfgData = adoptPtr(new DFGData);
+ }
- DFG::OSREntryData* appendDFGOSREntryData(unsigned bytecodeIndex, unsigned machineCodeOffset)
- {
- createDFGDataIfNecessary();
- DFG::OSREntryData entry;
- entry.m_bytecodeIndex = bytecodeIndex;
- entry.m_machineCodeOffset = machineCodeOffset;
- m_dfgData->osrEntry.append(entry);
- return &m_dfgData->osrEntry.last();
- }
- unsigned numberOfDFGOSREntries() const
- {
- if (!m_dfgData)
- return 0;
- return m_dfgData->osrEntry.size();
- }
- DFG::OSREntryData* dfgOSREntryData(unsigned i) { return &m_dfgData->osrEntry[i]; }
- DFG::OSREntryData* dfgOSREntryDataForBytecodeIndex(unsigned bytecodeIndex)
- {
- if (!m_dfgData)
- return 0;
- if (m_dfgData->osrEntry.isEmpty())
- return 0;
- DFG::OSREntryData* result = binarySearch<
- DFG::OSREntryData, unsigned, DFG::getOSREntryDataBytecodeIndex>(
- m_dfgData->osrEntry.begin(), m_dfgData->osrEntry.size(),
- bytecodeIndex, WTF::KeyMustNotBePresentInArray);
- if (result->m_bytecodeIndex != bytecodeIndex)
- return 0;
- return result;
- }
+ void saveCompilation(PassRefPtr<Profiler::Compilation> compilation)
+ {
+ createDFGDataIfNecessary();
+ m_dfgData->compilation = compilation;
+ }
- unsigned appendOSRExit(const DFG::OSRExit& osrExit)
- {
- createDFGDataIfNecessary();
- unsigned result = m_dfgData->osrExit.size();
- m_dfgData->osrExit.append(osrExit);
- return result;
- }
+ Profiler::Compilation* compilation()
+ {
+ if (!m_dfgData)
+ return 0;
+ return m_dfgData->compilation.get();
+ }
- DFG::OSRExit& lastOSRExit()
- {
- return m_dfgData->osrExit.last();
- }
+ DFG::OSREntryData* appendDFGOSREntryData(unsigned bytecodeIndex, unsigned machineCodeOffset)
+ {
+ createDFGDataIfNecessary();
+ DFG::OSREntryData entry;
+ entry.m_bytecodeIndex = bytecodeIndex;
+ entry.m_machineCodeOffset = machineCodeOffset;
+ m_dfgData->osrEntry.append(entry);
+ return &m_dfgData->osrEntry.last();
+ }
+ unsigned numberOfDFGOSREntries() const
+ {
+ if (!m_dfgData)
+ return 0;
+ return m_dfgData->osrEntry.size();
+ }
+ DFG::OSREntryData* dfgOSREntryData(unsigned i) { return &m_dfgData->osrEntry[i]; }
+ DFG::OSREntryData* dfgOSREntryDataForBytecodeIndex(unsigned bytecodeIndex)
+ {
+ if (!m_dfgData)
+ return 0;
+ return tryBinarySearch<DFG::OSREntryData, unsigned>(
+ m_dfgData->osrEntry, m_dfgData->osrEntry.size(), bytecodeIndex,
+ DFG::getOSREntryDataBytecodeIndex);
+ }
- unsigned appendSpeculationRecovery(const DFG::SpeculationRecovery& recovery)
- {
- createDFGDataIfNecessary();
- unsigned result = m_dfgData->speculationRecovery.size();
- m_dfgData->speculationRecovery.append(recovery);
- return result;
- }
+ unsigned appendOSRExit(const DFG::OSRExit& osrExit)
+ {
+ createDFGDataIfNecessary();
+ unsigned result = m_dfgData->osrExit.size();
+ m_dfgData->osrExit.append(osrExit);
+ return result;
+ }
- unsigned appendWatchpoint(const JumpReplacementWatchpoint& watchpoint)
- {
- createDFGDataIfNecessary();
- unsigned result = m_dfgData->watchpoints.size();
- m_dfgData->watchpoints.append(watchpoint);
- return result;
- }
+ DFG::OSRExit& lastOSRExit()
+ {
+ return m_dfgData->osrExit.last();
+ }
- unsigned numberOfOSRExits()
- {
- if (!m_dfgData)
- return 0;
- return m_dfgData->osrExit.size();
- }
+ unsigned appendSpeculationRecovery(const DFG::SpeculationRecovery& recovery)
+ {
+ createDFGDataIfNecessary();
+ unsigned result = m_dfgData->speculationRecovery.size();
+ m_dfgData->speculationRecovery.append(recovery);
+ return result;
+ }
- unsigned numberOfSpeculationRecoveries()
- {
- if (!m_dfgData)
- return 0;
- return m_dfgData->speculationRecovery.size();
- }
+ unsigned appendWatchpoint(const JumpReplacementWatchpoint& watchpoint)
+ {
+ createDFGDataIfNecessary();
+ unsigned result = m_dfgData->watchpoints.size();
+ m_dfgData->watchpoints.append(watchpoint);
+ return result;
+ }
- unsigned numberOfWatchpoints()
- {
- if (!m_dfgData)
- return 0;
- return m_dfgData->watchpoints.size();
- }
+ unsigned numberOfOSRExits()
+ {
+ if (!m_dfgData)
+ return 0;
+ return m_dfgData->osrExit.size();
+ }
- DFG::OSRExit& osrExit(unsigned index)
- {
- return m_dfgData->osrExit[index];
- }
+ unsigned numberOfSpeculationRecoveries()
+ {
+ if (!m_dfgData)
+ return 0;
+ return m_dfgData->speculationRecovery.size();
+ }
- DFG::SpeculationRecovery& speculationRecovery(unsigned index)
- {
- return m_dfgData->speculationRecovery[index];
- }
+ unsigned numberOfWatchpoints()
+ {
+ if (!m_dfgData)
+ return 0;
+ return m_dfgData->watchpoints.size();
+ }
- JumpReplacementWatchpoint& watchpoint(unsigned index)
- {
- return m_dfgData->watchpoints[index];
- }
+ DFG::OSRExit& osrExit(unsigned index)
+ {
+ return m_dfgData->osrExit[index];
+ }
- void appendWeakReference(JSCell* target)
- {
- createDFGDataIfNecessary();
- m_dfgData->weakReferences.append(WriteBarrier<JSCell>(*globalData(), ownerExecutable(), target));
- }
+ DFG::SpeculationRecovery& speculationRecovery(unsigned index)
+ {
+ return m_dfgData->speculationRecovery[index];
+ }
- void appendWeakReferenceTransition(JSCell* codeOrigin, JSCell* from, JSCell* to)
- {
- createDFGDataIfNecessary();
- m_dfgData->transitions.append(
- WeakReferenceTransition(*globalData(), ownerExecutable(), codeOrigin, from, to));
- }
+ JumpReplacementWatchpoint& watchpoint(unsigned index)
+ {
+ return m_dfgData->watchpoints[index];
+ }
- DFG::MinifiedGraph& minifiedDFG()
- {
- createDFGDataIfNecessary();
- return m_dfgData->minifiedDFG;
- }
+ void appendWeakReference(JSCell* target)
+ {
+ createDFGDataIfNecessary();
+ m_dfgData->weakReferences.append(WriteBarrier<JSCell>(*vm(), ownerExecutable(), target));
+ }
- DFG::VariableEventStream& variableEventStream()
- {
- createDFGDataIfNecessary();
- return m_dfgData->variableEventStream;
- }
+ void appendWeakReferenceTransition(JSCell* codeOrigin, JSCell* from, JSCell* to)
+ {
+ createDFGDataIfNecessary();
+ m_dfgData->transitions.append(
+ WeakReferenceTransition(*vm(), ownerExecutable(), codeOrigin, from, to));
+ }
+
+ DFG::MinifiedGraph& minifiedDFG()
+ {
+ createDFGDataIfNecessary();
+ return m_dfgData->minifiedDFG;
+ }
+
+ DFG::VariableEventStream& variableEventStream()
+ {
+ createDFGDataIfNecessary();
+ return m_dfgData->variableEventStream;
+ }
#endif
- unsigned bytecodeOffset(Instruction* returnAddress)
- {
- ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end());
- return static_cast<Instruction*>(returnAddress) - instructions().begin();
- }
+ unsigned bytecodeOffset(Instruction* returnAddress)
+ {
+ RELEASE_ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end());
+ return static_cast<Instruction*>(returnAddress) - instructions().begin();
+ }
- bool isNumericCompareFunction() { return m_unlinkedCode->isNumericCompareFunction(); }
+ bool isNumericCompareFunction() { return m_unlinkedCode->isNumericCompareFunction(); }
- unsigned numberOfInstructions() const { return m_instructions.size(); }
- RefCountedArray<Instruction>& instructions() { return m_instructions; }
- const RefCountedArray<Instruction>& instructions() const { return m_instructions; }
+ unsigned numberOfInstructions() const { return m_instructions.size(); }
+ RefCountedArray<Instruction>& instructions() { return m_instructions; }
+ const RefCountedArray<Instruction>& instructions() const { return m_instructions; }
-#if ENABLE(BYTECODE_COMMENTS)
- Vector<Comment>& bytecodeComments() { return m_bytecodeComments; }
-#endif
-
- size_t predictedMachineCodeSize();
+ size_t predictedMachineCodeSize();
- bool usesOpcode(OpcodeID);
+ bool usesOpcode(OpcodeID);
- unsigned instructionCount() { return m_instructions.size(); }
+ unsigned instructionCount() { return m_instructions.size(); }
- int argumentIndexAfterCapture(size_t argument);
+ int argumentIndexAfterCapture(size_t argument);
#if ENABLE(JIT)
- void setJITCode(const JITCode& code, MacroAssemblerCodePtr codeWithArityCheck)
- {
- m_jitCode = code;
- m_jitCodeWithArityCheck = codeWithArityCheck;
+ void setJITCode(const JITCode& code, MacroAssemblerCodePtr codeWithArityCheck)
+ {
+ m_jitCode = code;
+ m_jitCodeWithArityCheck = codeWithArityCheck;
#if ENABLE(DFG_JIT)
- if (m_jitCode.jitType() == JITCode::DFGJIT) {
- createDFGDataIfNecessary();
- m_globalData->heap.m_dfgCodeBlocks.m_set.add(this);
- }
+ if (m_jitCode.jitType() == JITCode::DFGJIT) {
+ createDFGDataIfNecessary();
+ m_vm->heap.m_dfgCodeBlocks.m_set.add(this);
+ }
#endif
+ }
+ JITCode& getJITCode() { return m_jitCode; }
+ MacroAssemblerCodePtr getJITCodeWithArityCheck() { return m_jitCodeWithArityCheck; }
+ JITCode::JITType getJITType() const { return m_jitCode.jitType(); }
+ ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex) = 0;
+ void jettison();
+ enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully };
+ JITCompilationResult jitCompile(ExecState* exec)
+ {
+ if (getJITType() != JITCode::InterpreterThunk) {
+ ASSERT(getJITType() == JITCode::BaselineJIT);
+ return AlreadyCompiled;
}
- JITCode& getJITCode() { return m_jitCode; }
- MacroAssemblerCodePtr getJITCodeWithArityCheck() { return m_jitCodeWithArityCheck; }
- JITCode::JITType getJITType() const { return m_jitCode.jitType(); }
- ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
- virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex) = 0;
- virtual void jettison() = 0;
- enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully };
- JITCompilationResult jitCompile(ExecState* exec)
- {
- if (getJITType() != JITCode::InterpreterThunk) {
- ASSERT(getJITType() == JITCode::BaselineJIT);
- return AlreadyCompiled;
- }
#if ENABLE(JIT)
- if (jitCompileImpl(exec))
- return CompiledSuccessfully;
- return CouldNotCompile;
+ if (jitCompileImpl(exec))
+ return CompiledSuccessfully;
+ return CouldNotCompile;
#else
- UNUSED_PARAM(exec);
- return CouldNotCompile;
+ UNUSED_PARAM(exec);
+ return CouldNotCompile;
#endif
- }
- virtual CodeBlock* replacement() = 0;
+ }
+ virtual CodeBlock* replacement() = 0;
- virtual DFG::CapabilityLevel canCompileWithDFGInternal() = 0;
- DFG::CapabilityLevel canCompileWithDFG()
- {
- DFG::CapabilityLevel result = canCompileWithDFGInternal();
- m_canCompileWithDFGState = result;
- return result;
- }
- DFG::CapabilityLevel canCompileWithDFGState() { return m_canCompileWithDFGState; }
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal() = 0;
+ DFG::CapabilityLevel canCompileWithDFG()
+ {
+ DFG::CapabilityLevel result = canCompileWithDFGInternal();
+ m_canCompileWithDFGState = result;
+ return result;
+ }
+ DFG::CapabilityLevel canCompileWithDFGState() { return m_canCompileWithDFGState; }
- bool hasOptimizedReplacement()
- {
- ASSERT(JITCode::isBaselineCode(getJITType()));
- bool result = replacement()->getJITType() > getJITType();
+ bool hasOptimizedReplacement()
+ {
+ ASSERT(JITCode::isBaselineCode(getJITType()));
+ bool result = replacement()->getJITType() > getJITType();
#if !ASSERT_DISABLED
- if (result)
- ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
- else {
- ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
- ASSERT(replacement() == this);
- }
-#endif
- return result;
+ if (result)
+ ASSERT(replacement()->getJITType() == JITCode::DFGJIT);
+ else {
+ ASSERT(JITCode::isBaselineCode(replacement()->getJITType()));
+ ASSERT(replacement() == this);
}
+#endif
+ return result;
+ }
#else
- JITCode::JITType getJITType() const { return JITCode::BaselineJIT; }
+ JITCode::JITType getJITType() const { return JITCode::BaselineJIT; }
#endif
- ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
+ ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
- void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
- JSGlobalData* globalData() { return m_globalData; }
+ void setVM(VM* vm) { m_vm = vm; }
+ VM* vm() { return m_vm; }
- void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
- int thisRegister() const { return m_thisRegister; }
+ void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
+ int thisRegister() const { return m_thisRegister; }
- bool needsFullScopeChain() const { return m_unlinkedCode->needsFullScopeChain(); }
- bool usesEval() const { return m_unlinkedCode->usesEval(); }
+ bool needsFullScopeChain() const { return m_unlinkedCode->needsFullScopeChain(); }
+ bool usesEval() const { return m_unlinkedCode->usesEval(); }
- void setArgumentsRegister(int argumentsRegister)
- {
- ASSERT(argumentsRegister != -1);
- m_argumentsRegister = argumentsRegister;
- ASSERT(usesArguments());
- }
- int argumentsRegister() const
- {
- ASSERT(usesArguments());
- return m_argumentsRegister;
- }
- int uncheckedArgumentsRegister()
- {
- if (!usesArguments())
- return InvalidVirtualRegister;
- return argumentsRegister();
- }
- void setActivationRegister(int activationRegister)
- {
- m_activationRegister = activationRegister;
- }
- int activationRegister() const
- {
- ASSERT(needsFullScopeChain());
- return m_activationRegister;
- }
- int uncheckedActivationRegister()
- {
- if (!needsFullScopeChain())
- return InvalidVirtualRegister;
- return activationRegister();
- }
- bool usesArguments() const { return m_argumentsRegister != -1; }
-
- bool needsActivation() const
- {
- return needsFullScopeChain() && codeType() != GlobalCode;
- }
+ void setArgumentsRegister(int argumentsRegister)
+ {
+ ASSERT(argumentsRegister != -1);
+ m_argumentsRegister = argumentsRegister;
+ ASSERT(usesArguments());
+ }
+ int argumentsRegister() const
+ {
+ ASSERT(usesArguments());
+ return m_argumentsRegister;
+ }
+ int uncheckedArgumentsRegister()
+ {
+ if (!usesArguments())
+ return InvalidVirtualRegister;
+ return argumentsRegister();
+ }
+ void setActivationRegister(int activationRegister)
+ {
+ m_activationRegister = activationRegister;
+ }
+ int activationRegister() const
+ {
+ ASSERT(needsFullScopeChain());
+ return m_activationRegister;
+ }
+ int uncheckedActivationRegister()
+ {
+ if (!needsFullScopeChain())
+ return InvalidVirtualRegister;
+ return activationRegister();
+ }
+ bool usesArguments() const { return m_argumentsRegister != -1; }
- bool isCaptured(int operand, InlineCallFrame* inlineCallFrame = 0) const
- {
- if (inlineCallFrame && !operandIsArgument(operand))
- return inlineCallFrame->capturedVars.get(operand);
+ bool needsActivation() const
+ {
+ return needsFullScopeChain() && codeType() != GlobalCode;
+ }
- if (operandIsArgument(operand))
- return usesArguments();
+ bool isCaptured(int operand, InlineCallFrame* inlineCallFrame = 0) const
+ {
+ if (operandIsArgument(operand))
+ return operandToArgument(operand) && usesArguments();
- // The activation object isn't in the captured region, but it's "captured"
- // in the sense that stores to its location can be observed indirectly.
- if (needsActivation() && operand == activationRegister())
- return true;
+ if (inlineCallFrame)
+ return inlineCallFrame->capturedVars.get(operand);
- // Ditto for the arguments object.
- if (usesArguments() && operand == argumentsRegister())
- return true;
+ // The activation object isn't in the captured region, but it's "captured"
+ // in the sense that stores to its location can be observed indirectly.
+ if (needsActivation() && operand == activationRegister())
+ return true;
- // Ditto for the arguments object.
- if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
- return true;
+ // Ditto for the arguments object.
+ if (usesArguments() && operand == argumentsRegister())
+ return true;
- // We're in global code so there are no locals to capture
- if (!symbolTable())
- return false;
+ // Ditto for the arguments object.
+ if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
+ return true;
- return operand >= symbolTable()->captureStart()
- && operand < symbolTable()->captureEnd();
- }
+ // We're in global code so there are no locals to capture
+ if (!symbolTable())
+ return false;
- CodeType codeType() const { return m_unlinkedCode->codeType(); }
+ return operand >= symbolTable()->captureStart()
+ && operand < symbolTable()->captureEnd();
+ }
- SourceProvider* source() const { return m_source.get(); }
- unsigned sourceOffset() const { return m_sourceOffset; }
+ CodeType codeType() const { return m_unlinkedCode->codeType(); }
- size_t numberOfJumpTargets() const { return m_unlinkedCode->numberOfJumpTargets(); }
- unsigned jumpTarget(int index) const { return m_unlinkedCode->jumpTarget(index); }
+ SourceProvider* source() const { return m_source.get(); }
+ unsigned sourceOffset() const { return m_sourceOffset; }
+ unsigned firstLineColumnOffset() const { return m_firstLineColumnOffset; }
- void createActivation(CallFrame*);
+ size_t numberOfJumpTargets() const { return m_unlinkedCode->numberOfJumpTargets(); }
+ unsigned jumpTarget(int index) const { return m_unlinkedCode->jumpTarget(index); }
- void clearEvalCache();
+ void createActivation(CallFrame*);
+
+ void clearEvalCache();
- String nameForRegister(int registerNumber);
+ String nameForRegister(int registerNumber);
#if ENABLE(JIT)
- void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
- size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
- StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
+ void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); }
+ size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
+ StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
- void setNumberOfByValInfos(size_t size) { m_byValInfos.grow(size); }
- size_t numberOfByValInfos() const { return m_byValInfos.size(); }
- ByValInfo& byValInfo(size_t index) { return m_byValInfos[index]; }
+ void setNumberOfByValInfos(size_t size) { m_byValInfos.grow(size); }
+ size_t numberOfByValInfos() const { return m_byValInfos.size(); }
+ ByValInfo& byValInfo(size_t index) { return m_byValInfos[index]; }
- void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); }
- size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
- CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
+ void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); }
+ size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
+ CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
#endif
#if ENABLE(VALUE_PROFILER)
- unsigned numberOfArgumentValueProfiles()
- {
- ASSERT(m_numParameters >= 0);
- ASSERT(m_argumentValueProfiles.size() == static_cast<unsigned>(m_numParameters));
- return m_argumentValueProfiles.size();
- }
- ValueProfile* valueProfileForArgument(unsigned argumentIndex)
- {
- ValueProfile* result = &m_argumentValueProfiles[argumentIndex];
- ASSERT(result->m_bytecodeOffset == -1);
- return result;
- }
+ unsigned numberOfArgumentValueProfiles()
+ {
+ ASSERT(m_numParameters >= 0);
+ ASSERT(m_argumentValueProfiles.size() == static_cast<unsigned>(m_numParameters));
+ return m_argumentValueProfiles.size();
+ }
+ ValueProfile* valueProfileForArgument(unsigned argumentIndex)
+ {
+ ValueProfile* result = &m_argumentValueProfiles[argumentIndex];
+ ASSERT(result->m_bytecodeOffset == -1);
+ return result;
+ }
- unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
- ValueProfile* valueProfile(int index)
- {
- ValueProfile* result = &m_valueProfiles[index];
- ASSERT(result->m_bytecodeOffset != -1);
- return result;
- }
- ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
- {
- ValueProfile* result = WTF::genericBinarySearch<ValueProfile, int, getValueProfileBytecodeOffset>(m_valueProfiles, m_valueProfiles.size(), bytecodeOffset);
- ASSERT(result->m_bytecodeOffset != -1);
- ASSERT(instructions()[bytecodeOffset + opcodeLength(
- m_globalData->interpreter->getOpcodeID(
- instructions()[
- bytecodeOffset].u.opcode)) - 1].u.profile == result);
- return result;
- }
- SpeculatedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
- {
- return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction();
- }
-
- unsigned totalNumberOfValueProfiles()
- {
- return numberOfArgumentValueProfiles() + numberOfValueProfiles();
- }
- ValueProfile* getFromAllValueProfiles(unsigned index)
- {
- if (index < numberOfArgumentValueProfiles())
- return valueProfileForArgument(index);
- return valueProfile(index - numberOfArgumentValueProfiles());
- }
+ unsigned numberOfValueProfiles() { return m_valueProfiles.size(); }
+ ValueProfile* valueProfile(int index) { return &m_valueProfiles[index]; }
+ ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset)
+ {
+ ValueProfile* result = binarySearch<ValueProfile, int>(
+ m_valueProfiles, m_valueProfiles.size(), bytecodeOffset,
+ getValueProfileBytecodeOffset<ValueProfile>);
+ ASSERT(result->m_bytecodeOffset != -1);
+ ASSERT(instructions()[bytecodeOffset + opcodeLength(
+ m_vm->interpreter->getOpcodeID(
+ instructions()[
+ bytecodeOffset].u.opcode)) - 1].u.profile == result);
+ return result;
+ }
+ SpeculatedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset)
+ {
+ return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction();
+ }
- RareCaseProfile* addRareCaseProfile(int bytecodeOffset)
- {
- m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset));
- return &m_rareCaseProfiles.last();
- }
- unsigned numberOfRareCaseProfiles() { return m_rareCaseProfiles.size(); }
- RareCaseProfile* rareCaseProfile(int index) { return &m_rareCaseProfiles[index]; }
- RareCaseProfile* rareCaseProfileForBytecodeOffset(int bytecodeOffset)
- {
- return WTF::genericBinarySearch<RareCaseProfile, int, getRareCaseProfileBytecodeOffset>(m_rareCaseProfiles, m_rareCaseProfiles.size(), bytecodeOffset);
- }
+ unsigned totalNumberOfValueProfiles()
+ {
+ return numberOfArgumentValueProfiles() + numberOfValueProfiles();
+ }
+ ValueProfile* getFromAllValueProfiles(unsigned index)
+ {
+ if (index < numberOfArgumentValueProfiles())
+ return valueProfileForArgument(index);
+ return valueProfile(index - numberOfArgumentValueProfiles());
+ }
- bool likelyToTakeSlowCase(int bytecodeOffset)
- {
- if (!numberOfRareCaseProfiles())
- return false;
- unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- return value >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
- }
+ RareCaseProfile* addRareCaseProfile(int bytecodeOffset)
+ {
+ m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset));
+ return &m_rareCaseProfiles.last();
+ }
+ unsigned numberOfRareCaseProfiles() { return m_rareCaseProfiles.size(); }
+ RareCaseProfile* rareCaseProfile(int index) { return &m_rareCaseProfiles[index]; }
+ RareCaseProfile* rareCaseProfileForBytecodeOffset(int bytecodeOffset)
+ {
+ return tryBinarySearch<RareCaseProfile, int>(
+ m_rareCaseProfiles, m_rareCaseProfiles.size(), bytecodeOffset,
+ getRareCaseProfileBytecodeOffset);
+ }
- bool couldTakeSlowCase(int bytecodeOffset)
- {
- if (!numberOfRareCaseProfiles())
- return false;
- unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- return value >= Options::couldTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold();
- }
+ bool likelyToTakeSlowCase(int bytecodeOffset)
+ {
+ if (!numberOfRareCaseProfiles())
+ return false;
+ unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ return value >= Options::likelyToTakeSlowCaseMinimumCount();
+ }
- RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset)
- {
- m_specialFastCaseProfiles.append(RareCaseProfile(bytecodeOffset));
- return &m_specialFastCaseProfiles.last();
- }
- unsigned numberOfSpecialFastCaseProfiles() { return m_specialFastCaseProfiles.size(); }
- RareCaseProfile* specialFastCaseProfile(int index) { return &m_specialFastCaseProfiles[index]; }
- RareCaseProfile* specialFastCaseProfileForBytecodeOffset(int bytecodeOffset)
- {
- return WTF::genericBinarySearch<RareCaseProfile, int, getRareCaseProfileBytecodeOffset>(m_specialFastCaseProfiles, m_specialFastCaseProfiles.size(), bytecodeOffset);
- }
+ bool couldTakeSlowCase(int bytecodeOffset)
+ {
+ if (!numberOfRareCaseProfiles())
+ return false;
+ unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ return value >= Options::couldTakeSlowCaseMinimumCount();
+ }
- bool likelyToTakeSpecialFastCase(int bytecodeOffset)
- {
- if (!numberOfRareCaseProfiles())
- return false;
- unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
- }
+ RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset)
+ {
+ m_specialFastCaseProfiles.append(RareCaseProfile(bytecodeOffset));
+ return &m_specialFastCaseProfiles.last();
+ }
+ unsigned numberOfSpecialFastCaseProfiles() { return m_specialFastCaseProfiles.size(); }
+ RareCaseProfile* specialFastCaseProfile(int index) { return &m_specialFastCaseProfiles[index]; }
+ RareCaseProfile* specialFastCaseProfileForBytecodeOffset(int bytecodeOffset)
+ {
+ return tryBinarySearch<RareCaseProfile, int>(
+ m_specialFastCaseProfiles, m_specialFastCaseProfiles.size(), bytecodeOffset,
+ getRareCaseProfileBytecodeOffset);
+ }
- bool couldTakeSpecialFastCase(int bytecodeOffset)
- {
- if (!numberOfRareCaseProfiles())
- return false;
- unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- return specialFastCaseCount >= Options::couldTakeSlowCaseMinimumCount() && static_cast<double>(specialFastCaseCount) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold();
- }
+ bool likelyToTakeSpecialFastCase(int bytecodeOffset)
+ {
+ if (!numberOfRareCaseProfiles())
+ return false;
+ unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount();
+ }
- bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
- {
- if (!numberOfRareCaseProfiles())
- return false;
- unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- unsigned value = slowCaseCount - specialFastCaseCount;
- return value >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
- }
+ bool couldTakeSpecialFastCase(int bytecodeOffset)
+ {
+ if (!numberOfRareCaseProfiles())
+ return false;
+ unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ return specialFastCaseCount >= Options::couldTakeSlowCaseMinimumCount();
+ }
- bool likelyToTakeAnySlowCase(int bytecodeOffset)
- {
- if (!numberOfRareCaseProfiles())
- return false;
- unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
- unsigned value = slowCaseCount + specialFastCaseCount;
- return value >= Options::likelyToTakeSlowCaseMinimumCount() && static_cast<double>(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold();
- }
+ bool likelyToTakeDeepestSlowCase(int bytecodeOffset)
+ {
+ if (!numberOfRareCaseProfiles())
+ return false;
+ unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ unsigned value = slowCaseCount - specialFastCaseCount;
+ return value >= Options::likelyToTakeSlowCaseMinimumCount();
+ }
- unsigned executionEntryCount() const { return m_executionEntryCount; }
-
- unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); }
- const ArrayProfileVector& arrayProfiles() { return m_arrayProfiles; }
- ArrayProfile* addArrayProfile(unsigned bytecodeOffset)
- {
- m_arrayProfiles.append(ArrayProfile(bytecodeOffset));
- return &m_arrayProfiles.last();
- }
- ArrayProfile* getArrayProfile(unsigned bytecodeOffset);
- ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset);
+ bool likelyToTakeAnySlowCase(int bytecodeOffset)
+ {
+ if (!numberOfRareCaseProfiles())
+ return false;
+ unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter;
+ unsigned value = slowCaseCount + specialFastCaseCount;
+ return value >= Options::likelyToTakeSlowCaseMinimumCount();
+ }
- unsigned numberOfArrayAllocationProfiles() const { return m_arrayAllocationProfiles.size(); }
- ArrayAllocationProfile* addArrayAllocationProfile()
- {
- m_arrayAllocationProfiles.append(ArrayAllocationProfile());
- return &m_arrayAllocationProfiles.last();
- }
+ unsigned numberOfArrayProfiles() const { return m_arrayProfiles.size(); }
+ const ArrayProfileVector& arrayProfiles() { return m_arrayProfiles; }
+ ArrayProfile* addArrayProfile(unsigned bytecodeOffset)
+ {
+ m_arrayProfiles.append(ArrayProfile(bytecodeOffset));
+ return &m_arrayProfiles.last();
+ }
+ ArrayProfile* getArrayProfile(unsigned bytecodeOffset);
+ ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset);
#endif
- // Exception handling support
-
- size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
- void allocateHandlers(const Vector<UnlinkedHandlerInfo>& unlinkedHandlers)
- {
- size_t count = unlinkedHandlers.size();
- if (!count)
- return;
- createRareDataIfNecessary();
- m_rareData->m_exceptionHandlers.resize(count);
- for (size_t i = 0; i < count; ++i) {
- m_rareData->m_exceptionHandlers[i].start = unlinkedHandlers[i].start;
- m_rareData->m_exceptionHandlers[i].end = unlinkedHandlers[i].end;
- m_rareData->m_exceptionHandlers[i].target = unlinkedHandlers[i].target;
- m_rareData->m_exceptionHandlers[i].scopeDepth = unlinkedHandlers[i].scopeDepth;
- }
+ // Exception handling support
+ size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
+ void allocateHandlers(const Vector<UnlinkedHandlerInfo>& unlinkedHandlers)
+ {
+ size_t count = unlinkedHandlers.size();
+ if (!count)
+ return;
+ createRareDataIfNecessary();
+ m_rareData->m_exceptionHandlers.resize(count);
+ for (size_t i = 0; i < count; ++i) {
+ m_rareData->m_exceptionHandlers[i].start = unlinkedHandlers[i].start;
+ m_rareData->m_exceptionHandlers[i].end = unlinkedHandlers[i].end;
+ m_rareData->m_exceptionHandlers[i].target = unlinkedHandlers[i].target;
+ m_rareData->m_exceptionHandlers[i].scopeDepth = unlinkedHandlers[i].scopeDepth;
}
- HandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
- bool hasExpressionInfo() { return m_unlinkedCode->hasExpressionInfo(); }
+ }
+ HandlerInfo& exceptionHandler(int index) { RELEASE_ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
+
+ bool hasExpressionInfo() { return m_unlinkedCode->hasExpressionInfo(); }
#if ENABLE(JIT)
- Vector<CallReturnOffsetToBytecodeOffset>& callReturnIndexVector()
- {
- createRareDataIfNecessary();
- return m_rareData->m_callReturnIndexVector;
- }
+ Vector<CallReturnOffsetToBytecodeOffset, 0, UnsafeVectorOverflow>& callReturnIndexVector()
+ {
+ createRareDataIfNecessary();
+ return m_rareData->m_callReturnIndexVector;
+ }
#endif
#if ENABLE(DFG_JIT)
- SegmentedVector<InlineCallFrame, 4>& inlineCallFrames()
- {
- createRareDataIfNecessary();
- return m_rareData->m_inlineCallFrames;
- }
+ SegmentedVector<InlineCallFrame, 4>& inlineCallFrames()
+ {
+ createRareDataIfNecessary();
+ return m_rareData->m_inlineCallFrames;
+ }
- Vector<CodeOriginAtCallReturnOffset>& codeOrigins()
- {
- createRareDataIfNecessary();
- return m_rareData->m_codeOrigins;
- }
+ Vector<CodeOriginAtCallReturnOffset, 0, UnsafeVectorOverflow>& codeOrigins()
+ {
+ createRareDataIfNecessary();
+ return m_rareData->m_codeOrigins;
+ }
- // Having code origins implies that there has been some inlining.
- bool hasCodeOrigins()
- {
- return m_rareData && !!m_rareData->m_codeOrigins.size();
- }
+ // Having code origins implies that there has been some inlining.
+ bool hasCodeOrigins()
+ {
+ return m_rareData && !!m_rareData->m_codeOrigins.size();
+ }
- bool codeOriginForReturn(ReturnAddressPtr, CodeOrigin&);
+ bool codeOriginForReturn(ReturnAddressPtr, CodeOrigin&);
- CodeOrigin codeOrigin(unsigned index)
- {
- ASSERT(m_rareData);
- return m_rareData->m_codeOrigins[index].codeOrigin;
- }
+ bool canGetCodeOrigin(unsigned index)
+ {
+ if (!m_rareData)
+ return false;
+ return m_rareData->m_codeOrigins.size() > index;
+ }
- bool addFrequentExitSite(const DFG::FrequentExitSite& site)
- {
- ASSERT(JITCode::isBaselineCode(getJITType()));
- return m_exitProfile.add(site);
- }
+ CodeOrigin codeOrigin(unsigned index)
+ {
+ RELEASE_ASSERT(m_rareData);
+ return m_rareData->m_codeOrigins[index].codeOrigin;
+ }
+
+ bool addFrequentExitSite(const DFG::FrequentExitSite& site)
+ {
+ ASSERT(JITCode::isBaselineCode(getJITType()));
+ return m_exitProfile.add(site);
+ }
+
+ bool hasExitSite(const DFG::FrequentExitSite& site) const { return m_exitProfile.hasExitSite(site); }
- DFG::ExitProfile& exitProfile() { return m_exitProfile; }
+ DFG::ExitProfile& exitProfile() { return m_exitProfile; }
- CompressedLazyOperandValueProfileHolder& lazyOperandValueProfiles()
- {
- return m_lazyOperandValueProfiles;
- }
+ CompressedLazyOperandValueProfileHolder& lazyOperandValueProfiles()
+ {
+ return m_lazyOperandValueProfiles;
+ }
#endif
- // Constant Pool
+ // Constant Pool
- size_t numberOfIdentifiers() const { return m_identifiers.size(); }
- void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
- Identifier& identifier(int index) { return m_identifiers[index]; }
+ size_t numberOfIdentifiers() const { return m_identifiers.size(); }
+ void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
+ Identifier& identifier(int index) { return m_identifiers[index]; }
- size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
- unsigned addConstant(JSValue v)
- {
- unsigned result = m_constantRegisters.size();
- m_constantRegisters.append(WriteBarrier<Unknown>());
- m_constantRegisters.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), v);
- return result;
- }
+ size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
+ unsigned addConstant(JSValue v)
+ {
+ unsigned result = m_constantRegisters.size();
+ m_constantRegisters.append(WriteBarrier<Unknown>());
+ m_constantRegisters.last().set(m_globalObject->vm(), m_ownerExecutable.get(), v);
+ return result;
+ }
- unsigned addOrFindConstant(JSValue);
- WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
- ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
- ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
+ unsigned addOrFindConstant(JSValue);
+ WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
+ ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
+ ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
- unsigned addFunctionDecl(FunctionExecutable* n)
- {
- unsigned size = m_functionDecls.size();
- m_functionDecls.append(WriteBarrier<FunctionExecutable>());
- m_functionDecls.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), n);
- return size;
- }
- FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
- int numberOfFunctionDecls() { return m_functionDecls.size(); }
- unsigned addFunctionExpr(FunctionExecutable* n)
- {
- unsigned size = m_functionExprs.size();
- m_functionExprs.append(WriteBarrier<FunctionExecutable>());
- m_functionExprs.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), n);
- return size;
- }
- FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
+ FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
+ int numberOfFunctionDecls() { return m_functionDecls.size(); }
+ FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
- RegExp* regexp(int index) const { return m_unlinkedCode->regexp(index); }
+ RegExp* regexp(int index) const { return m_unlinkedCode->regexp(index); }
- unsigned numberOfConstantBuffers() const
- {
- if (!m_rareData)
- return 0;
- return m_rareData->m_constantBuffers.size();
- }
- unsigned addConstantBuffer(const Vector<JSValue>& buffer)
- {
- createRareDataIfNecessary();
- unsigned size = m_rareData->m_constantBuffers.size();
- m_rareData->m_constantBuffers.append(buffer);
- return size;
- }
+ unsigned numberOfConstantBuffers() const
+ {
+ if (!m_rareData)
+ return 0;
+ return m_rareData->m_constantBuffers.size();
+ }
+ unsigned addConstantBuffer(const Vector<JSValue>& buffer)
+ {
+ createRareDataIfNecessary();
+ unsigned size = m_rareData->m_constantBuffers.size();
+ m_rareData->m_constantBuffers.append(buffer);
+ return size;
+ }
- Vector<JSValue>& constantBufferAsVector(unsigned index)
- {
- ASSERT(m_rareData);
- return m_rareData->m_constantBuffers[index];
- }
- JSValue* constantBuffer(unsigned index)
- {
- return constantBufferAsVector(index).data();
- }
+ Vector<JSValue>& constantBufferAsVector(unsigned index)
+ {
+ ASSERT(m_rareData);
+ return m_rareData->m_constantBuffers[index];
+ }
+ JSValue* constantBuffer(unsigned index)
+ {
+ return constantBufferAsVector(index).data();
+ }
- JSGlobalObject* globalObject() { return m_globalObject.get(); }
+ JSGlobalObject* globalObject() { return m_globalObject.get(); }
- JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin)
- {
- if (!codeOrigin.inlineCallFrame)
- return globalObject();
- // FIXME: if we ever inline based on executable not function, this code will need to change.
- return codeOrigin.inlineCallFrame->callee->scope()->globalObject();
- }
+ JSGlobalObject* globalObjectFor(CodeOrigin);
- // Jump Tables
+ // Jump Tables
- size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
- SimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
- SimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
+ size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
+ SimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
+ SimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
- size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
- SimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
- SimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
+ size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
+ SimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
+ SimpleJumpTable& characterSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
- size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
- StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
- StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
+ size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
+ StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
+ StringJumpTable& stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
- SharedSymbolTable* symbolTable() const { return m_unlinkedCode->symbolTable(); }
+ SharedSymbolTable* symbolTable() const { return m_unlinkedCode->symbolTable(); }
- EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
+ EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
- enum ShrinkMode {
- // Shrink prior to generating machine code that may point directly into vectors.
- EarlyShrink,
+ enum ShrinkMode {
+ // Shrink prior to generating machine code that may point directly into vectors.
+ EarlyShrink,
- // Shrink after generating machine code, and after possibly creating new vectors
- // and appending to others. At this time it is not safe to shrink certain vectors
- // because we would have generated machine code that references them directly.
- LateShrink
- };
- void shrinkToFit(ShrinkMode);
-
- void copyPostParseDataFrom(CodeBlock* alternative);
- void copyPostParseDataFromAlternative();
-
- // Functions for controlling when JITting kicks in, in a mixed mode
- // execution world.
-
- bool checkIfJITThresholdReached()
- {
- return m_llintExecuteCounter.checkIfThresholdCrossedAndSet(this);
- }
-
- void dontJITAnytimeSoon()
- {
- m_llintExecuteCounter.deferIndefinitely();
- }
-
- void jitAfterWarmUp()
- {
- m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp(), this);
- }
+ // Shrink after generating machine code, and after possibly creating new vectors
+ // and appending to others. At this time it is not safe to shrink certain vectors
+ // because we would have generated machine code that references them directly.
+ LateShrink
+ };
+ void shrinkToFit(ShrinkMode);
- void jitSoon()
- {
- m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon(), this);
- }
+ void copyPostParseDataFrom(CodeBlock* alternative);
+ void copyPostParseDataFromAlternative();
- const ExecutionCounter& llintExecuteCounter() const
- {
- return m_llintExecuteCounter;
- }
+ // Functions for controlling when JITting kicks in, in a mixed mode
+ // execution world.
- // Functions for controlling when tiered compilation kicks in. This
- // controls both when the optimizing compiler is invoked and when OSR
- // entry happens. Two triggers exist: the loop trigger and the return
- // trigger. In either case, when an addition to m_jitExecuteCounter
- // causes it to become non-negative, the optimizing compiler is
- // invoked. This includes a fast check to see if this CodeBlock has
- // already been optimized (i.e. replacement() returns a CodeBlock
- // that was optimized with a higher tier JIT than this one). In the
- // case of the loop trigger, if the optimized compilation succeeds
- // (or has already succeeded in the past) then OSR is attempted to
- // redirect program flow into the optimized code.
-
- // These functions are called from within the optimization triggers,
- // and are used as a single point at which we define the heuristics
- // for how much warm-up is mandated before the next optimization
- // trigger files. All CodeBlocks start out with optimizeAfterWarmUp(),
- // as this is called from the CodeBlock constructor.
-
- // When we observe a lot of speculation failures, we trigger a
- // reoptimization. But each time, we increase the optimization trigger
- // to avoid thrashing.
- unsigned reoptimizationRetryCounter() const
- {
- ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
- return m_reoptimizationRetryCounter;
- }
+ bool checkIfJITThresholdReached()
+ {
+ return m_llintExecuteCounter.checkIfThresholdCrossedAndSet(this);
+ }
- void countReoptimization()
- {
- m_reoptimizationRetryCounter++;
- if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
- m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
- }
+ void dontJITAnytimeSoon()
+ {
+ m_llintExecuteCounter.deferIndefinitely();
+ }
- int32_t counterValueForOptimizeAfterWarmUp()
- {
- return Options::thresholdForOptimizeAfterWarmUp() << reoptimizationRetryCounter();
- }
+ void jitAfterWarmUp()
+ {
+ m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp(), this);
+ }
- int32_t counterValueForOptimizeAfterLongWarmUp()
- {
- return Options::thresholdForOptimizeAfterLongWarmUp() << reoptimizationRetryCounter();
- }
+ void jitSoon()
+ {
+ m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon(), this);
+ }
- int32_t* addressOfJITExecuteCounter()
- {
- return &m_jitExecuteCounter.m_counter;
- }
+ const ExecutionCounter& llintExecuteCounter() const
+ {
+ return m_llintExecuteCounter;
+ }
- 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); }
+ // Functions for controlling when tiered compilation kicks in. This
+ // controls both when the optimizing compiler is invoked and when OSR
+ // entry happens. Two triggers exist: the loop trigger and the return
+ // trigger. In either case, when an addition to m_jitExecuteCounter
+ // causes it to become non-negative, the optimizing compiler is
+ // invoked. This includes a fast check to see if this CodeBlock has
+ // already been optimized (i.e. replacement() returns a CodeBlock
+ // that was optimized with a higher tier JIT than this one). In the
+ // case of the loop trigger, if the optimized compilation succeeds
+ // (or has already succeeded in the past) then OSR is attempted to
+ // redirect program flow into the optimized code.
+
+ // These functions are called from within the optimization triggers,
+ // and are used as a single point at which we define the heuristics
+ // for how much warm-up is mandated before the next optimization
+ // trigger files. All CodeBlocks start out with optimizeAfterWarmUp(),
+ // as this is called from the CodeBlock constructor.
+
+ // When we observe a lot of speculation failures, we trigger a
+ // reoptimization. But each time, we increase the optimization trigger
+ // to avoid thrashing.
+ unsigned reoptimizationRetryCounter() const;
+ void countReoptimization();
+
+ unsigned numberOfDFGCompiles();
- const ExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; }
+ int32_t codeTypeThresholdMultiplier() const;
- unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; }
+ int32_t counterValueForOptimizeAfterWarmUp();
+ int32_t counterValueForOptimizeAfterLongWarmUp();
+ int32_t counterValueForOptimizeSoon();
- // 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.setNewThreshold(0, this);
- }
-
- // Call this to prevent optimization from happening again. Note that
- // optimization will still happen after roughly 2^29 invocations,
- // so this is really meant to delay that as much as possible. This
- // is called if optimization failed, and we expect it to fail in
- // the future as well.
- void dontOptimizeAnytimeSoon()
- {
- m_jitExecuteCounter.deferIndefinitely();
- }
-
- // Call this to reinitialize the counter to its starting state,
- // forcing a warm-up to happen before the next optimization trigger
- // fires. This is called in the CodeBlock constructor. It also
- // makes sense to call this if an OSR exit occurred. Note that
- // OSR exit code is code generated, so the value of the execute
- // counter that this corresponds to is also available directly.
- void optimizeAfterWarmUp()
- {
- 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.setNewThreshold(counterValueForOptimizeAfterLongWarmUp(), this);
- }
-
- // Call this to cause an optimization trigger to fire soon, but
- // not necessarily the next one. This makes sense if optimization
- // succeeds. Successfuly optimization means that all calls are
- // relinked to the optimized code, so this only affects call
- // frames that are still executing this CodeBlock. The value here
- // is tuned to strike a balance between the cost of OSR entry
- // (which is too high to warrant making every loop back edge to
- // trigger OSR immediately) and the cost of executing baseline
- // code (which is high enough that we don't necessarily want to
- // have a full warm-up). The intuition for calling this instead of
- // optimizeNextInvocation() is for the case of recursive functions
- // with loops. Consider that there may be N call frames of some
- // recursive function, for a reasonably large value of N. The top
- // one triggers optimization, and then returns, and then all of
- // the others return. We don't want optimization to be triggered on
- // each return, as that would be superfluous. It only makes sense
- // to trigger optimization if one of those functions becomes hot
- // in the baseline code.
- void optimizeSoon()
- {
- m_jitExecuteCounter.setNewThreshold(Options::thresholdForOptimizeSoon() << reoptimizationRetryCounter(), this);
- }
-
- uint32_t osrExitCounter() const { return m_osrExitCounter; }
-
- void countOSRExit() { m_osrExitCounter++; }
-
- uint32_t* addressOfOSRExitCounter() { return &m_osrExitCounter; }
+ int32_t* addressOfJITExecuteCounter()
+ {
+ return &m_jitExecuteCounter.m_counter;
+ }
- static ptrdiff_t offsetOfOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_osrExitCounter); }
+ 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); }
+
+ const ExecutionCounter& jitExecuteCounter() const { return m_jitExecuteCounter; }
+
+ 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();
+
+ // 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();
+
+ // Call this to prevent optimization from happening again. Note that
+ // optimization will still happen after roughly 2^29 invocations,
+ // so this is really meant to delay that as much as possible. This
+ // is called if optimization failed, and we expect it to fail in
+ // the future as well.
+ void dontOptimizeAnytimeSoon();
+
+ // Call this to reinitialize the counter to its starting state,
+ // forcing a warm-up to happen before the next optimization trigger
+ // fires. This is called in the CodeBlock constructor. It also
+ // makes sense to call this if an OSR exit occurred. Note that
+ // OSR exit code is code generated, so the value of the execute
+ // counter that this corresponds to is also available directly.
+ void optimizeAfterWarmUp();
+
+ // Call this to force an optimization trigger to fire only after
+ // a lot of warm-up.
+ void optimizeAfterLongWarmUp();
+
+ // Call this to cause an optimization trigger to fire soon, but
+ // not necessarily the next one. This makes sense if optimization
+ // succeeds. Successfuly optimization means that all calls are
+ // relinked to the optimized code, so this only affects call
+ // frames that are still executing this CodeBlock. The value here
+ // is tuned to strike a balance between the cost of OSR entry
+ // (which is too high to warrant making every loop back edge to
+ // trigger OSR immediately) and the cost of executing baseline
+ // code (which is high enough that we don't necessarily want to
+ // have a full warm-up). The intuition for calling this instead of
+ // optimizeNextInvocation() is for the case of recursive functions
+ // with loops. Consider that there may be N call frames of some
+ // recursive function, for a reasonably large value of N. The top
+ // one triggers optimization, and then returns, and then all of
+ // the others return. We don't want optimization to be triggered on
+ // each return, as that would be superfluous. It only makes sense
+ // to trigger optimization if one of those functions becomes hot
+ // in the baseline code.
+ void optimizeSoon();
+
+ uint32_t osrExitCounter() const { return m_osrExitCounter; }
+
+ void countOSRExit() { m_osrExitCounter++; }
+
+ uint32_t* addressOfOSRExitCounter() { return &m_osrExitCounter; }
+
+ static ptrdiff_t offsetOfOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_osrExitCounter); }
#if ENABLE(JIT)
- uint32_t adjustedExitCountThreshold(uint32_t desiredThreshold)
- {
- ASSERT(getJITType() == JITCode::DFGJIT);
- // Compute this the lame way so we don't saturate. This is called infrequently
- // enough that this loop won't hurt us.
- unsigned result = desiredThreshold;
- for (unsigned n = baselineVersion()->reoptimizationRetryCounter(); n--;) {
- unsigned newResult = result << 1;
- if (newResult < result)
- return std::numeric_limits<uint32_t>::max();
- result = newResult;
- }
- return result;
- }
-
- uint32_t exitCountThresholdForReoptimization()
- {
- return adjustedExitCountThreshold(Options::osrExitCountForReoptimization());
- }
-
- uint32_t exitCountThresholdForReoptimizationFromLoop()
- {
- return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop());
- }
-
- bool shouldReoptimizeNow()
- {
- return osrExitCounter() >= exitCountThresholdForReoptimization();
- }
-
- bool shouldReoptimizeFromLoopNow()
- {
- return osrExitCounter() >= exitCountThresholdForReoptimizationFromLoop();
- }
+ uint32_t adjustedExitCountThreshold(uint32_t desiredThreshold);
+ uint32_t exitCountThresholdForReoptimization();
+ uint32_t exitCountThresholdForReoptimizationFromLoop();
+ bool shouldReoptimizeNow();
+ bool shouldReoptimizeFromLoopNow();
#endif
#if ENABLE(VALUE_PROFILER)
- bool shouldOptimizeNow();
- void updateAllValueProfilePredictions(OperationInProgress = NoOperation);
- void updateAllArrayPredictions(OperationInProgress = NoOperation);
- void updateAllPredictions(OperationInProgress = NoOperation);
+ bool shouldOptimizeNow();
+ void updateAllValueProfilePredictions(OperationInProgress = NoOperation);
+ void updateAllArrayPredictions(OperationInProgress = NoOperation);
+ void updateAllPredictions(OperationInProgress = NoOperation);
#else
- bool shouldOptimizeNow() { return false; }
- void updateAllValueProfilePredictions(OperationInProgress = NoOperation) { }
- void updateAllArrayPredictions(OperationInProgress = NoOperation) { }
- void updateAllPredictions(OperationInProgress = NoOperation) { }
+ bool shouldOptimizeNow() { return false; }
+ void updateAllValueProfilePredictions(OperationInProgress = NoOperation) { }
+ void updateAllArrayPredictions(OperationInProgress = NoOperation) { }
+ void updateAllPredictions(OperationInProgress = NoOperation) { }
#endif
#if ENABLE(JIT)
- void reoptimize();
+ void reoptimize();
#endif
#if ENABLE(VERBOSE_VALUE_PROFILE)
- void dumpValueProfiles();
+ void dumpValueProfiles();
#endif
- // FIXME: Make these remaining members private.
+ // FIXME: Make these remaining members private.
- int m_numCalleeRegisters;
- int m_numVars;
- bool m_isConstructor;
+ int m_numCalleeRegisters;
+ int m_numVars;
+ bool m_isConstructor;
- protected:
+protected:
#if ENABLE(JIT)
- virtual bool jitCompileImpl(ExecState*) = 0;
+ virtual bool jitCompileImpl(ExecState*) = 0;
+ virtual void jettisonImpl() = 0;
#endif
- virtual void visitWeakReferences(SlotVisitor&);
- virtual void finalizeUnconditionally();
+ virtual void visitWeakReferences(SlotVisitor&);
+ virtual void finalizeUnconditionally();
- UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
+#if ENABLE(DFG_JIT)
+ void tallyFrequentExitSites();
+#else
+ void tallyFrequentExitSites() { }
+#endif
- private:
- friend class DFGCodeBlocks;
+private:
+ friend class DFGCodeBlocks;
+
+ double optimizationThresholdScalingFactor();
#if ENABLE(JIT)
- ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
+ ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
#endif
-#if ENABLE(DFG_JIT)
- void tallyFrequentExitSites();
-#else
- void tallyFrequentExitSites() { }
-#endif
#if ENABLE(VALUE_PROFILER)
- void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
+ void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
#endif
- void setIdentifiers(const Vector<Identifier>& identifiers)
- {
- ASSERT(m_identifiers.isEmpty());
- m_identifiers.appendVector(identifiers);
- }
+ void setIdentifiers(const Vector<Identifier>& identifiers)
+ {
+ RELEASE_ASSERT(m_identifiers.isEmpty());
+ m_identifiers.appendVector(identifiers);
+ }
- void setConstantRegisters(const Vector<WriteBarrier<Unknown> >& constants)
- {
- size_t count = constants.size();
- m_constantRegisters.resize(count);
- for (size_t i = 0; i < count; i++)
- m_constantRegisters[i].set(*m_globalData, ownerExecutable(), constants[i].get());
- }
+ void setConstantRegisters(const Vector<WriteBarrier<Unknown> >& constants)
+ {
+ size_t count = constants.size();
+ m_constantRegisters.resize(count);
+ for (size_t i = 0; i < count; i++)
+ m_constantRegisters[i].set(*m_vm, ownerExecutable(), constants[i].get());
+ }
- void dumpBytecode(ExecState*, const Instruction* begin, const Instruction*&);
+ void dumpBytecode(PrintStream&, ExecState*, const Instruction* begin, const Instruction*&);
+
+ CString registerName(ExecState*, int r) const;
+ void printUnaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
+ void printBinaryOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
+ void printConditionalJump(PrintStream&, ExecState*, const Instruction*, const Instruction*&, int location, const char* op);
+ void printGetByIdOp(PrintStream&, ExecState*, int location, const Instruction*&);
+ void printGetByIdCacheStatus(PrintStream&, ExecState*, int location);
+ enum CacheDumpMode { DumpCaches, DontDumpCaches };
+ void printCallOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode);
+ void printPutByIdOp(PrintStream&, ExecState*, int location, const Instruction*&, const char* op);
+ void beginDumpProfiling(PrintStream&, bool& hasPrintedProfiling);
+ void dumpValueProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
+ void dumpArrayProfiling(PrintStream&, const Instruction*&, bool& hasPrintedProfiling);
+#if ENABLE(VALUE_PROFILER)
+ void dumpRareCaseProfile(PrintStream&, const char* name, RareCaseProfile*, bool& hasPrintedProfiling);
+#endif
- CString registerName(ExecState*, int r) const;
- void printUnaryOp(ExecState*, int location, const Instruction*&, const char* op);
- void printBinaryOp(ExecState*, int location, const Instruction*&, const char* op);
- void printConditionalJump(ExecState*, const Instruction*, const Instruction*&, int location, const char* op);
- void printGetByIdOp(ExecState*, int location, const Instruction*&);
- void printGetByIdCacheStatus(ExecState*, int location);
- enum CacheDumpMode { DumpCaches, DontDumpCaches };
- void printCallOp(ExecState*, int location, const Instruction*&, const char* op, CacheDumpMode);
- void printPutByIdOp(ExecState*, int location, const Instruction*&, const char* op);
- void visitStructures(SlotVisitor&, Instruction* vPC);
+ void visitStructures(SlotVisitor&, Instruction* vPC);
#if ENABLE(DFG_JIT)
- bool shouldImmediatelyAssumeLivenessDuringScan()
- {
- // Null m_dfgData means that this is a baseline JIT CodeBlock. Baseline JIT
- // CodeBlocks don't need to be jettisoned when their weak references go
- // stale. So if a basline JIT CodeBlock gets scanned, we can assume that
- // this means that it's live.
- if (!m_dfgData)
- return true;
+ bool shouldImmediatelyAssumeLivenessDuringScan()
+ {
+ // Null m_dfgData means that this is a baseline JIT CodeBlock. Baseline JIT
+ // CodeBlocks don't need to be jettisoned when their weak references go
+ // stale. So if a basline JIT CodeBlock gets scanned, we can assume that
+ // this means that it's live.
+ if (!m_dfgData)
+ return true;
- // For simplicity, we don't attempt to jettison code blocks during GC if
- // they are executing. Instead we strongly mark their weak references to
- // allow them to continue to execute soundly.
- if (m_dfgData->mayBeExecuting)
- return true;
+ // For simplicity, we don't attempt to jettison code blocks during GC if
+ // they are executing. Instead we strongly mark their weak references to
+ // allow them to continue to execute soundly.
+ if (m_dfgData->mayBeExecuting)
+ return true;
- if (Options::forceDFGCodeBlockLiveness())
- return true;
+ if (Options::forceDFGCodeBlockLiveness())
+ return true;
- return false;
- }
+ return false;
+ }
#else
- bool shouldImmediatelyAssumeLivenessDuringScan() { return true; }
+ bool shouldImmediatelyAssumeLivenessDuringScan() { return true; }
#endif
- void performTracingFixpointIteration(SlotVisitor&);
+ void performTracingFixpointIteration(SlotVisitor&);
- void stronglyVisitStrongReferences(SlotVisitor&);
- void stronglyVisitWeakReferences(SlotVisitor&);
+ void stronglyVisitStrongReferences(SlotVisitor&);
+ void stronglyVisitWeakReferences(SlotVisitor&);
- void createRareDataIfNecessary()
- {
- if (!m_rareData)
- m_rareData = adoptPtr(new RareData);
- }
+ void createRareDataIfNecessary()
+ {
+ if (!m_rareData)
+ m_rareData = adoptPtr(new RareData);
+ }
#if ENABLE(JIT)
- void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
+ void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
+ void resetStubDuringGCInternal(RepatchBuffer&, StructureStubInfo&);
#endif
- WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
- int m_numParameters;
- WriteBarrier<ScriptExecutable> m_ownerExecutable;
- JSGlobalData* m_globalData;
+ WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
+ int m_numParameters;
+ WriteBarrier<ScriptExecutable> m_ownerExecutable;
+ VM* m_vm;
- RefCountedArray<Instruction> m_instructions;
- int m_thisRegister;
- int m_argumentsRegister;
- int m_activationRegister;
+ RefCountedArray<Instruction> m_instructions;
+ int m_thisRegister;
+ int m_argumentsRegister;
+ int m_activationRegister;
- bool m_isStrictMode;
+ bool m_isStrictMode;
+ bool m_needsActivation;
- RefPtr<SourceProvider> m_source;
- unsigned m_sourceOffset;
+ RefPtr<SourceProvider> m_source;
+ unsigned m_sourceOffset;
+ unsigned m_firstLineColumnOffset;
+ unsigned m_codeType;
#if ENABLE(LLINT)
- SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
- SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
+ SegmentedVector<LLIntCallLinkInfo, 8> m_llintCallLinkInfos;
+ SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo> > m_incomingLLIntCalls;
#endif
#if ENABLE(JIT)
- Vector<StructureStubInfo> m_structureStubInfos;
- Vector<ByValInfo> m_byValInfos;
- Vector<CallLinkInfo> m_callLinkInfos;
- JITCode m_jitCode;
- MacroAssemblerCodePtr m_jitCodeWithArityCheck;
- SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
+ Vector<StructureStubInfo> m_structureStubInfos;
+ Vector<ByValInfo> m_byValInfos;
+ Vector<CallLinkInfo> m_callLinkInfos;
+ JITCode m_jitCode;
+ MacroAssemblerCodePtr m_jitCodeWithArityCheck;
+ SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo> > m_incomingCalls;
#endif
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
- OwnPtr<CompactJITCodeMap> m_jitCodeMap;
+ OwnPtr<CompactJITCodeMap> m_jitCodeMap;
#endif
#if ENABLE(DFG_JIT)
- struct WeakReferenceTransition {
- WeakReferenceTransition() { }
+ struct WeakReferenceTransition {
+ WeakReferenceTransition() { }
- WeakReferenceTransition(JSGlobalData& globalData, JSCell* owner, JSCell* codeOrigin, JSCell* from, JSCell* to)
- : m_from(globalData, owner, from)
- , m_to(globalData, owner, to)
- {
- if (!!codeOrigin)
- m_codeOrigin.set(globalData, owner, codeOrigin);
- }
-
- WriteBarrier<JSCell> m_codeOrigin;
- WriteBarrier<JSCell> m_from;
- WriteBarrier<JSCell> m_to;
- };
-
- struct DFGData {
- DFGData()
- : mayBeExecuting(false)
- , isJettisoned(false)
- {
- }
+ WeakReferenceTransition(VM& vm, JSCell* owner, JSCell* codeOrigin, JSCell* from, JSCell* to)
+ : m_from(vm, owner, from)
+ , m_to(vm, owner, to)
+ {
+ if (!!codeOrigin)
+ m_codeOrigin.set(vm, owner, codeOrigin);
+ }
+
+ WriteBarrier<JSCell> m_codeOrigin;
+ WriteBarrier<JSCell> m_from;
+ WriteBarrier<JSCell> m_to;
+ };
+
+ struct DFGData {
+ DFGData()
+ : mayBeExecuting(false)
+ , isJettisoned(false)
+ {
+ }
- Vector<DFG::OSREntryData> osrEntry;
- SegmentedVector<DFG::OSRExit, 8> osrExit;
- Vector<DFG::SpeculationRecovery> speculationRecovery;
- SegmentedVector<JumpReplacementWatchpoint, 1, 0> watchpoints;
- Vector<WeakReferenceTransition> transitions;
- Vector<WriteBarrier<JSCell> > weakReferences;
- DFG::VariableEventStream variableEventStream;
- DFG::MinifiedGraph minifiedDFG;
- bool mayBeExecuting;
- 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;
-
- // This is relevant to non-DFG code blocks that serve as the profiled code block
- // for DFG code blocks.
- DFG::ExitProfile m_exitProfile;
- CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles;
+ Vector<DFG::OSREntryData> osrEntry;
+ SegmentedVector<DFG::OSRExit, 8> osrExit;
+ Vector<DFG::SpeculationRecovery> speculationRecovery;
+ SegmentedVector<JumpReplacementWatchpoint, 1, 0> watchpoints;
+ Vector<WeakReferenceTransition> transitions;
+ Vector<WriteBarrier<JSCell> > weakReferences;
+ DFG::VariableEventStream variableEventStream;
+ DFG::MinifiedGraph minifiedDFG;
+ RefPtr<Profiler::Compilation> compilation;
+ bool mayBeExecuting;
+ 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;
+
+ // This is relevant to non-DFG code blocks that serve as the profiled code block
+ // for DFG code blocks.
+ DFG::ExitProfile m_exitProfile;
+ CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles;
#endif
#if ENABLE(VALUE_PROFILER)
- Vector<ValueProfile> m_argumentValueProfiles;
- SegmentedVector<ValueProfile, 8> m_valueProfiles;
- SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
- SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
- SegmentedVector<ArrayAllocationProfile, 8> m_arrayAllocationProfiles;
- ArrayProfileVector m_arrayProfiles;
- unsigned m_executionEntryCount;
+ Vector<ValueProfile> m_argumentValueProfiles;
+ SegmentedVector<ValueProfile, 8> m_valueProfiles;
+ SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
+ SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles;
+ SegmentedVector<ArrayAllocationProfile, 8> m_arrayAllocationProfiles;
+ ArrayProfileVector m_arrayProfiles;
#endif
+ SegmentedVector<ObjectAllocationProfile, 8> m_objectAllocationProfiles;
- // Constant Pool
- Vector<Identifier> m_identifiers;
- COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
- // TODO: This could just be a pointer to m_unlinkedCodeBlock's data, but the DFG mutates
- // it, so we're stuck with it for now.
- Vector<WriteBarrier<Unknown> > m_constantRegisters;
- Vector<WriteBarrier<FunctionExecutable> > m_functionDecls;
- Vector<WriteBarrier<FunctionExecutable> > m_functionExprs;
+ // Constant Pool
+ Vector<Identifier> m_identifiers;
+ COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
+ // TODO: This could just be a pointer to m_unlinkedCodeBlock's data, but the DFG mutates
+ // it, so we're stuck with it for now.
+ Vector<WriteBarrier<Unknown> > m_constantRegisters;
+ Vector<WriteBarrier<FunctionExecutable> > m_functionDecls;
+ Vector<WriteBarrier<FunctionExecutable> > m_functionExprs;
- OwnPtr<CodeBlock> m_alternative;
+ OwnPtr<CodeBlock> m_alternative;
- ExecutionCounter m_llintExecuteCounter;
+ ExecutionCounter m_llintExecuteCounter;
- ExecutionCounter m_jitExecuteCounter;
- int32_t m_totalJITExecutions;
- uint32_t m_osrExitCounter;
- uint16_t m_optimizationDelayCounter;
- uint16_t m_reoptimizationRetryCounter;
+ ExecutionCounter m_jitExecuteCounter;
+ int32_t m_totalJITExecutions;
+ uint32_t m_osrExitCounter;
+ uint16_t m_optimizationDelayCounter;
+ uint16_t m_reoptimizationRetryCounter;
- Vector<ResolveOperations> m_resolveOperations;
- Vector<PutToBaseOperation, 1> m_putToBaseOperations;
+ Vector<ResolveOperations> m_resolveOperations;
+ Vector<PutToBaseOperation, 1> m_putToBaseOperations;
- struct RareData {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- Vector<HandlerInfo> m_exceptionHandlers;
+ struct RareData {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
+ Vector<HandlerInfo> m_exceptionHandlers;
- // Buffers used for large array literals
- Vector<Vector<JSValue> > m_constantBuffers;
+ // Buffers used for large array literals
+ Vector<Vector<JSValue> > m_constantBuffers;
- // Jump Tables
- Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
- Vector<SimpleJumpTable> m_characterSwitchJumpTables;
- Vector<StringJumpTable> m_stringSwitchJumpTables;
+ // Jump Tables
+ Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
+ Vector<SimpleJumpTable> m_characterSwitchJumpTables;
+ Vector<StringJumpTable> m_stringSwitchJumpTables;
- EvalCodeCache m_evalCodeCache;
+ EvalCodeCache m_evalCodeCache;
#if ENABLE(JIT)
- Vector<CallReturnOffsetToBytecodeOffset> m_callReturnIndexVector;
+ Vector<CallReturnOffsetToBytecodeOffset, 0, UnsafeVectorOverflow> m_callReturnIndexVector;
#endif
#if ENABLE(DFG_JIT)
- SegmentedVector<InlineCallFrame, 4> m_inlineCallFrames;
- Vector<CodeOriginAtCallReturnOffset> m_codeOrigins;
+ SegmentedVector<InlineCallFrame, 4> m_inlineCallFrames;
+ Vector<CodeOriginAtCallReturnOffset, 0, UnsafeVectorOverflow> m_codeOrigins;
#endif
- };
+ };
#if COMPILER(MSVC)
- friend void WTF::deleteOwnedPtr<RareData>(RareData*);
+ friend void WTF::deleteOwnedPtr<RareData>(RareData*);
#endif
- OwnPtr<RareData> m_rareData;
+ OwnPtr<RareData> m_rareData;
#if ENABLE(JIT)
- DFG::CapabilityLevel m_canCompileWithDFGState;
+ DFG::CapabilityLevel m_canCompileWithDFGState;
#endif
- };
+};
- // Program code is not marked by any function, so we make the global object
- // responsible for marking it.
+// Program code is not marked by any function, so we make the global object
+// responsible for marking it.
- class GlobalCodeBlock : public CodeBlock {
- protected:
- GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
- : CodeBlock(CopyParsedBlock, other)
- {
- }
-
- GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
- : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, sourceOffset, alternative)
- {
- }
- };
-
- class ProgramCodeBlock : public GlobalCodeBlock {
- public:
- ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
- : GlobalCodeBlock(CopyParsedBlock, other)
- {
- }
-
- ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, PassOwnPtr<CodeBlock> alternative)
- : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, 0, alternative)
- {
- }
-
-#if ENABLE(JIT)
- protected:
- virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
- virtual void jettison();
- virtual bool jitCompileImpl(ExecState*);
- virtual CodeBlock* replacement();
- virtual DFG::CapabilityLevel canCompileWithDFGInternal();
-#endif
- };
-
- class EvalCodeBlock : public GlobalCodeBlock {
- public:
- EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
- : GlobalCodeBlock(CopyParsedBlock, other)
- {
- }
-
- EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative)
- : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, 0, alternative)
- {
- }
-
- const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
- unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
+class GlobalCodeBlock : public CodeBlock {
+protected:
+ GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
+ : CodeBlock(CopyParsedBlock, other)
+ {
+ }
-#if ENABLE(JIT)
- protected:
- virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
- virtual void jettison();
- virtual bool jitCompileImpl(ExecState*);
- virtual CodeBlock* replacement();
- virtual DFG::CapabilityLevel canCompileWithDFGInternal();
-#endif
+ GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset, PassOwnPtr<CodeBlock> alternative)
+ : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, sourceOffset, firstLineColumnOffset, alternative)
+ {
+ }
+};
- private:
- UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
- };
+class ProgramCodeBlock : public GlobalCodeBlock {
+public:
+ ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
+ : GlobalCodeBlock(CopyParsedBlock, other)
+ {
+ }
- class FunctionCodeBlock : public CodeBlock {
- public:
- FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
- : CodeBlock(CopyParsedBlock, other)
- {
- }
+ ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset, PassOwnPtr<CodeBlock> alternative)
+ : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, 0, firstLineColumnOffset, alternative)
+ {
+ }
- FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative = nullptr)
- : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, sourceOffset, alternative)
- {
- }
-
#if ENABLE(JIT)
- protected:
- virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
- virtual void jettison();
- virtual bool jitCompileImpl(ExecState*);
- virtual CodeBlock* replacement();
- virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+protected:
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
+ virtual void jettisonImpl();
+ virtual bool jitCompileImpl(ExecState*);
+ virtual CodeBlock* replacement();
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal();
#endif
- };
+};
- inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
+class EvalCodeBlock : public GlobalCodeBlock {
+public:
+ EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
+ : GlobalCodeBlock(CopyParsedBlock, other)
{
- ASSERT(inlineCallFrame);
- ExecutableBase* executable = inlineCallFrame->executable.get();
- ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info);
- return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
}
-
- inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
+
+ EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative)
+ : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, baseScopeDepth, sourceProvider, 0, 1, alternative)
{
- if (codeOrigin.inlineCallFrame)
- return baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame);
- return baselineCodeBlock;
}
-
- inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
- {
- if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
- return CallFrame::argumentOffset(argument);
- const SlowArgument* slowArguments = symbolTable()->slowArguments();
- if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
- return CallFrame::argumentOffset(argument);
+ const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
+ unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
+
+#if ENABLE(JIT)
+protected:
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
+ virtual void jettisonImpl();
+ virtual bool jitCompileImpl(ExecState*);
+ virtual CodeBlock* replacement();
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+#endif
- ASSERT(slowArguments[argument].status == SlowArgument::Captured);
- return slowArguments[argument].index;
- }
+private:
+ UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
+};
- inline Register& ExecState::r(int index)
+class FunctionCodeBlock : public CodeBlock {
+public:
+ FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
+ : CodeBlock(CopyParsedBlock, other)
{
- CodeBlock* codeBlock = this->codeBlock();
- if (codeBlock->isConstantRegisterIndex(index))
- return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
- return this[index];
}
- inline Register& ExecState::uncheckedR(int index)
+ FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset, PassOwnPtr<CodeBlock> alternative = nullptr)
+ : CodeBlock(ownerExecutable, unlinkedCodeBlock, globalObject, 0, sourceProvider, sourceOffset, firstLineColumnOffset, alternative)
{
- ASSERT(index < FirstConstantRegisterIndex);
- return this[index];
}
+
+#if ENABLE(JIT)
+protected:
+ virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
+ virtual void jettisonImpl();
+ virtual bool jitCompileImpl(ExecState*);
+ virtual CodeBlock* replacement();
+ virtual DFG::CapabilityLevel canCompileWithDFGInternal();
+#endif
+};
+
+inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
+{
+ RELEASE_ASSERT(inlineCallFrame);
+ ExecutableBase* executable = inlineCallFrame->executable.get();
+ RELEASE_ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info);
+ return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
+}
+
+inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
+{
+ if (codeOrigin.inlineCallFrame)
+ return baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame);
+ return baselineCodeBlock;
+}
+
+inline int CodeBlock::argumentIndexAfterCapture(size_t argument)
+{
+ if (argument >= static_cast<size_t>(symbolTable()->parameterCount()))
+ return CallFrame::argumentOffset(argument);
+
+ const SlowArgument* slowArguments = symbolTable()->slowArguments();
+ if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
+ return CallFrame::argumentOffset(argument);
+
+ ASSERT(slowArguments[argument].status == SlowArgument::Captured);
+ return slowArguments[argument].index;
+}
+
+inline Register& ExecState::r(int index)
+{
+ CodeBlock* codeBlock = this->codeBlock();
+ if (codeBlock->isConstantRegisterIndex(index))
+ return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
+ return this[index];
+}
+
+inline Register& ExecState::uncheckedR(int index)
+{
+ RELEASE_ASSERT(index < FirstConstantRegisterIndex);
+ return this[index];
+}
#if ENABLE(DFG_JIT)
- inline bool ExecState::isInlineCallFrame()
- {
- if (LIKELY(!codeBlock() || codeBlock()->getJITType() != JITCode::DFGJIT))
- return false;
- return isInlineCallFrameSlow();
- }
+inline bool ExecState::isInlineCallFrame()
+{
+ if (LIKELY(!codeBlock() || codeBlock()->getJITType() != JITCode::DFGJIT))
+ return false;
+ return isInlineCallFrameSlow();
+}
#endif
- inline JSValue ExecState::argumentAfterCapture(size_t argument)
- {
- if (argument >= argumentCount())
- return jsUndefined();
+inline JSValue ExecState::argumentAfterCapture(size_t argument)
+{
+ if (argument >= argumentCount())
+ return jsUndefined();
- if (!codeBlock())
- return this[argumentOffset(argument)].jsValue();
+ if (!codeBlock())
+ return this[argumentOffset(argument)].jsValue();
- return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
- }
+ return this[codeBlock()->argumentIndexAfterCapture(argument)].jsValue();
+}
#if ENABLE(DFG_JIT)
- inline void DFGCodeBlocks::mark(void* candidateCodeBlock)
- {
- // We have to check for 0 and -1 because those are used by the HashMap as markers.
- uintptr_t value = reinterpret_cast<uintptr_t>(candidateCodeBlock);
-
- // This checks for both of those nasty cases in one go.
- // 0 + 1 = 1
- // -1 + 1 = 0
- if (value + 1 <= 1)
- return;
-
- HashSet<CodeBlock*>::iterator iter = m_set.find(static_cast<CodeBlock*>(candidateCodeBlock));
- if (iter == m_set.end())
- return;
-
- (*iter)->m_dfgData->mayBeExecuting = true;
- }
+inline void DFGCodeBlocks::mark(void* candidateCodeBlock)
+{
+ // We have to check for 0 and -1 because those are used by the HashMap as markers.
+ uintptr_t value = reinterpret_cast<uintptr_t>(candidateCodeBlock);
+
+ // This checks for both of those nasty cases in one go.
+ // 0 + 1 = 1
+ // -1 + 1 = 0
+ if (value + 1 <= 1)
+ return;
+
+ HashSet<CodeBlock*>::iterator iter = m_set.find(static_cast<CodeBlock*>(candidateCodeBlock));
+ if (iter == m_set.end())
+ return;
+
+ (*iter)->m_dfgData->mayBeExecuting = true;
+}
#endif
- inline JSValue Structure::prototypeForLookup(CodeBlock* codeBlock) const
- {
- return prototypeForLookup(codeBlock->globalObject());
- }
-
} // namespace JSC
#endif // CodeBlock_h
diff --git a/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp b/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp
index 79fe9ccb5..7c890cc88 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlockHash.cpp
@@ -36,8 +36,7 @@ namespace JSC {
CodeBlockHash::CodeBlockHash(const char* string)
: m_hash(0)
{
- if (strlen(string) != 6)
- CRASH();
+ RELEASE_ASSERT(strlen(string) == 6);
for (unsigned i = 0; i < 6; ++i) {
m_hash *= 62;
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.cpp b/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
index 92e2b0fc9..52bc2bf7f 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,10 @@
#include "config.h"
#include "CodeOrigin.h"
+#include "CallFrame.h"
+#include "CodeBlock.h"
#include "Executable.h"
+#include "Operations.h"
namespace JSC {
@@ -50,13 +53,66 @@ Vector<CodeOrigin> CodeOrigin::inlineStack() const
unsigned index = result.size() - 2;
for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame)
result[index--] = current->caller;
+ RELEASE_ASSERT(!result[0].inlineCallFrame);
return result;
}
+void CodeOrigin::dump(PrintStream& out) const
+{
+ Vector<CodeOrigin> stack = inlineStack();
+ for (unsigned i = 0; i < stack.size(); ++i) {
+ if (i)
+ out.print(" --> ");
+
+ if (InlineCallFrame* frame = stack[i].inlineCallFrame) {
+ out.print(frame->briefFunctionInformation(), ":<", RawPointer(frame->executable.get()), "> ");
+ if (frame->isClosureCall())
+ out.print("(closure) ");
+ }
+
+ out.print("bc#", stack[i].bytecodeIndex);
+ }
+}
+
+JSFunction* InlineCallFrame::calleeForCallFrame(ExecState* exec) const
+{
+ if (!isClosureCall())
+ return callee.get();
+
+ return jsCast<JSFunction*>((exec + stackOffset)->callee());
+}
+
CodeBlockHash InlineCallFrame::hash() const
{
return executable->hashFor(specializationKind());
}
+String InlineCallFrame::inferredName() const
+{
+ return jsCast<FunctionExecutable*>(executable.get())->inferredName().string();
+}
+
+CodeBlock* InlineCallFrame::baselineCodeBlock() const
+{
+ return jsCast<FunctionExecutable*>(executable.get())->baselineCodeBlockFor(specializationKind());
+}
+
+void InlineCallFrame::dumpBriefFunctionInformation(PrintStream& out) const
+{
+ out.print(inferredName(), "#", hash());
+}
+
+void InlineCallFrame::dump(PrintStream& out) const
+{
+ out.print(briefFunctionInformation(), ":<", RawPointer(executable.get()), ", bc#", caller.bytecodeIndex, ", ", specializationKind());
+ if (callee)
+ out.print(", known callee: ", JSValue(callee.get()));
+ else
+ out.print(", closure call");
+ out.print(", numArgs+this = ", arguments.size());
+ out.print(", stack >= r", stackOffset);
+ out.print(">");
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.h b/Source/JavaScriptCore/bytecode/CodeOrigin.h
index d8fbf7328..5d9eaa041 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.h
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,12 +31,14 @@
#include "ValueRecovery.h"
#include "WriteBarrier.h"
#include <wtf/BitVector.h>
+#include <wtf/PrintStream.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
namespace JSC {
struct InlineCallFrame;
+class ExecState;
class ExecutableBase;
class JSFunction;
@@ -63,8 +65,8 @@ struct CodeOrigin {
, valueProfileOffset(valueProfileOffset)
, inlineCallFrame(inlineCallFrame)
{
- ASSERT(bytecodeIndex <= maximumBytecodeIndex);
- ASSERT(valueProfileOffset < (1u << 3));
+ RELEASE_ASSERT(bytecodeIndex <= maximumBytecodeIndex);
+ RELEASE_ASSERT(valueProfileOffset < (1u << 3));
}
bool isSet() const { return bytecodeIndex != maximumBytecodeIndex; }
@@ -82,6 +84,8 @@ struct CodeOrigin {
// would have owned the code if it had not been inlined. Otherwise returns 0.
ExecutableBase* codeOriginOwner() const;
+ unsigned stackOffset() const;
+
static unsigned inlineDepthForCallFrame(InlineCallFrame*);
bool operator==(const CodeOrigin& other) const;
@@ -90,12 +94,14 @@ struct CodeOrigin {
// Get the inline stack. This is slow, and is intended for debugging only.
Vector<CodeOrigin> inlineStack() const;
+
+ void dump(PrintStream&) const;
};
struct InlineCallFrame {
Vector<ValueRecovery> arguments;
WriteBarrier<ExecutableBase> executable;
- WriteBarrier<JSFunction> callee;
+ WriteBarrier<JSFunction> callee; // This may be null, indicating that this is a closure call and that the JSFunction and JSScope are already on the stack.
CodeOrigin caller;
BitVector capturedVars; // Indexed by the machine call frame's variable numbering.
unsigned stackOffset : 31;
@@ -103,7 +109,20 @@ struct InlineCallFrame {
CodeSpecializationKind specializationKind() const { return specializationFromIsCall(isCall); }
+ bool isClosureCall() const { return !callee; }
+
+ // Get the callee given a machine call frame to which this InlineCallFrame belongs.
+ JSFunction* calleeForCallFrame(ExecState*) const;
+
+ String inferredName() const;
CodeBlockHash hash() const;
+
+ CodeBlock* baselineCodeBlock() const;
+
+ void dumpBriefFunctionInformation(PrintStream&) const;
+ void dump(PrintStream&) const;
+
+ MAKE_PRINT_METHOD(InlineCallFrame, dumpBriefFunctionInformation, briefFunctionInformation);
};
struct CodeOriginAtCallReturnOffset {
@@ -111,6 +130,14 @@ struct CodeOriginAtCallReturnOffset {
unsigned callReturnOffset;
};
+inline unsigned CodeOrigin::stackOffset() const
+{
+ if (!inlineCallFrame)
+ return 0;
+
+ return inlineCallFrame->stackOffset;
+}
+
inline bool CodeOrigin::operator==(const CodeOrigin& other) const
{
return bytecodeIndex == other.bytecodeIndex
diff --git a/Source/JavaScriptCore/bytecode/Comment.h b/Source/JavaScriptCore/bytecode/Comment.h
deleted file mode 100644
index c28f3a068..000000000
--- a/Source/JavaScriptCore/bytecode/Comment.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Comment_h
-#define Comment_h
-
-namespace JSC {
-
-struct Comment {
- size_t pc;
- const char* string;
-};
-
-} // namespace JSC
-
-#endif // Comment_h
diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp b/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp
index 69fdc3737..d36878fc9 100644
--- a/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.cpp
@@ -55,6 +55,33 @@ bool ExitProfile::add(const FrequentExitSite& site)
return true;
}
+Vector<FrequentExitSite> ExitProfile::exitSitesFor(unsigned bytecodeIndex)
+{
+ Vector<FrequentExitSite> result;
+
+ if (!m_frequentExitSites)
+ return result;
+
+ for (unsigned i = 0; i < m_frequentExitSites->size(); ++i) {
+ if (m_frequentExitSites->at(i).bytecodeOffset() == bytecodeIndex)
+ result.append(m_frequentExitSites->at(i));
+ }
+
+ return result;
+}
+
+bool ExitProfile::hasExitSite(const FrequentExitSite& site) const
+{
+ if (!m_frequentExitSites)
+ return false;
+
+ for (unsigned i = m_frequentExitSites->size(); i--;) {
+ if (m_frequentExitSites->at(i) == site)
+ return true;
+ }
+ return false;
+}
+
QueryableExitProfile::QueryableExitProfile(const ExitProfile& profile)
{
if (!profile.m_frequentExitSites)
diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
index 7132adfd4..fe7b2f921 100644
--- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h
+++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.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
@@ -26,73 +26,13 @@
#ifndef DFGExitProfile_h
#define DFGExitProfile_h
+#include "ExitKind.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
-enum ExitKind {
- ExitKindUnset,
- BadType, // We exited because a type prediction was wrong.
- BadCache, // We exited because an inline cache was wrong.
- BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
- BadIndexingType, // We exited because an indexing type was wrong.
- Overflow, // We exited because of overflow.
- NegativeZero, // We exited because we encountered negative zero.
- OutOfBounds, // We had an out-of-bounds access to an array.
- InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
- ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
- Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
- UncountableWatchpoint // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
-};
-
-inline const char* exitKindToString(ExitKind kind)
-{
- switch (kind) {
- case ExitKindUnset:
- return "Unset";
- case BadType:
- return "BadType";
- case BadCache:
- return "BadCache";
- case BadWeakConstantCache:
- return "BadWeakConstantCache";
- case BadIndexingType:
- return "BadIndexingType";
- case Overflow:
- return "Overflow";
- case NegativeZero:
- return "NegativeZero";
- case OutOfBounds:
- return "OutOfBounds";
- case InadequateCoverage:
- return "InadequateCoverage";
- case ArgumentsEscaped:
- return "ArgumentsEscaped";
- case Uncountable:
- return "Uncountable";
- case UncountableWatchpoint:
- return "UncountableWatchpoint";
- default:
- return "Unknown";
- }
-}
-
-inline bool exitKindIsCountable(ExitKind kind)
-{
- switch (kind) {
- case ExitKindUnset:
- ASSERT_NOT_REACHED();
- case BadType:
- case Uncountable:
- case UncountableWatchpoint:
- return false;
- default:
- return true;
- }
-}
-
class FrequentExitSite {
public:
FrequentExitSite()
@@ -189,6 +129,24 @@ public:
// anyway.
bool add(const FrequentExitSite&);
+ // Get the frequent exit sites for a bytecode index. This is O(n), and is
+ // meant to only be used from debugging/profiling code.
+ Vector<FrequentExitSite> exitSitesFor(unsigned bytecodeIndex);
+
+ // This is O(n) and should be called on less-frequently executed code paths
+ // in the compiler. It should be strictly cheaper than building a
+ // QueryableExitProfile, if you really expect this to be called infrequently
+ // and you believe that there are few exit sites.
+ bool hasExitSite(const FrequentExitSite&) const;
+ bool hasExitSite(ExitKind kind) const
+ {
+ return hasExitSite(FrequentExitSite(kind));
+ }
+ bool hasExitSite(unsigned bytecodeIndex, ExitKind kind) const
+ {
+ return hasExitSite(FrequentExitSite(bytecodeIndex, kind));
+ }
+
private:
friend class QueryableExitProfile;
diff --git a/Source/JavaScriptCore/bytecode/DataFormat.h b/Source/JavaScriptCore/bytecode/DataFormat.h
index 51c8afbf6..da8dacf49 100644
--- a/Source/JavaScriptCore/bytecode/DataFormat.h
+++ b/Source/JavaScriptCore/bytecode/DataFormat.h
@@ -82,7 +82,12 @@ inline const char* dataFormatToString(DataFormat dataFormat)
return "JSCell";
case DataFormatJSBoolean:
return "JSBoolean";
+ case DataFormatDead:
+ return "Dead";
+ case DataFormatArguments:
+ return "Arguments";
default:
+ RELEASE_ASSERT_NOT_REACHED();
return "Unknown";
}
}
@@ -115,14 +120,14 @@ inline bool needDataFormatConversion(DataFormat from, DataFormat to)
return false;
default:
// This captures DataFormatBoolean, which is currently unused.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
case DataFormatStorage:
ASSERT(to == DataFormatStorage);
return false;
default:
// This captures DataFormatBoolean, which is currently unused.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
return true;
}
@@ -149,7 +154,7 @@ inline bool needDataFormatConversion(DataFormat from, DataFormat to)
ASSERT(to == DataFormatStorage);
return false;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
return true;
}
diff --git a/Source/JavaScriptCore/bytecode/EvalCodeCache.h b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
index 29b17dd82..5d04637f4 100644
--- a/Source/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -31,8 +31,6 @@
#include "Executable.h"
#include "JSGlobalObject.h"
-#include "Nodes.h"
-#include "Parser.h"
#include "SourceCode.h"
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
@@ -40,6 +38,7 @@
namespace JSC {
+ class CodeCache;
class SlotVisitor;
class EvalCodeCache {
@@ -51,25 +50,25 @@ namespace JSC {
return 0;
}
- EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope, JSValue& exceptionValue)
+ EvalExecutable* getSlow(ExecState* exec, CodeCache* codeCache, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope, JSValue& exceptionValue)
{
- EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
+ EvalExecutable* evalExecutable = EvalExecutable::create(exec, codeCache, makeSource(evalSource), inStrictContext);
exceptionValue = evalExecutable->compile(exec, scope);
if (exceptionValue)
return 0;
if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && scope->begin()->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
- m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable));
+ m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->vm(), owner, evalExecutable));
return evalExecutable;
}
- EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope, JSValue& exceptionValue)
+ EvalExecutable* get(ExecState* exec, CodeCache* codeCache, ScriptExecutable* owner, bool inStrictContext, const String& evalSource, JSScope* scope, JSValue& exceptionValue)
{
EvalExecutable* evalExecutable = tryGet(inStrictContext, evalSource, scope);
if (!evalExecutable)
- evalExecutable = getSlow(exec, owner, inStrictContext, evalSource, scope, exceptionValue);
+ evalExecutable = getSlow(exec, codeCache, owner, inStrictContext, evalSource, scope, exceptionValue);
return evalExecutable;
}
diff --git a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
index e619a0376..dca9c5126 100644
--- a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
+++ b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
@@ -113,7 +113,8 @@ bool ExecutionCounter::hasCrossedThreshold(CodeBlock* codeBlock) const
double modifiedThreshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock);
return static_cast<double>(m_totalCount) + m_counter >=
- modifiedThreshold - static_cast<double>(m_activeThreshold) / 2;
+ modifiedThreshold - static_cast<double>(
+ std::min(m_activeThreshold, Options::maximumExecutionCountsBetweenCheckpoints())) / 2;
}
bool ExecutionCounter::setThreshold(CodeBlock* codeBlock)
diff --git a/Source/JavaScriptCore/bytecode/ExitKind.cpp b/Source/JavaScriptCore/bytecode/ExitKind.cpp
new file mode 100644
index 000000000..a8d904585
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ExitKind.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ExitKind.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+const char* exitKindToString(ExitKind kind)
+{
+ switch (kind) {
+ case ExitKindUnset:
+ return "Unset";
+ case BadType:
+ return "BadType";
+ case BadFunction:
+ return "BadFunction";
+ case BadExecutable:
+ return "BadExecutable";
+ case BadCache:
+ return "BadCache";
+ case BadWeakConstantCache:
+ return "BadWeakConstantCache";
+ case BadIndexingType:
+ return "BadIndexingType";
+ case Overflow:
+ return "Overflow";
+ case NegativeZero:
+ return "NegativeZero";
+ case StoreToHole:
+ return "StoreToHole";
+ case LoadFromHole:
+ return "LoadFromHole";
+ case OutOfBounds:
+ return "OutOfBounds";
+ case StoreToHoleOrOutOfBounds:
+ return "StoreToHoleOrOutOfBounds";
+ case InadequateCoverage:
+ return "InadequateCoverage";
+ case ArgumentsEscaped:
+ return "ArgumentsEscaped";
+ case NotStringObject:
+ return "NotStringObject";
+ case Uncountable:
+ return "Uncountable";
+ case UncountableWatchpoint:
+ return "UncountableWatchpoint";
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return "Unknown";
+ }
+}
+
+bool exitKindIsCountable(ExitKind kind)
+{
+ switch (kind) {
+ case ExitKindUnset:
+ RELEASE_ASSERT_NOT_REACHED();
+ case BadType:
+ case Uncountable:
+ case UncountableWatchpoint:
+ case LoadFromHole: // Already counted directly by the baseline JIT.
+ case StoreToHole: // Already counted directly by the baseline JIT.
+ case OutOfBounds: // Already counted directly by the baseline JIT.
+ case StoreToHoleOrOutOfBounds: // Already counted directly by the baseline JIT.
+ return false;
+ default:
+ return true;
+ }
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::ExitKind kind)
+{
+ out.print(exitKindToString(kind));
+}
+
+} // namespace WTF
+
diff --git a/Source/JavaScriptCore/bytecode/ExitKind.h b/Source/JavaScriptCore/bytecode/ExitKind.h
new file mode 100644
index 000000000..af918ace3
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ExitKind.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ExitKind_h
+#define ExitKind_h
+
+namespace JSC {
+
+enum ExitKind {
+ ExitKindUnset,
+ BadType, // We exited because a type prediction was wrong.
+ BadFunction, // We exited because we made an incorrect assumption about what function we would see.
+ BadExecutable, // We exited because we made an incorrect assumption about what executable we would see.
+ BadCache, // We exited because an inline cache was wrong.
+ BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
+ BadIndexingType, // We exited because an indexing type was wrong.
+ Overflow, // We exited because of overflow.
+ NegativeZero, // We exited because we encountered negative zero.
+ StoreToHole, // We had a store to a hole.
+ LoadFromHole, // We had a load from a hole.
+ OutOfBounds, // We had an out-of-bounds access to an array.
+ StoreToHoleOrOutOfBounds, // We're simultaneously speculating that we're in bounds and not accessing a hole, and one of those things didn't pan out.
+ InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
+ ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
+ NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
+ Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
+ UncountableWatchpoint, // We exited because of a watchpoint, which isn't counted because watchpoints do tracking themselves.
+ WatchdogTimerFired // We exited because we need to service the watchdog timer.
+};
+
+const char* exitKindToString(ExitKind);
+bool exitKindIsCountable(ExitKind);
+
+} // namespace JSC
+
+namespace WTF {
+
+class PrintStream;
+void printInternal(PrintStream&, JSC::ExitKind);
+
+} // namespace WTF
+
+#endif // ExitKind_h
+
diff --git a/Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h b/Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h
index f4949a686..855738aec 100644
--- a/Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h
+++ b/Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,14 +31,79 @@
namespace JSC {
struct ExpressionRangeInfo {
+ // Line and column values are encoded in 1 of 3 modes depending on the size
+ // of their values. These modes are:
+ //
+ // 1. FatLine: 22-bit line, 8-bit column.
+ // 2. FatColumn: 8-bit line, 22-bit column.
+ // 3. FatLineAndColumn: 32-bit line, 32-bit column.
+ //
+ // For the first 2 modes, the line and column will be encoded in the 30-bit
+ // position field in the ExpressionRangeInfo. For the FatLineAndColumn mode,
+ // the position field will hold an index into a FatPosition vector which
+ // holds the FatPosition records with the full 32-bit line and column values.
+
+ enum {
+ FatLineMode,
+ FatColumnMode,
+ FatLineAndColumnMode
+ };
+
+ struct FatPosition {
+ uint32_t line;
+ uint32_t column;
+ };
+
+ enum {
+ FatLineModeLineShift = 8,
+ FatLineModeLineMask = (1 << 22) - 1,
+ FatLineModeColumnMask = (1 << 8) - 1,
+ FatColumnModeLineShift = 22,
+ FatColumnModeLineMask = (1 << 8) - 1,
+ FatColumnModeColumnMask = (1 << 22) - 1
+ };
+
enum {
MaxOffset = (1 << 7) - 1,
- MaxDivot = (1 << 25) - 1
+ MaxDivot = (1 << 25) - 1,
+ MaxFatLineModeLine = (1 << 22) - 1,
+ MaxFatLineModeColumn = (1 << 8) - 1,
+ MaxFatColumnModeLine = (1 << 8) - 1,
+ MaxFatColumnModeColumn = (1 << 22) - 1
};
+
+ void encodeFatLineMode(unsigned line, unsigned column)
+ {
+ ASSERT(line <= MaxFatLineModeLine);
+ ASSERT(column <= MaxFatLineModeColumn);
+ position = ((line & FatLineModeLineMask) << FatLineModeLineShift | (column & FatLineModeColumnMask));
+ }
+
+ void encodeFatColumnMode(unsigned line, unsigned column)
+ {
+ ASSERT(line <= MaxFatColumnModeLine);
+ ASSERT(column <= MaxFatColumnModeColumn);
+ position = ((line & FatColumnModeLineMask) << FatColumnModeLineShift | (column & FatColumnModeColumnMask));
+ }
+
+ void decodeFatLineMode(unsigned& line, unsigned& column)
+ {
+ line = (position >> FatLineModeLineShift) & FatLineModeLineMask;
+ column = position & FatLineModeColumnMask;
+ }
+
+ void decodeFatColumnMode(unsigned& line, unsigned& column)
+ {
+ line = (position >> FatColumnModeLineShift) & FatColumnModeLineMask;
+ column = position & FatColumnModeColumnMask;
+ }
+
uint32_t instructionOffset : 25;
- uint32_t divotPoint : 25;
uint32_t startOffset : 7;
+ uint32_t divotPoint : 25;
uint32_t endOffset : 7;
+ uint32_t mode : 2;
+ uint32_t position : 30;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
index d17c17325..db4aa9b99 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp
@@ -30,6 +30,7 @@
#include "JSScope.h"
#include "LLIntData.h"
#include "LowLevelInterpreter.h"
+#include "Operations.h"
namespace JSC {
@@ -51,7 +52,7 @@ GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
unsigned attributesIgnored;
JSCell* specificValue;
PropertyOffset offset = structure->get(
- *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
+ *profiledBlock->vm(), ident, attributesIgnored, specificValue);
if (structure->isDictionary())
specificValue = 0;
if (!isValidOffset(offset))
@@ -92,7 +93,7 @@ void GetByIdStatus::computeForChain(GetByIdStatus& result, CodeBlock* profiledBl
JSCell* specificValue;
result.m_offset = currentStructure->get(
- *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
+ *profiledBlock->vm(), ident, attributesIgnored, specificValue);
if (currentStructure->isDictionary())
specificValue = 0;
if (!isValidOffset(result.m_offset))
@@ -124,6 +125,9 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
if (!stubInfo.seen)
return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
+ if (stubInfo.resetByGC)
+ return GetByIdStatus(TakesSlowPath, true);
+
PolymorphicAccessStructureList* list;
int listSize;
switch (stubInfo.accessType) {
@@ -161,7 +165,7 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
unsigned attributesIgnored;
JSCell* specificValue;
result.m_offset = structure->get(
- *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
+ *profiledBlock->vm(), ident, attributesIgnored, specificValue);
if (structure->isDictionary())
specificValue = 0;
@@ -186,7 +190,7 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
unsigned attributesIgnored;
JSCell* specificValue;
PropertyOffset myOffset = structure->get(
- *profiledBlock->globalData(), ident, attributesIgnored, specificValue);
+ *profiledBlock->vm(), ident, attributesIgnored, specificValue);
if (structure->isDictionary())
specificValue = 0;
@@ -252,7 +256,7 @@ GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
#endif // ENABLE(JIT)
}
-GetByIdStatus GetByIdStatus::computeFor(JSGlobalData& globalData, Structure* structure, Identifier& ident)
+GetByIdStatus GetByIdStatus::computeFor(VM& vm, Structure* structure, Identifier& ident)
{
// For now we only handle the super simple self access case. We could handle the
// prototype case in the future.
@@ -267,10 +271,10 @@ GetByIdStatus GetByIdStatus::computeFor(JSGlobalData& globalData, Structure* str
return GetByIdStatus(TakesSlowPath);
GetByIdStatus result;
- result.m_wasSeenInJIT = false; // To my knowledge nobody that uses computeFor(JSGlobalData&, Structure*, Identifier&) reads this field, but I might as well be honest: no, it wasn't seen in the JIT, since I computed it statically.
+ result.m_wasSeenInJIT = false; // To my knowledge nobody that uses computeFor(VM&, Structure*, Identifier&) reads this field, but I might as well be honest: no, it wasn't seen in the JIT, since I computed it statically.
unsigned attributes;
JSCell* specificValue;
- result.m_offset = structure->get(globalData, ident, attributes, specificValue);
+ result.m_offset = structure->get(vm, ident, attributes, specificValue);
if (!isValidOffset(result.m_offset))
return GetByIdStatus(TakesSlowPath); // It's probably a prototype lookup. Give up on life for now, even though we could totally be way smarter about it.
if (attributes & Accessor)
diff --git a/Source/JavaScriptCore/bytecode/GetByIdStatus.h b/Source/JavaScriptCore/bytecode/GetByIdStatus.h
index 45d8c0b1f..117766646 100644
--- a/Source/JavaScriptCore/bytecode/GetByIdStatus.h
+++ b/Source/JavaScriptCore/bytecode/GetByIdStatus.h
@@ -72,7 +72,7 @@ public:
}
static GetByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
- static GetByIdStatus computeFor(JSGlobalData&, Structure*, Identifier&);
+ static GetByIdStatus computeFor(VM&, Structure*, Identifier&);
State state() const { return m_state; }
diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h
index 50b80e03c..988b1ddf1 100644
--- a/Source/JavaScriptCore/bytecode/Instruction.h
+++ b/Source/JavaScriptCore/bytecode/Instruction.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,206 +29,108 @@
#ifndef Instruction_h
#define Instruction_h
-#include "JITStubRoutine.h"
#include "MacroAssembler.h"
#include "Opcode.h"
#include "PropertySlot.h"
+#include "ResolveOperation.h"
#include "SpecialPointer.h"
#include "Structure.h"
#include "StructureChain.h"
#include <wtf/VectorTraits.h>
-#define POLYMORPHIC_LIST_CACHE_SIZE 8
-
namespace JSC {
- // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel),
- // If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't
- // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best
- // solution for now - will need to something smarter if/when we actually want mixed-mode operation.
-
- class ArrayAllocationProfile;
- class ArrayProfile;
- class JSCell;
- class Structure;
- class StructureChain;
- struct LLIntCallLinkInfo;
- struct ValueProfile;
-
-#if ENABLE(JIT)
- // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
- struct PolymorphicAccessStructureList {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- struct PolymorphicStubInfo {
- bool isChain;
- bool isDirect;
- RefPtr<JITStubRoutine> stubRoutine;
- WriteBarrier<Structure> base;
- union {
- WriteBarrierBase<Structure> proto;
- WriteBarrierBase<StructureChain> chain;
- } u;
-
- PolymorphicStubInfo()
- {
- u.proto.clear();
- }
-
- void set(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, bool isDirect)
- {
- stubRoutine = _stubRoutine;
- base.set(globalData, owner, _base);
- u.proto.clear();
- isChain = false;
- this->isDirect = isDirect;
- }
-
- void set(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, Structure* _proto, bool isDirect)
- {
- stubRoutine = _stubRoutine;
- base.set(globalData, owner, _base);
- u.proto.set(globalData, owner, _proto);
- isChain = false;
- this->isDirect = isDirect;
- }
-
- void set(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, StructureChain* _chain, bool isDirect)
- {
- stubRoutine = _stubRoutine;
- base.set(globalData, owner, _base);
- u.chain.set(globalData, owner, _chain);
- isChain = true;
- this->isDirect = isDirect;
- }
- } list[POLYMORPHIC_LIST_CACHE_SIZE];
+class ArrayAllocationProfile;
+class ArrayProfile;
+class ObjectAllocationProfile;
+struct LLIntCallLinkInfo;
+struct ValueProfile;
+
+struct Instruction {
+ Instruction()
+ {
+ u.jsCell.clear();
+ }
- PolymorphicAccessStructureList()
- {
- }
-
- PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, bool isDirect)
- {
- list[0].set(globalData, owner, stubRoutine, firstBase, isDirect);
- }
-
- PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, Structure* firstProto, bool isDirect)
- {
- list[0].set(globalData, owner, stubRoutine, firstBase, firstProto, isDirect);
- }
-
- PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect)
- {
- list[0].set(globalData, owner, stubRoutine, firstBase, firstChain, isDirect);
- }
-
- bool visitWeak(int count)
- {
- for (int i = 0; i < count; ++i) {
- PolymorphicStubInfo& info = list[i];
- if (!info.base) {
- // We're being marked during initialisation of an entry
- ASSERT(!info.u.proto);
- continue;
- }
-
- if (!Heap::isMarked(info.base.get()))
- return false;
- if (info.u.proto && !info.isChain
- && !Heap::isMarked(info.u.proto.get()))
- return false;
- if (info.u.chain && info.isChain
- && !Heap::isMarked(info.u.chain.get()))
- return false;
- }
-
- return true;
- }
- };
-
-#endif
-
- struct Instruction {
- Instruction()
- {
- u.jsCell.clear();
- }
-
- Instruction(Opcode opcode)
- {
+ Instruction(Opcode opcode)
+ {
#if !ENABLE(COMPUTED_GOTO_OPCODES)
- // We have to initialize one of the pointer members to ensure that
- // the entire struct is initialized, when opcode is not a pointer.
- u.jsCell.clear();
+ // We have to initialize one of the pointer members to ensure that
+ // the entire struct is initialized, when opcode is not a pointer.
+ u.jsCell.clear();
#endif
- u.opcode = opcode;
- }
-
- Instruction(int operand)
- {
- // We have to initialize one of the pointer members to ensure that
- // the entire struct is initialized in 64-bit.
- u.jsCell.clear();
- u.operand = operand;
- }
-
- Instruction(JSGlobalData& globalData, JSCell* owner, Structure* structure)
- {
- u.structure.clear();
- u.structure.set(globalData, owner, structure);
- }
- Instruction(JSGlobalData& globalData, JSCell* owner, StructureChain* structureChain)
- {
- u.structureChain.clear();
- u.structureChain.set(globalData, owner, structureChain);
- }
- Instruction(JSGlobalData& globalData, JSCell* owner, JSCell* jsCell)
- {
- u.jsCell.clear();
- u.jsCell.set(globalData, owner, jsCell);
- }
-
- Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
+ u.opcode = opcode;
+ }
+
+ Instruction(int operand)
+ {
+ // We have to initialize one of the pointer members to ensure that
+ // the entire struct is initialized in 64-bit.
+ u.jsCell.clear();
+ u.operand = operand;
+ }
+
+ Instruction(VM& vm, JSCell* owner, Structure* structure)
+ {
+ u.structure.clear();
+ u.structure.set(vm, owner, structure);
+ }
+ Instruction(VM& vm, JSCell* owner, StructureChain* structureChain)
+ {
+ u.structureChain.clear();
+ u.structureChain.set(vm, owner, structureChain);
+ }
+ Instruction(VM& vm, JSCell* owner, JSCell* jsCell)
+ {
+ u.jsCell.clear();
+ u.jsCell.set(vm, owner, jsCell);
+ }
+
+ Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
- Instruction(LLIntCallLinkInfo* callLinkInfo) { u.callLinkInfo = callLinkInfo; }
+ Instruction(LLIntCallLinkInfo* callLinkInfo) { u.callLinkInfo = callLinkInfo; }
- Instruction(ValueProfile* profile) { u.profile = profile; }
- Instruction(ArrayProfile* profile) { u.arrayProfile = profile; }
- Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; }
+ Instruction(ValueProfile* profile) { u.profile = profile; }
+ Instruction(ArrayProfile* profile) { u.arrayProfile = profile; }
+ Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; }
+ Instruction(ObjectAllocationProfile* profile) { u.objectAllocationProfile = profile; }
- Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; }
+ Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; }
- Instruction(Special::Pointer pointer) { u.specialPointer = pointer; }
+ Instruction(Special::Pointer pointer) { u.specialPointer = pointer; }
- Instruction(bool* predicatePointer) { u.predicatePointer = predicatePointer; }
-
- union {
- Opcode opcode;
- int operand;
- WriteBarrierBase<Structure> structure;
- WriteBarrierBase<StructureChain> structureChain;
- WriteBarrierBase<JSCell> jsCell;
- WriteBarrier<Unknown>* registerPointer;
- Special::Pointer specialPointer;
- PropertySlot::GetValueFunc getterFunc;
- LLIntCallLinkInfo* callLinkInfo;
- ValueProfile* profile;
- ArrayProfile* arrayProfile;
- ArrayAllocationProfile* arrayAllocationProfile;
- void* pointer;
- bool* predicatePointer;
- } u;
+ Instruction(bool* predicatePointer) { u.predicatePointer = predicatePointer; }
+
+ union {
+ Opcode opcode;
+ int operand;
+ WriteBarrierBase<Structure> structure;
+ WriteBarrierBase<StructureChain> structureChain;
+ WriteBarrierBase<JSCell> jsCell;
+ WriteBarrier<Unknown>* registerPointer;
+ Special::Pointer specialPointer;
+ PropertySlot::GetValueFunc getterFunc;
+ LLIntCallLinkInfo* callLinkInfo;
+ ValueProfile* profile;
+ ArrayProfile* arrayProfile;
+ ArrayAllocationProfile* arrayAllocationProfile;
+ ObjectAllocationProfile* objectAllocationProfile;
+ void* pointer;
+ bool* predicatePointer;
+ ResolveOperations* resolveOperations;
+ PutToBaseOperation* putToBaseOperation;
+ } u;
- private:
- Instruction(StructureChain*);
- Instruction(Structure*);
- };
+private:
+ Instruction(StructureChain*);
+ Instruction(Structure*);
+};
} // namespace JSC
namespace WTF {
- template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { };
+template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { };
} // namespace WTF
diff --git a/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp b/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp
index f923e4a28..97b8f3bcd 100644
--- a/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp
@@ -28,6 +28,8 @@
#if ENABLE(VALUE_PROFILER)
+#include "Operations.h"
+
namespace JSC {
CompressedLazyOperandValueProfileHolder::CompressedLazyOperandValueProfileHolder() { }
diff --git a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
index 857ed9c87..a0f301a0c 100644
--- a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
@@ -58,7 +58,7 @@ EncodedJSValue* MethodOfGettingAValueProfile::getSpecFailBucket(unsigned index)
u.lazyOperand.bytecodeOffset, u.lazyOperand.operand))->specFailBucket(index);
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
}
diff --git a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
index 0f5c2be7b..c6fe6c5f0 100644
--- a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
+++ b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
@@ -34,7 +34,7 @@
// these #if's will disappear...
#if ENABLE(DFG_JIT)
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h b/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h
new file mode 100644
index 000000000..9a9db0bc7
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ObjectAllocationProfile_h
+#define ObjectAllocationProfile_h
+
+#include "VM.h"
+#include "JSGlobalObject.h"
+#include "ObjectPrototype.h"
+#include "SlotVisitor.h"
+#include "WriteBarrier.h"
+
+namespace JSC {
+
+class ObjectAllocationProfile {
+ friend class LLIntOffsetsExtractor;
+public:
+ static ptrdiff_t offsetOfAllocator() { return OBJECT_OFFSETOF(ObjectAllocationProfile, m_allocator); }
+ static ptrdiff_t offsetOfStructure() { return OBJECT_OFFSETOF(ObjectAllocationProfile, m_structure); }
+
+ ObjectAllocationProfile()
+ : m_allocator(0)
+ {
+ }
+
+ bool isNull() { return !m_allocator; }
+
+ void initialize(VM& vm, JSCell* owner, JSObject* prototype, unsigned inferredInlineCapacity)
+ {
+ ASSERT(!m_allocator);
+ ASSERT(!m_structure);
+
+ unsigned inlineCapacity = 0;
+ if (inferredInlineCapacity < JSFinalObject::defaultInlineCapacity()) {
+ // Try to shrink the object based on static analysis.
+ inferredInlineCapacity += possibleDefaultPropertyCount(vm, prototype);
+
+ if (!inferredInlineCapacity) {
+ // Empty objects are rare, so most likely the static analyzer just didn't
+ // see the real initializer function. This can happen with helper functions.
+ inferredInlineCapacity = JSFinalObject::defaultInlineCapacity();
+ } else if (inferredInlineCapacity > JSFinalObject::defaultInlineCapacity()) {
+ // Default properties are weak guesses, so don't allow them to turn a small
+ // object into a large object.
+ inferredInlineCapacity = JSFinalObject::defaultInlineCapacity();
+ }
+
+ inlineCapacity = inferredInlineCapacity;
+ ASSERT(inlineCapacity < JSFinalObject::maxInlineCapacity());
+ } else {
+ // Normal or large object.
+ inlineCapacity = inferredInlineCapacity;
+ if (inlineCapacity > JSFinalObject::maxInlineCapacity())
+ inlineCapacity = JSFinalObject::maxInlineCapacity();
+ }
+
+ ASSERT(inlineCapacity > 0);
+ ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
+
+ size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity);
+ MarkedAllocator* allocator = &vm.heap.allocatorForObjectWithoutDestructor(allocationSize);
+ ASSERT(allocator->cellSize());
+
+ // Take advantage of extra inline capacity available in the size class.
+ size_t slop = (allocator->cellSize() - allocationSize) / sizeof(WriteBarrier<Unknown>);
+ inlineCapacity += slop;
+ if (inlineCapacity > JSFinalObject::maxInlineCapacity())
+ inlineCapacity = JSFinalObject::maxInlineCapacity();
+
+ m_allocator = allocator;
+ m_structure.set(vm, owner,
+ vm.prototypeMap.emptyObjectStructureForPrototype(prototype, inlineCapacity));
+ }
+
+ Structure* structure() { return m_structure.get(); }
+ unsigned inlineCapacity() { return m_structure->inlineCapacity(); }
+
+ void clear()
+ {
+ m_allocator = 0;
+ m_structure.clear();
+ ASSERT(isNull());
+ }
+
+ void visitAggregate(SlotVisitor& visitor)
+ {
+ visitor.append(&m_structure);
+ }
+
+private:
+
+ unsigned possibleDefaultPropertyCount(VM& vm, JSObject* prototype)
+ {
+ if (prototype == prototype->globalObject()->objectPrototype())
+ return 0;
+
+ size_t count = 0;
+ PropertyNameArray propertyNameArray(&vm);
+ prototype->structure()->getPropertyNamesFromStructure(vm, propertyNameArray, ExcludeDontEnumProperties);
+ PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArray.data()->propertyNameVector();
+ for (size_t i = 0; i < propertyNameVector.size(); ++i) {
+ JSValue value = prototype->getDirect(vm, propertyNameVector[i]);
+
+ // Functions are common, and are usually class-level objects that are not overridden.
+ if (jsDynamicCast<JSFunction*>(value))
+ continue;
+
+ ++count;
+
+ }
+ return count;
+ }
+
+ MarkedAllocator* m_allocator; // Precomputed to make things easier for generated code.
+ WriteBarrier<Structure> m_structure;
+};
+
+} // namespace JSC
+
+#endif // ObjectAllocationProfile_h
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index 5fe28bc09..72ac51b4f 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,260 +39,253 @@
namespace JSC {
- #define FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, extension__) \
- macro(op_enter, 1) \
- macro(op_create_activation, 2) \
- macro(op_init_lazy_reg, 2) \
- macro(op_create_arguments, 2) \
- macro(op_create_this, 3) \
- macro(op_get_callee, 3) \
- macro(op_convert_this, 3) \
- \
- macro(op_new_object, 2) \
- macro(op_new_array, 5) \
- macro(op_new_array_with_size, 4) \
- macro(op_new_array_buffer, 5) \
- macro(op_new_regexp, 3) \
- macro(op_mov, 3) \
- \
- macro(op_not, 3) \
- macro(op_eq, 4) \
- macro(op_eq_null, 3) \
- macro(op_neq, 4) \
- macro(op_neq_null, 3) \
- macro(op_stricteq, 4) \
- macro(op_nstricteq, 4) \
- macro(op_less, 4) \
- macro(op_lesseq, 4) \
- macro(op_greater, 4) \
- macro(op_greatereq, 4) \
- \
- macro(op_pre_inc, 2) \
- macro(op_pre_dec, 2) \
- macro(op_post_inc, 3) \
- macro(op_post_dec, 3) \
- macro(op_to_jsnumber, 3) \
- macro(op_negate, 3) \
- macro(op_add, 5) \
- macro(op_mul, 5) \
- macro(op_div, 5) \
- macro(op_mod, 4) \
- macro(op_sub, 5) \
- \
- macro(op_lshift, 4) \
- macro(op_rshift, 4) \
- macro(op_urshift, 4) \
- macro(op_bitand, 5) \
- macro(op_bitxor, 5) \
- macro(op_bitor, 5) \
- \
- macro(op_check_has_instance, 5) \
- macro(op_instanceof, 4) \
- macro(op_typeof, 3) \
- macro(op_is_undefined, 3) \
- macro(op_is_boolean, 3) \
- macro(op_is_number, 3) \
- macro(op_is_string, 3) \
- macro(op_is_object, 3) \
- macro(op_is_function, 3) \
- macro(op_in, 4) \
- \
- macro(op_resolve, 5) /* has value profiling */ \
- macro(op_resolve_global_property, 5) /* has value profiling */ \
- macro(op_resolve_global_var, 5) /* has value profiling */ \
- macro(op_resolve_scoped_var, 5) /* has value profiling */ \
- macro(op_resolve_scoped_var_on_top_scope, 5) /* has value profiling */ \
- macro(op_resolve_scoped_var_with_top_scope_check, 5) /* has value profiling */ \
- \
- macro(op_resolve_base_to_global, 7) /* has value profiling */ \
- macro(op_resolve_base_to_global_dynamic, 7) /* has value profiling */ \
- macro(op_resolve_base_to_scope, 7) /* has value profiling */ \
- macro(op_resolve_base_to_scope_with_top_scope_check, 7) /* has value profiling */ \
- macro(op_resolve_base, 7) /* has value profiling */ \
- \
- macro(op_ensure_property_exists, 3) \
- \
- macro(op_resolve_with_base, 7) /* has value profiling */ \
- \
- macro(op_resolve_with_this, 6) /* has value profiling */ \
- \
- macro(op_put_to_base, 5) \
- macro(op_put_to_base_variable, 5) \
- \
- macro(op_init_global_const_nop, 5) \
- macro(op_init_global_const, 5) \
- macro(op_init_global_const_check, 5) \
- macro(op_get_by_id, 9) /* has value profiling */ \
- macro(op_get_by_id_out_of_line, 9) /* has value profiling */ \
- macro(op_get_by_id_self, 9) /* has value profiling */ \
- macro(op_get_by_id_proto, 9) /* has value profiling */ \
- macro(op_get_by_id_chain, 9) /* has value profiling */ \
- macro(op_get_by_id_getter_self, 9) /* has value profiling */ \
- macro(op_get_by_id_getter_proto, 9) /* has value profiling */ \
- macro(op_get_by_id_getter_chain, 9) /* has value profiling */ \
- macro(op_get_by_id_custom_self, 9) /* has value profiling */ \
- macro(op_get_by_id_custom_proto, 9) /* has value profiling */ \
- macro(op_get_by_id_custom_chain, 9) /* has value profiling */ \
- macro(op_get_by_id_generic, 9) /* has value profiling */ \
- macro(op_get_array_length, 9) /* has value profiling */ \
- macro(op_get_string_length, 9) /* has value profiling */ \
- macro(op_get_arguments_length, 4) \
- macro(op_put_by_id, 9) \
- macro(op_put_by_id_out_of_line, 9) \
- macro(op_put_by_id_transition, 9) \
- macro(op_put_by_id_transition_direct, 9) \
- macro(op_put_by_id_transition_direct_out_of_line, 9) \
- macro(op_put_by_id_transition_normal, 9) \
- macro(op_put_by_id_transition_normal_out_of_line, 9) \
- macro(op_put_by_id_replace, 9) \
- macro(op_put_by_id_generic, 9) \
- macro(op_del_by_id, 4) \
- macro(op_get_by_val, 6) /* has value profiling */ \
- macro(op_get_argument_by_val, 6) /* must be the same size as op_get_by_val */ \
- macro(op_get_by_pname, 7) \
- macro(op_put_by_val, 5) \
- macro(op_del_by_val, 4) \
- macro(op_put_by_index, 4) \
- macro(op_put_getter_setter, 5) \
- \
- macro(op_jmp, 2) \
- macro(op_jtrue, 3) \
- macro(op_jfalse, 3) \
- macro(op_jeq_null, 3) \
- macro(op_jneq_null, 3) \
- macro(op_jneq_ptr, 4) \
- macro(op_jless, 4) \
- macro(op_jlesseq, 4) \
- macro(op_jgreater, 4) \
- macro(op_jgreatereq, 4) \
- macro(op_jnless, 4) \
- macro(op_jnlesseq, 4) \
- macro(op_jngreater, 4) \
- macro(op_jngreatereq, 4) \
- macro(op_jmp_scopes, 3) \
- macro(op_loop, 2) \
- macro(op_loop_if_true, 3) \
- macro(op_loop_if_false, 3) \
- macro(op_loop_if_less, 4) \
- macro(op_loop_if_lesseq, 4) \
- macro(op_loop_if_greater, 4) \
- macro(op_loop_if_greatereq, 4) \
- macro(op_loop_hint, 1) \
- macro(op_switch_imm, 4) \
- macro(op_switch_char, 4) \
- macro(op_switch_string, 4) \
- \
- macro(op_new_func, 4) \
- macro(op_new_func_exp, 3) \
- macro(op_call, 6) \
- macro(op_call_eval, 6) \
- macro(op_call_varargs, 5) \
- macro(op_tear_off_activation, 2) \
- macro(op_tear_off_arguments, 3) \
- macro(op_ret, 2) \
- macro(op_call_put_result, 3) /* has value profiling */ \
- macro(op_ret_object_or_this, 3) \
- \
- macro(op_construct, 6) \
- macro(op_strcat, 4) \
- macro(op_to_primitive, 3) \
- \
- macro(op_get_pnames, 6) \
- macro(op_next_pname, 7) \
- \
- macro(op_push_with_scope, 2) \
- macro(op_pop_scope, 1) \
- macro(op_push_name_scope, 4) \
- \
- macro(op_catch, 2) \
- macro(op_throw, 2) \
- macro(op_throw_static_error, 3) \
- \
- macro(op_debug, 5) \
- macro(op_profile_will_call, 2) \
- macro(op_profile_did_call, 2) \
- \
- extension__ \
- \
- macro(op_end, 2) // end must be the last opcode in the list
+#define FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, extension__) \
+ macro(op_enter, 1) \
+ macro(op_create_activation, 2) \
+ macro(op_init_lazy_reg, 2) \
+ macro(op_create_arguments, 2) \
+ macro(op_create_this, 4) \
+ macro(op_get_callee, 3) \
+ macro(op_convert_this, 3) \
+ \
+ macro(op_new_object, 4) \
+ macro(op_new_array, 5) \
+ macro(op_new_array_with_size, 4) \
+ macro(op_new_array_buffer, 5) \
+ macro(op_new_regexp, 3) \
+ macro(op_mov, 3) \
+ \
+ macro(op_not, 3) \
+ macro(op_eq, 4) \
+ macro(op_eq_null, 3) \
+ macro(op_neq, 4) \
+ macro(op_neq_null, 3) \
+ macro(op_stricteq, 4) \
+ macro(op_nstricteq, 4) \
+ macro(op_less, 4) \
+ macro(op_lesseq, 4) \
+ macro(op_greater, 4) \
+ macro(op_greatereq, 4) \
+ \
+ macro(op_inc, 2) \
+ macro(op_dec, 2) \
+ macro(op_to_number, 3) \
+ macro(op_negate, 3) \
+ macro(op_add, 5) \
+ macro(op_mul, 5) \
+ macro(op_div, 5) \
+ macro(op_mod, 4) \
+ macro(op_sub, 5) \
+ \
+ macro(op_lshift, 4) \
+ macro(op_rshift, 4) \
+ macro(op_urshift, 4) \
+ macro(op_bitand, 5) \
+ macro(op_bitxor, 5) \
+ macro(op_bitor, 5) \
+ \
+ macro(op_check_has_instance, 5) \
+ macro(op_instanceof, 4) \
+ macro(op_typeof, 3) \
+ macro(op_is_undefined, 3) \
+ macro(op_is_boolean, 3) \
+ macro(op_is_number, 3) \
+ macro(op_is_string, 3) \
+ macro(op_is_object, 3) \
+ macro(op_is_function, 3) \
+ macro(op_in, 4) \
+ \
+ macro(op_get_scoped_var, 5) /* has value profiling */ \
+ macro(op_put_scoped_var, 4) \
+ \
+ macro(op_resolve, 5) /* has value profiling */ \
+ macro(op_resolve_global_property, 5) /* has value profiling */ \
+ macro(op_resolve_global_var, 5) /* has value profiling */ \
+ macro(op_resolve_scoped_var, 5) /* has value profiling */ \
+ macro(op_resolve_scoped_var_on_top_scope, 5) /* has value profiling */ \
+ macro(op_resolve_scoped_var_with_top_scope_check, 5) /* has value profiling */ \
+ \
+ macro(op_resolve_base_to_global, 7) /* has value profiling */ \
+ macro(op_resolve_base_to_global_dynamic, 7) /* has value profiling */ \
+ macro(op_resolve_base_to_scope, 7) /* has value profiling */ \
+ macro(op_resolve_base_to_scope_with_top_scope_check, 7) /* has value profiling */ \
+ macro(op_resolve_base, 7) /* has value profiling */ \
+ \
+ macro(op_resolve_with_base, 7) /* has value profiling */ \
+ \
+ macro(op_resolve_with_this, 6) /* has value profiling */ \
+ \
+ macro(op_put_to_base, 5) \
+ macro(op_put_to_base_variable, 5) \
+ \
+ macro(op_init_global_const_nop, 5) \
+ macro(op_init_global_const, 5) \
+ macro(op_init_global_const_check, 5) \
+ macro(op_get_by_id, 9) /* has value profiling */ \
+ macro(op_get_by_id_out_of_line, 9) /* has value profiling */ \
+ macro(op_get_by_id_self, 9) /* has value profiling */ \
+ macro(op_get_by_id_proto, 9) /* has value profiling */ \
+ macro(op_get_by_id_chain, 9) /* has value profiling */ \
+ macro(op_get_by_id_getter_self, 9) /* has value profiling */ \
+ macro(op_get_by_id_getter_proto, 9) /* has value profiling */ \
+ macro(op_get_by_id_getter_chain, 9) /* has value profiling */ \
+ macro(op_get_by_id_custom_self, 9) /* has value profiling */ \
+ macro(op_get_by_id_custom_proto, 9) /* has value profiling */ \
+ macro(op_get_by_id_custom_chain, 9) /* has value profiling */ \
+ macro(op_get_by_id_generic, 9) /* has value profiling */ \
+ macro(op_get_array_length, 9) /* has value profiling */ \
+ macro(op_get_string_length, 9) /* has value profiling */ \
+ macro(op_get_arguments_length, 4) \
+ macro(op_put_by_id, 9) \
+ macro(op_put_by_id_out_of_line, 9) \
+ macro(op_put_by_id_transition, 9) \
+ macro(op_put_by_id_transition_direct, 9) \
+ macro(op_put_by_id_transition_direct_out_of_line, 9) \
+ macro(op_put_by_id_transition_normal, 9) \
+ macro(op_put_by_id_transition_normal_out_of_line, 9) \
+ macro(op_put_by_id_replace, 9) \
+ macro(op_put_by_id_generic, 9) \
+ macro(op_del_by_id, 4) \
+ macro(op_get_by_val, 6) /* has value profiling */ \
+ macro(op_get_argument_by_val, 6) /* must be the same size as op_get_by_val */ \
+ macro(op_get_by_pname, 7) \
+ macro(op_put_by_val, 5) \
+ macro(op_del_by_val, 4) \
+ macro(op_put_by_index, 4) \
+ macro(op_put_getter_setter, 5) \
+ \
+ macro(op_jmp, 2) \
+ macro(op_jtrue, 3) \
+ macro(op_jfalse, 3) \
+ macro(op_jeq_null, 3) \
+ macro(op_jneq_null, 3) \
+ macro(op_jneq_ptr, 4) \
+ macro(op_jless, 4) \
+ macro(op_jlesseq, 4) \
+ macro(op_jgreater, 4) \
+ macro(op_jgreatereq, 4) \
+ macro(op_jnless, 4) \
+ macro(op_jnlesseq, 4) \
+ macro(op_jngreater, 4) \
+ macro(op_jngreatereq, 4) \
+ \
+ macro(op_loop_hint, 1) \
+ \
+ macro(op_switch_imm, 4) \
+ macro(op_switch_char, 4) \
+ macro(op_switch_string, 4) \
+ \
+ macro(op_new_func, 4) \
+ macro(op_new_func_exp, 3) \
+ macro(op_call, 6) \
+ macro(op_call_eval, 6) \
+ macro(op_call_varargs, 5) \
+ macro(op_tear_off_activation, 2) \
+ macro(op_tear_off_arguments, 3) \
+ macro(op_ret, 2) \
+ macro(op_call_put_result, 3) /* has value profiling */ \
+ macro(op_ret_object_or_this, 3) \
+ \
+ macro(op_construct, 6) \
+ macro(op_strcat, 4) \
+ macro(op_to_primitive, 3) \
+ \
+ macro(op_get_pnames, 6) \
+ macro(op_next_pname, 7) \
+ \
+ macro(op_push_with_scope, 2) \
+ macro(op_pop_scope, 1) \
+ macro(op_push_name_scope, 4) \
+ \
+ macro(op_catch, 2) \
+ macro(op_throw, 2) \
+ macro(op_throw_static_error, 3) \
+ \
+ macro(op_debug, 5) \
+ macro(op_profile_will_call, 2) \
+ macro(op_profile_did_call, 2) \
+ \
+ extension__ \
+ \
+ macro(op_end, 2) // end must be the last opcode in the list
- #define FOR_EACH_CORE_OPCODE_ID(macro) \
- FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, /* No extension */ )
+#define FOR_EACH_CORE_OPCODE_ID(macro) \
+ FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION(macro, /* No extension */ )
- #define FOR_EACH_OPCODE_ID(macro) \
- FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION( \
- macro, \
- FOR_EACH_LLINT_OPCODE_EXTENSION(macro) \
- )
+#define FOR_EACH_OPCODE_ID(macro) \
+ FOR_EACH_CORE_OPCODE_ID_WITH_EXTENSION( \
+ macro, \
+ FOR_EACH_LLINT_OPCODE_EXTENSION(macro) \
+ )
- #define OPCODE_ID_ENUM(opcode, length) opcode,
- typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
- #undef OPCODE_ID_ENUM
+#define OPCODE_ID_ENUM(opcode, length) opcode,
+ typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
+#undef OPCODE_ID_ENUM
- const int maxOpcodeLength = 9;
- const int numOpcodeIDs = op_end + 1;
+const int maxOpcodeLength = 9;
+const int numOpcodeIDs = op_end + 1;
- #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
- FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS);
- #undef OPCODE_ID_LENGTHS
-
- #define OPCODE_LENGTH(opcode) opcode##_length
+#define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
+ FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS);
+#undef OPCODE_ID_LENGTHS
+
+#define OPCODE_LENGTH(opcode) opcode##_length
- #define OPCODE_ID_LENGTH_MAP(opcode, length) length,
- const int opcodeLengths[numOpcodeIDs] = { FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTH_MAP) };
- #undef OPCODE_ID_LENGTH_MAP
+#define OPCODE_ID_LENGTH_MAP(opcode, length) length,
+ const int opcodeLengths[numOpcodeIDs] = { FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTH_MAP) };
+#undef OPCODE_ID_LENGTH_MAP
- #define VERIFY_OPCODE_ID(id, size) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
- FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
- #undef VERIFY_OPCODE_ID
+#define VERIFY_OPCODE_ID(id, size) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
+ FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
+#undef VERIFY_OPCODE_ID
#if ENABLE(COMPUTED_GOTO_OPCODES)
- typedef void* Opcode;
+typedef void* Opcode;
#else
- typedef OpcodeID Opcode;
+typedef OpcodeID Opcode;
#endif
#define PADDING_STRING " "
#define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
- extern const char* const opcodeNames[];
+extern const char* const opcodeNames[];
- inline const char* padOpcodeName(OpcodeID op, unsigned width)
- {
- unsigned pad = width - strlen(opcodeNames[op]);
- pad = std::min(pad, PADDING_STRING_LENGTH);
- return PADDING_STRING + PADDING_STRING_LENGTH - pad;
- }
+inline const char* padOpcodeName(OpcodeID op, unsigned width)
+{
+ unsigned pad = width - strlen(opcodeNames[op]);
+ pad = std::min(pad, PADDING_STRING_LENGTH);
+ return PADDING_STRING + PADDING_STRING_LENGTH - pad;
+}
#undef PADDING_STRING_LENGTH
#undef PADDING_STRING
#if ENABLE(OPCODE_STATS)
- struct OpcodeStats {
- OpcodeStats();
- ~OpcodeStats();
- static long long opcodeCounts[numOpcodeIDs];
- static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
- static int lastOpcode;
-
- static void recordInstruction(int opcode);
- static void resetLastInstruction();
- };
+struct OpcodeStats {
+ OpcodeStats();
+ ~OpcodeStats();
+ static long long opcodeCounts[numOpcodeIDs];
+ static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
+ static int lastOpcode;
+
+ static void recordInstruction(int opcode);
+ static void resetLastInstruction();
+};
#endif
- inline size_t opcodeLength(OpcodeID opcode)
- {
- switch (opcode) {
+inline size_t opcodeLength(OpcodeID opcode)
+{
+ switch (opcode) {
#define OPCODE_ID_LENGTHS(id, length) case id: return OPCODE_LENGTH(id);
- FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS)
+ FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS)
#undef OPCODE_ID_LENGTHS
- }
- ASSERT_NOT_REACHED();
- return 0;
}
+ RELEASE_ASSERT_NOT_REACHED();
+ return 0;
+}
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/Operands.h b/Source/JavaScriptCore/bytecode/Operands.h
index 20f79ffd1..e7b3e241f 100644
--- a/Source/JavaScriptCore/bytecode/Operands.h
+++ b/Source/JavaScriptCore/bytecode/Operands.h
@@ -46,6 +46,8 @@ struct OperandValueTraits {
static void dump(const T& value, PrintStream& out) { value.dump(out); }
};
+enum OperandKind { ArgumentOperand, LocalOperand };
+
template<typename T, typename Traits = OperandValueTraits<T> >
class Operands {
public:
@@ -66,6 +68,28 @@ public:
T& local(size_t idx) { return m_locals[idx]; }
const T& local(size_t idx) const { return m_locals[idx]; }
+ template<OperandKind operandKind>
+ size_t sizeFor() const
+ {
+ if (operandKind == ArgumentOperand)
+ return numberOfArguments();
+ return numberOfLocals();
+ }
+ template<OperandKind operandKind>
+ T& atFor(size_t idx)
+ {
+ if (operandKind == ArgumentOperand)
+ return argument(idx);
+ return local(idx);
+ }
+ template<OperandKind operandKind>
+ const T& atFor(size_t idx) const
+ {
+ if (operandKind == ArgumentOperand)
+ return argument(idx);
+ return local(idx);
+ }
+
void ensureLocals(size_t size)
{
if (size <= m_locals.size())
@@ -192,15 +216,17 @@ private:
template<typename T, typename Traits>
void dumpOperands(const Operands<T, Traits>& operands, PrintStream& out)
{
- for (size_t argument = 0; argument < operands.numberOfArguments(); ++argument) {
- if (argument)
+ for (size_t argument = operands.numberOfArguments(); argument--;) {
+ if (argument != operands.numberOfArguments() - 1)
out.printf(" ");
+ out.print("arg", argument, ":");
Traits::dump(operands.argument(argument), out);
}
out.printf(" : ");
for (size_t local = 0; local < operands.numberOfLocals(); ++local) {
if (local)
out.printf(" ");
+ out.print("r", local, ":");
Traits::dump(operands.local(local), out);
}
}
diff --git a/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h b/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h
new file mode 100644
index 000000000..d1da89d77
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/PolymorphicAccessStructureList.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PolymorphicAccessStructureList_h
+#define PolymorphicAccessStructureList_h
+
+#include "JITStubRoutine.h"
+#include "Structure.h"
+#include "StructureChain.h"
+#include <wtf/Platform.h>
+
+#define POLYMORPHIC_LIST_CACHE_SIZE 8
+
+namespace JSC {
+
+// *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel),
+// If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't
+// curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best
+// solution for now - will need to something smarter if/when we actually want mixed-mode operation.
+
+#if ENABLE(JIT)
+// Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
+struct PolymorphicAccessStructureList {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ struct PolymorphicStubInfo {
+ bool isChain;
+ bool isDirect;
+ RefPtr<JITStubRoutine> stubRoutine;
+ WriteBarrier<Structure> base;
+ union {
+ WriteBarrierBase<Structure> proto;
+ WriteBarrierBase<StructureChain> chain;
+ } u;
+
+ PolymorphicStubInfo()
+ {
+ u.proto.clear();
+ }
+
+ void set(VM& vm, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, bool isDirect)
+ {
+ stubRoutine = _stubRoutine;
+ base.set(vm, owner, _base);
+ u.proto.clear();
+ isChain = false;
+ this->isDirect = isDirect;
+ }
+
+ void set(VM& vm, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, Structure* _proto, bool isDirect)
+ {
+ stubRoutine = _stubRoutine;
+ base.set(vm, owner, _base);
+ u.proto.set(vm, owner, _proto);
+ isChain = false;
+ this->isDirect = isDirect;
+ }
+
+ void set(VM& vm, JSCell* owner, PassRefPtr<JITStubRoutine> _stubRoutine, Structure* _base, StructureChain* _chain, bool isDirect)
+ {
+ stubRoutine = _stubRoutine;
+ base.set(vm, owner, _base);
+ u.chain.set(vm, owner, _chain);
+ isChain = true;
+ this->isDirect = isDirect;
+ }
+ } list[POLYMORPHIC_LIST_CACHE_SIZE];
+
+ PolymorphicAccessStructureList()
+ {
+ }
+
+ PolymorphicAccessStructureList(VM& vm, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, bool isDirect)
+ {
+ list[0].set(vm, owner, stubRoutine, firstBase, isDirect);
+ }
+
+ PolymorphicAccessStructureList(VM& vm, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, Structure* firstProto, bool isDirect)
+ {
+ list[0].set(vm, owner, stubRoutine, firstBase, firstProto, isDirect);
+ }
+
+ PolymorphicAccessStructureList(VM& vm, JSCell* owner, PassRefPtr<JITStubRoutine> stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect)
+ {
+ list[0].set(vm, owner, stubRoutine, firstBase, firstChain, isDirect);
+ }
+
+ bool visitWeak(int count)
+ {
+ for (int i = 0; i < count; ++i) {
+ PolymorphicStubInfo& info = list[i];
+ if (!info.base) {
+ // We're being marked during initialisation of an entry
+ ASSERT(!info.u.proto);
+ continue;
+ }
+
+ if (!Heap::isMarked(info.base.get()))
+ return false;
+ if (info.u.proto && !info.isChain
+ && !Heap::isMarked(info.u.proto.get()))
+ return false;
+ if (info.u.chain && info.isChain
+ && !Heap::isMarked(info.u.chain.get()))
+ return false;
+ }
+
+ return true;
+ }
+};
+
+#endif // ENABLE(JIT)
+
+} // namespace JSC
+
+#endif // PolymorphicAccessStructureList_h
+
diff --git a/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp b/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp
index 3a87567d8..6a6ec8141 100644
--- a/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp
+++ b/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp
@@ -55,7 +55,7 @@ PutByIdAccess PutByIdAccess::fromStructureStubInfo(
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
return result;
@@ -77,7 +77,7 @@ bool PutByIdAccess::visitWeak() const
return false;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
return true;
diff --git a/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h b/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h
index 4a20b6d1c..6e88e7062 100644
--- a/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h
+++ b/Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h
@@ -55,7 +55,7 @@ public:
}
static PutByIdAccess transition(
- JSGlobalData& globalData,
+ VM& vm,
JSCell* owner,
Structure* oldStructure,
Structure* newStructure,
@@ -64,22 +64,22 @@ public:
{
PutByIdAccess result;
result.m_type = Transition;
- result.m_oldStructure.set(globalData, owner, oldStructure);
- result.m_newStructure.set(globalData, owner, newStructure);
- result.m_chain.set(globalData, owner, chain);
+ result.m_oldStructure.set(vm, owner, oldStructure);
+ result.m_newStructure.set(vm, owner, newStructure);
+ result.m_chain.set(vm, owner, chain);
result.m_stubRoutine = stubRoutine;
return result;
}
static PutByIdAccess replace(
- JSGlobalData& globalData,
+ VM& vm,
JSCell* owner,
Structure* structure,
PassRefPtr<JITStubRoutine> stubRoutine)
{
PutByIdAccess result;
result.m_type = Replace;
- result.m_oldStructure.set(globalData, owner, structure);
+ result.m_oldStructure.set(vm, owner, structure);
result.m_stubRoutine = stubRoutine;
return result;
}
diff --git a/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
new file mode 100644
index 000000000..0cdf51a98
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PreciseJumpTargets.h"
+
+namespace JSC {
+
+static void addSimpleSwitchTargets(SimpleJumpTable& jumpTable, unsigned bytecodeOffset, Vector<unsigned, 32>& out)
+{
+ for (unsigned i = jumpTable.branchOffsets.size(); i--;)
+ out.append(bytecodeOffset + jumpTable.branchOffsets[i]);
+}
+
+void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
+{
+ ASSERT(out.isEmpty());
+
+ // We will derive a superset of the jump targets that the code block thinks it has.
+ // So, if the code block claims there are none, then we are done.
+ if (!codeBlock->numberOfJumpTargets())
+ return;
+
+ for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;)
+ out.append(codeBlock->exceptionHandler(i).target);
+
+ Interpreter* interpreter = codeBlock->vm()->interpreter;
+ Instruction* instructionsBegin = codeBlock->instructions().begin();
+ unsigned instructionCount = codeBlock->instructions().size();
+ for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount;) {
+ OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
+ Instruction* current = instructionsBegin + bytecodeOffset;
+ switch (opcodeID) {
+ case op_jmp:
+ out.append(bytecodeOffset + current[1].u.operand);
+ break;
+ case op_jtrue:
+ case op_jfalse:
+ case op_jeq_null:
+ case op_jneq_null:
+ out.append(bytecodeOffset + current[2].u.operand);
+ break;
+ case op_jneq_ptr:
+ case op_jless:
+ case op_jlesseq:
+ case op_jgreater:
+ case op_jgreatereq:
+ case op_jnless:
+ case op_jnlesseq:
+ case op_jngreater:
+ case op_jngreatereq:
+ out.append(bytecodeOffset + current[3].u.operand);
+ break;
+ case op_switch_imm:
+ addSimpleSwitchTargets(codeBlock->immediateSwitchJumpTable(current[1].u.operand), bytecodeOffset, out);
+ out.append(bytecodeOffset + current[2].u.operand);
+ break;
+ case op_switch_char:
+ addSimpleSwitchTargets(codeBlock->characterSwitchJumpTable(current[1].u.operand), bytecodeOffset, out);
+ out.append(bytecodeOffset + current[2].u.operand);
+ break;
+ case op_switch_string: {
+ StringJumpTable& table = codeBlock->stringSwitchJumpTable(current[1].u.operand);
+ StringJumpTable::StringOffsetTable::iterator iter = table.offsetTable.begin();
+ StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
+ for (; iter != end; ++iter)
+ out.append(bytecodeOffset + iter->value.branchOffset);
+ out.append(bytecodeOffset + current[2].u.operand);
+ break;
+ }
+ case op_get_pnames:
+ out.append(bytecodeOffset + current[5].u.operand);
+ break;
+ case op_next_pname:
+ out.append(bytecodeOffset + current[6].u.operand);
+ break;
+ case op_check_has_instance:
+ out.append(bytecodeOffset + current[4].u.operand);
+ break;
+ case op_loop_hint:
+ out.append(bytecodeOffset);
+ break;
+ default:
+ break;
+ }
+ bytecodeOffset += opcodeLengths[opcodeID];
+ }
+
+ std::sort(out.begin(), out.end());
+
+ // We will have duplicates, and we must remove them.
+ unsigned toIndex = 0;
+ unsigned fromIndex = 0;
+ unsigned lastValue = UINT_MAX;
+ while (fromIndex < out.size()) {
+ unsigned value = out[fromIndex++];
+ if (value == lastValue)
+ continue;
+ out[toIndex++] = value;
+ lastValue = value;
+ }
+ out.resize(toIndex);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/bytecode/PreciseJumpTargets.h b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.h
new file mode 100644
index 000000000..109c40cea
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/PreciseJumpTargets.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PreciseJumpTargets_h
+#define PreciseJumpTargets_h
+
+#include "CodeBlock.h"
+
+namespace JSC {
+
+void computePreciseJumpTargets(CodeBlock*, Vector<unsigned, 32>& out);
+
+} // namespace JSC
+
+#endif // PreciseJumpTargets_h
+
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
index 7d6ba0987..24a57eb50 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
@@ -49,7 +49,7 @@ PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
if (instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id)
|| instruction[0].u.opcode == LLInt::getOpcode(llint_op_put_by_id_out_of_line)) {
- PropertyOffset offset = structure->get(*profiledBlock->globalData(), ident);
+ PropertyOffset offset = structure->get(*profiledBlock->vm(), ident);
if (!isValidOffset(offset))
return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
@@ -68,7 +68,7 @@ PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned
ASSERT(newStructure);
ASSERT(chain);
- PropertyOffset offset = newStructure->get(*profiledBlock->globalData(), ident);
+ PropertyOffset offset = newStructure->get(*profiledBlock->vm(), ident);
if (!isValidOffset(offset))
return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
@@ -94,13 +94,17 @@ PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
if (!stubInfo.seen)
return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
+ if (stubInfo.resetByGC)
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
+
switch (stubInfo.accessType) {
case access_unset:
- return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
+ // If the JIT saw it but didn't optimize it, then assume that this takes slow path.
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
case access_put_by_id_replace: {
PropertyOffset offset = stubInfo.u.putByIdReplace.baseObjectStructure->get(
- *profiledBlock->globalData(), ident);
+ *profiledBlock->vm(), ident);
if (isValidOffset(offset)) {
return PutByIdStatus(
SimpleReplace,
@@ -115,7 +119,7 @@ PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
case access_put_by_id_transition_direct: {
ASSERT(stubInfo.u.putByIdTransition.previousStructure->transitionWatchpointSetHasBeenInvalidated());
PropertyOffset offset = stubInfo.u.putByIdTransition.structure->get(
- *profiledBlock->globalData(), ident);
+ *profiledBlock->vm(), ident);
if (isValidOffset(offset)) {
return PutByIdStatus(
SimpleTransition,
@@ -135,7 +139,7 @@ PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytec
#endif // ENABLE(JIT)
}
-PutByIdStatus PutByIdStatus::computeFor(JSGlobalData& globalData, JSGlobalObject* globalObject, Structure* structure, Identifier& ident, bool isDirect)
+PutByIdStatus PutByIdStatus::computeFor(VM& vm, JSGlobalObject* globalObject, Structure* structure, Identifier& ident, bool isDirect)
{
if (PropertyName(ident).asIndex() != PropertyName::NotAnIndex)
return PutByIdStatus(TakesSlowPath);
@@ -147,11 +151,16 @@ PutByIdStatus PutByIdStatus::computeFor(JSGlobalData& globalData, JSGlobalObject
return PutByIdStatus(TakesSlowPath);
unsigned attributes;
- JSCell* specificValueIgnored;
- PropertyOffset offset = structure->get(globalData, ident, attributes, specificValueIgnored);
+ JSCell* specificValue;
+ PropertyOffset offset = structure->get(vm, ident, attributes, specificValue);
if (isValidOffset(offset)) {
if (attributes & (Accessor | ReadOnly))
return PutByIdStatus(TakesSlowPath);
+ if (specificValue) {
+ // We need the PutById slow path to verify that we're storing the right value into
+ // the specialized slot.
+ return PutByIdStatus(TakesSlowPath);
+ }
return PutByIdStatus(SimpleReplace, structure, 0, 0, offset);
}
@@ -169,7 +178,7 @@ PutByIdStatus PutByIdStatus::computeFor(JSGlobalData& globalData, JSGlobalObject
if (!isDirect) {
// If the prototype chain has setters or read-only properties, then give up.
- if (structure->prototypeChainMayInterceptStoreTo(globalData, ident))
+ if (structure->prototypeChainMayInterceptStoreTo(vm, ident))
return PutByIdStatus(TakesSlowPath);
// If the prototype chain hasn't been normalized (i.e. there are proxies or dictionaries)
@@ -204,7 +213,7 @@ PutByIdStatus PutByIdStatus::computeFor(JSGlobalData& globalData, JSGlobalObject
return PutByIdStatus(
SimpleTransition, structure, transition,
- structure->prototypeChain(globalData, globalObject), offset);
+ structure->prototypeChain(vm, globalObject), offset);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/PutByIdStatus.h b/Source/JavaScriptCore/bytecode/PutByIdStatus.h
index fe22009fe..659e629d2 100644
--- a/Source/JavaScriptCore/bytecode/PutByIdStatus.h
+++ b/Source/JavaScriptCore/bytecode/PutByIdStatus.h
@@ -33,7 +33,7 @@ namespace JSC {
class CodeBlock;
class Identifier;
-class JSGlobalData;
+class VM;
class JSGlobalObject;
class Structure;
class StructureChain;
@@ -91,7 +91,7 @@ public:
}
static PutByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&);
- static PutByIdStatus computeFor(JSGlobalData&, JSGlobalObject*, Structure*, Identifier&, bool isDirect);
+ static PutByIdStatus computeFor(VM&, JSGlobalObject*, Structure*, Identifier&, bool isDirect);
State state() const { return m_state; }
diff --git a/Source/JavaScriptCore/bytecode/ReduceWhitespace.cpp b/Source/JavaScriptCore/bytecode/ReduceWhitespace.cpp
new file mode 100644
index 000000000..1636cba1d
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ReduceWhitespace.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "ReduceWhitespace.h"
+
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+String reduceWhitespace(const String& input)
+{
+ StringBuilder builder;
+
+ for (unsigned i = 0; i < input.length();) {
+ if (isASCIISpace(input[i])) {
+ while (i < input.length() && isASCIISpace(input[i]))
+ ++i;
+ builder.append(' ');
+ continue;
+ }
+ builder.append(input[i]);
+ ++i;
+ }
+
+ return builder.toString();
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/ReduceWhitespace.h b/Source/JavaScriptCore/bytecode/ReduceWhitespace.h
new file mode 100644
index 000000000..383dd3798
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ReduceWhitespace.h
@@ -0,0 +1,38 @@
+/*
+ * 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 ReduceWhitespace_h
+#define ReduceWhitespace_h
+
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+// Replace all whitespace runs with a single space.
+String reduceWhitespace(const String&);
+
+} // namespace JSC
+
+#endif // ReduceWhitespace_h
diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
index 7814f8c99..c02acb38d 100644
--- a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
+++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp
@@ -27,7 +27,8 @@
#include "ResolveGlobalStatus.h"
#include "CodeBlock.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
+#include "Operations.h"
#include "Structure.h"
namespace JSC {
@@ -36,7 +37,7 @@ static ResolveGlobalStatus computeForStructure(CodeBlock* codeBlock, Structure*
{
unsigned attributesIgnored;
JSCell* specificValue;
- PropertyOffset offset = structure->get(*codeBlock->globalData(), identifier, attributesIgnored, specificValue);
+ PropertyOffset offset = structure->get(*codeBlock->vm(), identifier, attributesIgnored, specificValue);
if (structure->isDictionary())
specificValue = 0;
if (!isValidOffset(offset))
diff --git a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
index 46a9254e7..6763ff7c8 100644
--- a/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
+++ b/Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h
@@ -26,7 +26,7 @@
#ifndef ResolveGlobalStatus_h
#define ResolveGlobalStatus_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "PropertyOffset.h"
#include <wtf/NotFound.h>
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.cpp b/Source/JavaScriptCore/bytecode/SamplingTool.cpp
index a76fee179..d18dbc1ff 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -297,13 +297,13 @@ void SamplingTool::sample()
s_samplingTool->doRun();
}
-void SamplingTool::notifyOfScope(JSGlobalData& globalData, ScriptExecutable* script)
+void SamplingTool::notifyOfScope(VM& vm, ScriptExecutable* script)
{
#if ENABLE(CODEBLOCK_SAMPLING)
MutexLocker locker(m_scriptSampleMapMutex);
- m_scopeSampleMap->set(script, adoptPtr(new ScriptSampleRecord(globalData, script)));
+ m_scopeSampleMap->set(script, adoptPtr(new ScriptSampleRecord(vm, script)));
#else
- UNUSED_PARAM(globalData);
+ UNUSED_PARAM(vm);
UNUSED_PARAM(script);
#endif
}
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.h b/Source/JavaScriptCore/bytecode/SamplingTool.h
index 6c9df62ee..516968a33 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.h
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,6 @@
#define SamplingTool_h
#include "Strong.h"
-#include "Nodes.h"
#include "Opcode.h"
#include "SamplingCounter.h"
#include <wtf/Assertions.h>
@@ -186,8 +185,8 @@ namespace JSC {
struct Instruction;
struct ScriptSampleRecord {
- ScriptSampleRecord(JSGlobalData& globalData, ScriptExecutable* executable)
- : m_executable(globalData, executable)
+ ScriptSampleRecord(VM& vm, ScriptExecutable* executable)
+ : m_executable(vm, executable)
, m_codeBlock(0)
, m_sampleCount(0)
, m_opcodeSampleCount(0)
@@ -282,7 +281,7 @@ namespace JSC {
JS_EXPORT_PRIVATE void setup();
void dump(ExecState*);
- void notifyOfScope(JSGlobalData&, ScriptExecutable* scope);
+ void notifyOfScope(VM&, ScriptExecutable* scope);
void sample(CodeBlock* codeBlock, Instruction* vPC)
{
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
index a07ca2b22..0e33b650f 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +32,8 @@
#include "Arguments.h"
#include "JSArray.h"
#include "JSFunction.h"
+#include "Operations.h"
+#include "StringObject.h"
#include "ValueProfile.h"
#include <wtf/BoundsCheckedPointer.h>
#include <wtf/StringPrintStream.h>
@@ -119,18 +121,18 @@ void dumpSpeculation(PrintStream& out, SpeculatedType value)
else
isTop = false;
- if (value & SpecMyArguments)
- myOut.print("Myarguments");
+ if (value & SpecArguments)
+ myOut.print("Arguments");
else
isTop = false;
- if (value & SpecForeignArguments)
- myOut.print("Foreignarguments");
+ if (value & SpecString)
+ myOut.print("String");
else
isTop = false;
- if (value & SpecString)
- myOut.print("String");
+ if (value & SpecStringObject)
+ myOut.print("Stringobject");
else
isTop = false;
@@ -196,10 +198,12 @@ static const char* speculationToAbbreviatedString(SpeculatedType prediction)
return "<Float32array>";
if (isFloat64ArraySpeculation(prediction))
return "<Float64array>";
- if (isMyArgumentsSpeculation(prediction))
- return "<Myarguments>";
if (isArgumentsSpeculation(prediction))
return "<Arguments>";
+ if (isStringObjectSpeculation(prediction))
+ return "<StringObject>";
+ if (isStringOrStringObjectSpeculation(prediction))
+ return "<StringOrStringObject>";
if (isObjectSpeculation(prediction))
return "<Object>";
if (isCellSpeculation(prediction))
@@ -231,11 +235,13 @@ SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
return SpecArray;
if (classInfo == &Arguments::s_info)
- return SpecArguments; // Cannot distinguish between MyArguments and ForeignArguments at this stage. That happens in the flow analysis.
+ return SpecArguments;
+
+ if (classInfo == &StringObject::s_info)
+ return SpecStringObject;
if (classInfo->isSubClassOf(&JSFunction::s_info))
return SpecFunction;
-
if (classInfo->typedArrayStorageType != TypedArrayNone) {
switch (classInfo->typedArrayStorageType) {
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h
index 261a26b0e..05788f0f1 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.h
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,7 +29,8 @@
#ifndef SpeculatedType_h
#define SpeculatedType_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
+#include <wtf/PrintStream.h>
namespace JSC {
@@ -49,11 +50,10 @@ static const SpeculatedType SpecUint16Array = 0x00000200; // It's definite
static const SpeculatedType SpecUint32Array = 0x00000400; // It's definitely an Uint32Array or one of its subclasses.
static const SpeculatedType SpecFloat32Array = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
static const SpeculatedType SpecFloat64Array = 0x00001000; // It's definitely an Uint16Array or one of its subclasses.
-static const SpeculatedType SpecMyArguments = 0x00002000; // It's definitely an Arguments object, and it's definitely the one for my current frame.
-static const SpeculatedType SpecForeignArguments = 0x00004000; // It's definitely an Arguments object, and it's definitely not mine.
-static const SpeculatedType SpecArguments = 0x00006000; // It's definitely an Arguments object.
+static const SpeculatedType SpecArguments = 0x00002000; // It's definitely an Arguments object.
+static const SpeculatedType SpecStringObject = 0x00004000; // It's definitely a StringObject.
static const SpeculatedType SpecObjectOther = 0x00008000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
-static const SpeculatedType SpecObjectMask = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
+static const SpeculatedType SpecObject = 0x0000ffff; // Bitmask used for testing for any kind of object prediction.
static const SpeculatedType SpecString = 0x00010000; // It's definitely a JSString.
static const SpeculatedType SpecCellOther = 0x00020000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
static const SpeculatedType SpecCell = 0x0003ffff; // It's definitely a JSCell.
@@ -83,19 +83,14 @@ inline bool isCellSpeculation(SpeculatedType value)
return !!(value & SpecCell) && !(value & ~SpecCell);
}
-inline bool isNonStringCellSpeculation(SpeculatedType value)
-{
- return !!(value & (SpecCell & ~SpecString)) && !(value & ~(SpecCell & ~SpecString));
-}
-
-inline bool isNonStringCellOrOtherSpeculation(SpeculatedType value)
+inline bool isObjectSpeculation(SpeculatedType value)
{
- return !!(value & ((SpecCell & ~SpecString) | SpecOther)) && !(value & ~((SpecCell & ~SpecString) | SpecOther));
+ return !!(value & SpecObject) && !(value & ~SpecObject);
}
-inline bool isObjectSpeculation(SpeculatedType value)
+inline bool isObjectOrOtherSpeculation(SpeculatedType value)
{
- return !!(value & SpecObjectMask) && !(value & ~SpecObjectMask);
+ return !!(value & (SpecObject | SpecOther)) && !(value & ~(SpecObject | SpecOther));
}
inline bool isFinalObjectSpeculation(SpeculatedType value)
@@ -219,9 +214,14 @@ inline bool isArrayOrOtherSpeculation(SpeculatedType value)
return !!(value & (SpecArray | SpecOther)) && !(value & ~(SpecArray | SpecOther));
}
-inline bool isMyArgumentsSpeculation(SpeculatedType value)
+inline bool isStringObjectSpeculation(SpeculatedType value)
+{
+ return value == SpecStringObject;
+}
+
+inline bool isStringOrStringObjectSpeculation(SpeculatedType value)
{
- return value == SpecMyArguments;
+ return !!value && !(value & ~(SpecString | SpecStringObject));
}
inline bool isInt32Speculation(SpeculatedType value)
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
index 9238fefdc..70cf2fccb 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -63,7 +63,7 @@ void StructureStubInfo::deref()
// These instructions don't have to release any allocated memory
return;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
index 445ffe6c6..f5c39357c 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -36,282 +36,285 @@
#include "JITStubRoutine.h"
#include "MacroAssembler.h"
#include "Opcode.h"
+#include "PolymorphicAccessStructureList.h"
#include "Structure.h"
#include "StructureStubClearingWatchpoint.h"
#include <wtf/OwnPtr.h>
namespace JSC {
- class PolymorphicPutByIdList;
-
- enum AccessType {
- access_get_by_id_self,
- access_get_by_id_proto,
- access_get_by_id_chain,
- access_get_by_id_self_list,
- access_get_by_id_proto_list,
- access_put_by_id_transition_normal,
- access_put_by_id_transition_direct,
- access_put_by_id_replace,
- access_put_by_id_list,
- access_unset,
- access_get_by_id_generic,
- access_put_by_id_generic,
- access_get_array_length,
- access_get_string_length,
- };
-
- inline bool isGetByIdAccess(AccessType accessType)
- {
- switch (accessType) {
- case access_get_by_id_self:
- case access_get_by_id_proto:
- case access_get_by_id_chain:
- case access_get_by_id_self_list:
- case access_get_by_id_proto_list:
- case access_get_by_id_generic:
- case access_get_array_length:
- case access_get_string_length:
- return true;
- default:
- return false;
- }
+class PolymorphicPutByIdList;
+
+enum AccessType {
+ access_get_by_id_self,
+ access_get_by_id_proto,
+ access_get_by_id_chain,
+ access_get_by_id_self_list,
+ access_get_by_id_proto_list,
+ access_put_by_id_transition_normal,
+ access_put_by_id_transition_direct,
+ access_put_by_id_replace,
+ access_put_by_id_list,
+ access_unset,
+ access_get_by_id_generic,
+ access_put_by_id_generic,
+ access_get_array_length,
+ access_get_string_length,
+};
+
+inline bool isGetByIdAccess(AccessType accessType)
+{
+ switch (accessType) {
+ case access_get_by_id_self:
+ case access_get_by_id_proto:
+ case access_get_by_id_chain:
+ case access_get_by_id_self_list:
+ case access_get_by_id_proto_list:
+ case access_get_by_id_generic:
+ case access_get_array_length:
+ case access_get_string_length:
+ return true;
+ default:
+ return false;
}
+}
- inline bool isPutByIdAccess(AccessType accessType)
+inline bool isPutByIdAccess(AccessType accessType)
+{
+ switch (accessType) {
+ case access_put_by_id_transition_normal:
+ case access_put_by_id_transition_direct:
+ case access_put_by_id_replace:
+ case access_put_by_id_list:
+ case access_put_by_id_generic:
+ return true;
+ default:
+ return false;
+ }
+}
+
+struct StructureStubInfo {
+ StructureStubInfo()
+ : accessType(access_unset)
+ , seen(false)
+ , resetByGC(false)
+ {
+ }
+
+ void initGetByIdSelf(VM& vm, JSCell* owner, Structure* baseObjectStructure)
{
- switch (accessType) {
- case access_put_by_id_transition_normal:
- case access_put_by_id_transition_direct:
- case access_put_by_id_replace:
- case access_put_by_id_list:
- case access_put_by_id_generic:
- return true;
- default:
- return false;
- }
+ accessType = access_get_by_id_self;
+
+ u.getByIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
+ }
+
+ void initGetByIdProto(VM& vm, JSCell* owner, Structure* baseObjectStructure, Structure* prototypeStructure, bool isDirect)
+ {
+ accessType = access_get_by_id_proto;
+
+ u.getByIdProto.baseObjectStructure.set(vm, owner, baseObjectStructure);
+ u.getByIdProto.prototypeStructure.set(vm, owner, prototypeStructure);
+ u.getByIdProto.isDirect = isDirect;
+ }
+
+ void initGetByIdChain(VM& vm, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain, unsigned count, bool isDirect)
+ {
+ accessType = access_get_by_id_chain;
+
+ u.getByIdChain.baseObjectStructure.set(vm, owner, baseObjectStructure);
+ u.getByIdChain.chain.set(vm, owner, chain);
+ u.getByIdChain.count = count;
+ u.getByIdChain.isDirect = isDirect;
+ }
+
+ void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
+ {
+ accessType = access_get_by_id_self_list;
+
+ u.getByIdSelfList.structureList = structureList;
+ u.getByIdSelfList.listSize = listSize;
+ }
+
+ void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
+ {
+ accessType = access_get_by_id_proto_list;
+
+ u.getByIdProtoList.structureList = structureList;
+ u.getByIdProtoList.listSize = listSize;
}
- struct StructureStubInfo {
- StructureStubInfo()
- : accessType(access_unset)
- , seen(false)
- {
- }
-
- void initGetByIdSelf(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure)
- {
- accessType = access_get_by_id_self;
-
- u.getByIdSelf.baseObjectStructure.set(globalData, owner, baseObjectStructure);
- }
-
- void initGetByIdProto(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure, Structure* prototypeStructure, bool isDirect)
- {
- accessType = access_get_by_id_proto;
-
- u.getByIdProto.baseObjectStructure.set(globalData, owner, baseObjectStructure);
- u.getByIdProto.prototypeStructure.set(globalData, owner, prototypeStructure);
- u.getByIdProto.isDirect = isDirect;
- }
-
- void initGetByIdChain(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain, unsigned count, bool isDirect)
- {
- accessType = access_get_by_id_chain;
-
- u.getByIdChain.baseObjectStructure.set(globalData, owner, baseObjectStructure);
- u.getByIdChain.chain.set(globalData, owner, chain);
- u.getByIdChain.count = count;
- u.getByIdChain.isDirect = isDirect;
- }
-
- void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
- {
- accessType = access_get_by_id_self_list;
-
- u.getByIdSelfList.structureList = structureList;
- u.getByIdSelfList.listSize = listSize;
- }
-
- void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
- {
- accessType = access_get_by_id_proto_list;
-
- u.getByIdProtoList.structureList = structureList;
- u.getByIdProtoList.listSize = listSize;
- }
-
- // PutById*
-
- void initPutByIdTransition(JSGlobalData& globalData, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain, bool isDirect)
- {
- if (isDirect)
- accessType = access_put_by_id_transition_direct;
- else
- accessType = access_put_by_id_transition_normal;
-
- u.putByIdTransition.previousStructure.set(globalData, owner, previousStructure);
- u.putByIdTransition.structure.set(globalData, owner, structure);
- u.putByIdTransition.chain.set(globalData, owner, chain);
- }
-
- void initPutByIdReplace(JSGlobalData& globalData, JSCell* owner, Structure* baseObjectStructure)
- {
- accessType = access_put_by_id_replace;
+ // PutById*
+
+ void initPutByIdTransition(VM& vm, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain, bool isDirect)
+ {
+ if (isDirect)
+ accessType = access_put_by_id_transition_direct;
+ else
+ accessType = access_put_by_id_transition_normal;
+
+ u.putByIdTransition.previousStructure.set(vm, owner, previousStructure);
+ u.putByIdTransition.structure.set(vm, owner, structure);
+ u.putByIdTransition.chain.set(vm, owner, chain);
+ }
+
+ void initPutByIdReplace(VM& vm, JSCell* owner, Structure* baseObjectStructure)
+ {
+ accessType = access_put_by_id_replace;
- u.putByIdReplace.baseObjectStructure.set(globalData, owner, baseObjectStructure);
- }
+ u.putByIdReplace.baseObjectStructure.set(vm, owner, baseObjectStructure);
+ }
- void initPutByIdList(PolymorphicPutByIdList* list)
- {
- accessType = access_put_by_id_list;
- u.putByIdList.list = list;
- }
+ void initPutByIdList(PolymorphicPutByIdList* list)
+ {
+ accessType = access_put_by_id_list;
+ u.putByIdList.list = list;
+ }
- void reset()
- {
- deref();
- accessType = access_unset;
- stubRoutine.clear();
- watchpoints.clear();
- }
+ void reset()
+ {
+ deref();
+ accessType = access_unset;
+ stubRoutine.clear();
+ watchpoints.clear();
+ }
- void deref();
+ void deref();
- bool visitWeakReferences();
+ bool visitWeakReferences();
- bool seenOnce()
- {
- return seen;
- }
-
- void setSeen()
- {
- seen = true;
- }
+ bool seenOnce()
+ {
+ return seen;
+ }
+
+ void setSeen()
+ {
+ seen = true;
+ }
- StructureStubClearingWatchpoint* addWatchpoint(CodeBlock* codeBlock)
- {
- return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
- watchpoints, codeBlock, this);
- }
+ StructureStubClearingWatchpoint* addWatchpoint(CodeBlock* codeBlock)
+ {
+ return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
+ watchpoints, codeBlock, this);
+ }
- unsigned bytecodeIndex;
+ unsigned bytecodeIndex;
- int8_t accessType;
- int8_t seen;
+ int8_t accessType;
+ bool seen : 1;
+ bool resetByGC : 1;
#if ENABLE(DFG_JIT)
- CodeOrigin codeOrigin;
+ CodeOrigin codeOrigin;
#endif // ENABLE(DFG_JIT)
- union {
- struct {
- int8_t registersFlushed;
- int8_t baseGPR;
+ union {
+ struct {
+ int8_t registersFlushed;
+ int8_t baseGPR;
#if USE(JSVALUE32_64)
- int8_t valueTagGPR;
+ int8_t valueTagGPR;
#endif
- int8_t valueGPR;
- DFG::RegisterSetPOD usedRegisters;
- int32_t deltaCallToDone;
- int32_t deltaCallToStorageLoad;
- int32_t deltaCallToStructCheck;
- int32_t deltaCallToSlowCase;
- int32_t deltaCheckImmToCall;
+ int8_t valueGPR;
+ DFG::RegisterSetPOD usedRegisters;
+ int32_t deltaCallToDone;
+ int32_t deltaCallToStorageLoad;
+ int32_t deltaCallToStructCheck;
+ int32_t deltaCallToSlowCase;
+ int32_t deltaCheckImmToCall;
#if USE(JSVALUE64)
- int32_t deltaCallToLoadOrStore;
+ int32_t deltaCallToLoadOrStore;
#else
- int32_t deltaCallToTagLoadOrStore;
- int32_t deltaCallToPayloadLoadOrStore;
+ int32_t deltaCallToTagLoadOrStore;
+ int32_t deltaCallToPayloadLoadOrStore;
#endif
- } dfg;
- struct {
- union {
- struct {
- int16_t structureToCompare;
- int16_t structureCheck;
- int16_t propertyStorageLoad;
+ } dfg;
+ struct {
+ union {
+ struct {
+ int16_t structureToCompare;
+ int16_t structureCheck;
+ int16_t propertyStorageLoad;
#if USE(JSVALUE64)
- int16_t displacementLabel;
+ int16_t displacementLabel;
#else
- int16_t displacementLabel1;
- int16_t displacementLabel2;
+ int16_t displacementLabel1;
+ int16_t displacementLabel2;
#endif
- int16_t putResult;
- int16_t coldPathBegin;
- } get;
- struct {
- int16_t structureToCompare;
- int16_t propertyStorageLoad;
+ int16_t putResult;
+ int16_t coldPathBegin;
+ } get;
+ struct {
+ int16_t structureToCompare;
+ int16_t propertyStorageLoad;
#if USE(JSVALUE64)
- int16_t displacementLabel;
+ int16_t displacementLabel;
#else
- int16_t displacementLabel1;
- int16_t displacementLabel2;
+ int16_t displacementLabel1;
+ int16_t displacementLabel2;
#endif
- } put;
- } u;
- int16_t methodCheckProtoObj;
- int16_t methodCheckProtoStructureToCompare;
- int16_t methodCheckPutFunction;
- } baseline;
- } patch;
-
- union {
- struct {
- // It would be unwise to put anything here, as it will surely be overwritten.
- } unset;
- struct {
- WriteBarrierBase<Structure> baseObjectStructure;
- } getByIdSelf;
- struct {
- WriteBarrierBase<Structure> baseObjectStructure;
- WriteBarrierBase<Structure> prototypeStructure;
- bool isDirect;
- } getByIdProto;
- struct {
- WriteBarrierBase<Structure> baseObjectStructure;
- WriteBarrierBase<StructureChain> chain;
- unsigned count : 31;
- bool isDirect : 1;
- } getByIdChain;
- struct {
- PolymorphicAccessStructureList* structureList;
- int listSize;
- } getByIdSelfList;
- struct {
- PolymorphicAccessStructureList* structureList;
- int listSize;
- } getByIdProtoList;
- struct {
- WriteBarrierBase<Structure> previousStructure;
- WriteBarrierBase<Structure> structure;
- WriteBarrierBase<StructureChain> chain;
- } putByIdTransition;
- struct {
- WriteBarrierBase<Structure> baseObjectStructure;
- } putByIdReplace;
- struct {
- PolymorphicPutByIdList* list;
- } putByIdList;
- } u;
-
- RefPtr<JITStubRoutine> stubRoutine;
- CodeLocationCall callReturnLocation;
- CodeLocationLabel hotPathBegin;
- RefPtr<WatchpointsOnStructureStubInfo> watchpoints;
- };
-
- inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
- {
- return structureStubInfo->callReturnLocation.executableAddress();
- }
-
- inline unsigned getStructureStubInfoBytecodeIndex(StructureStubInfo* structureStubInfo)
- {
- return structureStubInfo->bytecodeIndex;
- }
+ } put;
+ } u;
+ int16_t methodCheckProtoObj;
+ int16_t methodCheckProtoStructureToCompare;
+ int16_t methodCheckPutFunction;
+ } baseline;
+ } patch;
+
+ union {
+ struct {
+ // It would be unwise to put anything here, as it will surely be overwritten.
+ } unset;
+ struct {
+ WriteBarrierBase<Structure> baseObjectStructure;
+ } getByIdSelf;
+ struct {
+ WriteBarrierBase<Structure> baseObjectStructure;
+ WriteBarrierBase<Structure> prototypeStructure;
+ bool isDirect;
+ } getByIdProto;
+ struct {
+ WriteBarrierBase<Structure> baseObjectStructure;
+ WriteBarrierBase<StructureChain> chain;
+ unsigned count : 31;
+ bool isDirect : 1;
+ } getByIdChain;
+ struct {
+ PolymorphicAccessStructureList* structureList;
+ int listSize;
+ } getByIdSelfList;
+ struct {
+ PolymorphicAccessStructureList* structureList;
+ int listSize;
+ } getByIdProtoList;
+ struct {
+ WriteBarrierBase<Structure> previousStructure;
+ WriteBarrierBase<Structure> structure;
+ WriteBarrierBase<StructureChain> chain;
+ } putByIdTransition;
+ struct {
+ WriteBarrierBase<Structure> baseObjectStructure;
+ } putByIdReplace;
+ struct {
+ PolymorphicPutByIdList* list;
+ } putByIdList;
+ } u;
+
+ RefPtr<JITStubRoutine> stubRoutine;
+ CodeLocationCall callReturnLocation;
+ CodeLocationLabel hotPathBegin;
+ RefPtr<WatchpointsOnStructureStubInfo> watchpoints;
+};
+
+inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
+{
+ return structureStubInfo->callReturnLocation.executableAddress();
+}
+
+inline unsigned getStructureStubInfoBytecodeIndex(StructureStubInfo* structureStubInfo)
+{
+ return structureStubInfo->bytecodeIndex;
+}
} // namespace JSC
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
index e98d4de0a..8aba1ff8b 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,6 +32,8 @@
#include "CodeCache.h"
#include "Executable.h"
#include "JSString.h"
+#include "Operations.h"
+#include "Parser.h"
#include "SourceProvider.h"
#include "Structure.h"
#include "SymbolTable.h"
@@ -45,6 +47,29 @@ const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock",
const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) };
const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) };
+static UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(VM& vm, JSScope* scope, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+{
+ RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&vm, source, executable->parameters(), executable->name(), executable->isInStrictContext() ? JSParseStrict : JSParseNormal, JSParseFunctionCode, error);
+
+ if (!body) {
+ ASSERT(error.m_type != ParserError::ErrorNone);
+ return 0;
+ }
+
+ if (executable->forceUsesArguments())
+ body->setUsesArguments();
+ body->finishParsing(executable->parameters(), executable->name(), executable->functionNameIsInScopeToggle());
+ executable->recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
+
+ UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, scope, body.get(), result, debuggerMode, profilerMode)));
+ error = generator->generate();
+ body->destroyData();
+ if (error.m_type != ParserError::ErrorNone)
+ return 0;
+ return result;
+}
+
unsigned UnlinkedCodeBlock::addOrFindConstant(JSValue v)
{
unsigned numberOfConstants = numberOfConstantRegisters();
@@ -55,8 +80,8 @@ unsigned UnlinkedCodeBlock::addOrFindConstant(JSValue v)
return addConstant(v);
}
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(JSGlobalData* globalData, Structure* structure, const SourceCode& source, FunctionBodyNode* node)
- : Base(*globalData, structure)
+UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, FunctionBodyNode* node)
+ : Base(*vm, structure)
, m_numCapturedVariables(node->capturedVariableCount())
, m_forceUsesArguments(node->usesArguments())
, m_isInStrictContext(node->isStrictMode())
@@ -66,6 +91,8 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(JSGlobalData* globalData,
, m_parameters(node->parameters())
, m_firstLineOffset(node->firstLine() - source.firstLine())
, m_lineCount(node->lastLine() - node->firstLine())
+ , m_functionStartOffset(node->functionStart() - source.startOffset())
+ , m_functionStartColumn(node->startColumn())
, m_startOffset(node->source().startOffset() - source.startOffset())
, m_sourceLength(node->source().length())
, m_features(node->features())
@@ -73,6 +100,11 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(JSGlobalData* globalData,
{
}
+size_t UnlinkedFunctionExecutable::parameterCount() const
+{
+ return m_parameters->size();
+}
+
void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
UnlinkedFunctionExecutable* thisObject = jsCast<UnlinkedFunctionExecutable*>(cell);
@@ -80,24 +112,31 @@ void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visito
COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
Base::visitChildren(thisObject, visitor);
+ visitor.append(&thisObject->m_codeBlockForCall);
+ visitor.append(&thisObject->m_codeBlockForConstruct);
visitor.append(&thisObject->m_nameValue);
visitor.append(&thisObject->m_symbolTableForCall);
visitor.append(&thisObject->m_symbolTableForConstruct);
}
-FunctionExecutable* UnlinkedFunctionExecutable::link(JSGlobalData& globalData, const SourceCode& source, size_t lineOffset, size_t sourceOffset)
+FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& source, size_t lineOffset, size_t sourceOffset)
{
unsigned firstLine = lineOffset + m_firstLineOffset;
unsigned startOffset = sourceOffset + m_startOffset;
- SourceCode code(source.provider(), startOffset, startOffset + m_sourceLength, firstLine);
- return FunctionExecutable::create(globalData, code, this, firstLine, firstLine + m_lineCount);
+ unsigned startColumn = m_functionStartColumn + 1; // startColumn should start from 1, not 0.
+ SourceCode code(source.provider(), startOffset, startOffset + m_sourceLength, firstLine, startColumn);
+ return FunctionExecutable::create(vm, code, this, firstLine, firstLine + m_lineCount, startColumn);
}
UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger*, const SourceCode& source, JSObject** exception)
{
ParserError error;
- CodeCache* codeCache = exec->globalData().codeCache();
- UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(exec->globalData(), name, source, error);
+ CodeCache* codeCache = exec->vm().codeCache();
+ UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(exec->vm(), name, source, error);
+
+ if (exec->lexicalGlobalObject()->hasDebugger())
+ exec->lexicalGlobalObject()->debugger()->sourceParsed(exec, source.provider(), error.m_line, error.m_message);
+
if (error.m_type != ParserError::ErrorNone) {
*exception = error.toErrorObject(exec->lexicalGlobalObject(), source);
return 0;
@@ -106,36 +145,32 @@ UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(const Ide
return executable;
}
-UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(JSGlobalData& globalData, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(VM& vm, JSScope* scope, const SourceCode& source, CodeSpecializationKind specializationKind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
{
switch (specializationKind) {
case CodeForCall:
- if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get()) {
- globalData.codeCache()->usedFunctionCode(globalData, codeBlock);
+ if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get())
return codeBlock;
- }
break;
case CodeForConstruct:
- if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get()) {
- globalData.codeCache()->usedFunctionCode(globalData, codeBlock);
+ if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get())
return codeBlock;
- }
break;
}
- UnlinkedFunctionCodeBlock* result = globalData.codeCache()->getFunctionCodeBlock(globalData, this, source, specializationKind, debuggerMode, profilerMode, error);
+ UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(vm, scope, this, source, specializationKind, debuggerMode, profilerMode, error);
if (error.m_type != ParserError::ErrorNone)
return 0;
switch (specializationKind) {
case CodeForCall:
- m_codeBlockForCall = PassWeak<UnlinkedFunctionCodeBlock>(result);
- m_symbolTableForCall.set(globalData, this, result->symbolTable());
+ m_codeBlockForCall.set(vm, this, result);
+ m_symbolTableForCall.set(vm, this, result->symbolTable());
break;
case CodeForConstruct:
- m_codeBlockForConstruct = PassWeak<UnlinkedFunctionCodeBlock>(result);
- m_symbolTableForConstruct.set(globalData, this, result->symbolTable());
+ m_codeBlockForConstruct.set(vm, this, result);
+ m_symbolTableForConstruct.set(vm, this, result->symbolTable());
break;
}
return result;
@@ -148,18 +183,19 @@ String UnlinkedFunctionExecutable::paramString() const
for (size_t pos = 0; pos < parameters.size(); ++pos) {
if (!builder.isEmpty())
builder.appendLiteral(", ");
- builder.append(parameters[pos].string());
+ builder.append(parameters.at(pos).string());
}
return builder.toString();
}
-UnlinkedCodeBlock::UnlinkedCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
- : Base(*globalData, structure)
+UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
+ : Base(*vm, structure)
, m_numVars(0)
, m_numCalleeRegisters(0)
, m_numParameters(0)
- , m_globalData(globalData)
+ , m_vm(vm)
, m_argumentsRegister(-1)
+ , m_globalObjectRegister(-1)
, m_needsFullScopeChain(info.m_needsActivation)
, m_usesEval(info.m_usesEval)
, m_isNumericCompareFunction(false)
@@ -174,6 +210,7 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(JSGlobalData* globalData, Structure* struct
, m_putToBaseOperationCount(1)
, m_arrayProfileCount(0)
, m_arrayAllocationProfileCount(0)
+ , m_objectAllocationProfileCount(0)
, m_valueProfileCount(0)
, m_llintCallLinkInfoCount(0)
#if ENABLE(BYTECODE_COMMENTS)
@@ -205,24 +242,17 @@ void UnlinkedCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
int UnlinkedCodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
{
ASSERT(bytecodeOffset < instructions().size());
- Vector<LineInfo>& lineInfo = m_lineInfo;
-
- int low = 0;
- int high = lineInfo.size();
- while (low < high) {
- int mid = low + (high - low) / 2;
- if (lineInfo[mid].instructionOffset <= bytecodeOffset)
- low = mid + 1;
- else
- high = mid;
- }
-
- if (!low)
- return 0;
- return lineInfo[low - 1].lineNumber;
+ int divot;
+ int startOffset;
+ int endOffset;
+ unsigned line;
+ unsigned column;
+ expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
+ return line;
}
-void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
+void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset,
+ int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
{
ASSERT(bytecodeOffset < instructions().size());
@@ -230,6 +260,8 @@ void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset
startOffset = 0;
endOffset = 0;
divot = 0;
+ line = 0;
+ column = 0;
return;
}
@@ -245,17 +277,83 @@ void UnlinkedCodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset
high = mid;
}
- ASSERT(low);
- if (!low) {
+ if (!low)
+ low = 1;
+
+ ExpressionRangeInfo& info = expressionInfo[low - 1];
+ startOffset = info.startOffset;
+ endOffset = info.endOffset;
+ divot = info.divotPoint;
+
+ switch (info.mode) {
+ case ExpressionRangeInfo::FatLineMode:
+ info.decodeFatLineMode(line, column);
+ break;
+ case ExpressionRangeInfo::FatColumnMode:
+ info.decodeFatColumnMode(line, column);
+ break;
+ case ExpressionRangeInfo::FatLineAndColumnMode: {
+ unsigned fatIndex = info.position;
+ ExpressionRangeInfo::FatPosition& fatPos = m_rareData->m_expressionInfoFatPositions[fatIndex];
+ line = fatPos.line;
+ column = fatPos.column;
+ break;
+ }
+ } // switch
+}
+
+void UnlinkedCodeBlock::addExpressionInfo(unsigned instructionOffset,
+ int divot, int startOffset, int endOffset, unsigned line, unsigned column)
+{
+ if (divot > ExpressionRangeInfo::MaxDivot) {
+ // Overflow has occurred, we can only give line number info for errors for this region
+ divot = 0;
startOffset = 0;
endOffset = 0;
- divot = 0;
- return;
+ } else if (startOffset > ExpressionRangeInfo::MaxOffset) {
+ // If the start offset is out of bounds we clear both offsets
+ // so we only get the divot marker. Error message will have to be reduced
+ // to line and charPosition number.
+ startOffset = 0;
+ endOffset = 0;
+ } else if (endOffset > ExpressionRangeInfo::MaxOffset) {
+ // The end offset is only used for additional context, and is much more likely
+ // to overflow (eg. function call arguments) so we are willing to drop it without
+ // dropping the rest of the range.
+ endOffset = 0;
+ }
+
+ unsigned positionMode =
+ (line <= ExpressionRangeInfo::MaxFatLineModeLine && column <= ExpressionRangeInfo::MaxFatLineModeColumn)
+ ? ExpressionRangeInfo::FatLineMode
+ : (line <= ExpressionRangeInfo::MaxFatColumnModeLine && column <= ExpressionRangeInfo::MaxFatColumnModeColumn)
+ ? ExpressionRangeInfo::FatColumnMode
+ : ExpressionRangeInfo::FatLineAndColumnMode;
+
+ ExpressionRangeInfo info;
+ info.instructionOffset = instructionOffset;
+ info.divotPoint = divot;
+ info.startOffset = startOffset;
+ info.endOffset = endOffset;
+
+ info.mode = positionMode;
+ switch (positionMode) {
+ case ExpressionRangeInfo::FatLineMode:
+ info.encodeFatLineMode(line, column);
+ break;
+ case ExpressionRangeInfo::FatColumnMode:
+ info.encodeFatColumnMode(line, column);
+ break;
+ case ExpressionRangeInfo::FatLineAndColumnMode: {
+ createRareDataIfNecessary();
+ unsigned fatIndex = m_rareData->m_expressionInfoFatPositions.size();
+ ExpressionRangeInfo::FatPosition fatPos = { line, column };
+ m_rareData->m_expressionInfoFatPositions.append(fatPos);
+ info.position = fatIndex;
}
+ } // switch
- startOffset = expressionInfo[low - 1].startOffset;
- endOffset = expressionInfo[low - 1].endOffset;
- divot = expressionInfo[low - 1].divotPoint;
+ m_expressionInfo.append(info);
}
void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
index 23937d773..634968313 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,16 +27,18 @@
#define UnlinkedCodeBlock_h
#include "BytecodeConventions.h"
+#include "CodeCache.h"
#include "CodeSpecializationKind.h"
#include "CodeType.h"
#include "ExpressionRangeInfo.h"
#include "Identifier.h"
#include "JSCell.h"
+#include "JSString.h"
#include "LineInfo.h"
-#include "Nodes.h"
+#include "ParserModes.h"
#include "RegExp.h"
#include "SpecialPointer.h"
-#include "Weak.h"
+#include "SymbolTable.h"
#include <wtf/RefCountedArray.h>
#include <wtf/Vector.h>
@@ -47,6 +49,7 @@ class Debugger;
class FunctionBodyNode;
class FunctionExecutable;
class FunctionParameters;
+class JSScope;
struct ParserError;
class ScriptExecutable;
class SourceCode;
@@ -58,6 +61,7 @@ class UnlinkedFunctionCodeBlock;
typedef unsigned UnlinkedValueProfile;
typedef unsigned UnlinkedArrayProfile;
typedef unsigned UnlinkedArrayAllocationProfile;
+typedef unsigned UnlinkedObjectAllocationProfile;
typedef unsigned UnlinkedLLIntCallLinkInfo;
struct ExecutableInfo {
@@ -78,10 +82,10 @@ class UnlinkedFunctionExecutable : public JSCell {
public:
friend class CodeCache;
typedef JSCell Base;
- static UnlinkedFunctionExecutable* create(JSGlobalData* globalData, const SourceCode& source, FunctionBodyNode* node)
+ static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node)
{
- UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(globalData->heap)) UnlinkedFunctionExecutable(globalData, globalData->unlinkedFunctionExecutableStructure.get(), source, node);
- instance->finishCreation(*globalData);
+ UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node);
+ instance->finishCreation(*vm);
return instance;
}
@@ -92,22 +96,24 @@ public:
{
return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
}
- size_t parameterCount() const { return m_parameters->size(); }
+ size_t parameterCount() const;
bool isInStrictContext() const { return m_isInStrictContext; }
FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; }
unsigned firstLineOffset() const { return m_firstLineOffset; }
unsigned lineCount() const { return m_lineCount; }
+ unsigned functionStartOffset() const { return m_functionStartOffset; }
+ unsigned functionStartColumn() const { return m_functionStartColumn; }
unsigned startOffset() const { return m_startOffset; }
unsigned sourceLength() { return m_sourceLength; }
String paramString() const;
- UnlinkedFunctionCodeBlock* codeBlockFor(JSGlobalData&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
+ UnlinkedFunctionCodeBlock* codeBlockFor(VM&, JSScope*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
- FunctionExecutable* link(JSGlobalData&, const SourceCode&, size_t lineOffset, size_t sourceOffset);
+ FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset, size_t sourceOffset);
void clearCodeForRecompilation()
{
@@ -136,9 +142,9 @@ public:
static void destroy(JSCell*);
private:
- UnlinkedFunctionExecutable(JSGlobalData*, Structure*, const SourceCode&, FunctionBodyNode*);
- Weak<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
- Weak<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
+ UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*);
+ WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
+ WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
unsigned m_numCapturedVariables : 29;
bool m_forceUsesArguments : 1;
@@ -153,6 +159,8 @@ private:
RefPtr<FunctionParameters> m_parameters;
unsigned m_firstLineOffset;
unsigned m_lineCount;
+ unsigned m_functionStartOffset;
+ unsigned m_functionStartColumn;
unsigned m_startOffset;
unsigned m_sourceLength;
@@ -161,18 +169,18 @@ private:
FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
protected:
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
- m_nameValue.set(globalData, this, jsString(&globalData, name().string()));
+ Base::finishCreation(vm);
+ m_nameValue.set(vm, this, jsString(&vm, name().string()));
}
static void visitChildren(JSCell*, SlotVisitor&);
public:
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), &s_info);
}
static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
@@ -239,19 +247,8 @@ public:
bool needsFullScopeChain() const { return m_needsFullScopeChain; }
void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
- void addExpressionInfo(const ExpressionRangeInfo& expressionInfo)
- {
- m_expressionInfo.append(expressionInfo);
- }
-
- void addLineInfo(unsigned bytecodeOffset, int lineNo)
- {
- Vector<LineInfo>& lineInfo = m_lineInfo;
- if (!lineInfo.size() || lineInfo.last().lineNumber != lineNo) {
- LineInfo info = { bytecodeOffset, lineNo };
- lineInfo.append(info);
- }
- }
+ void addExpressionInfo(unsigned instructionOffset, int divot,
+ int startOffset, int endOffset, unsigned line, unsigned column);
bool hasExpressionInfo() { return m_expressionInfo.size(); }
@@ -263,6 +260,11 @@ public:
bool usesArguments() const { return m_argumentsRegister != -1; }
int argumentsRegister() const { return m_argumentsRegister; }
+
+ bool usesGlobalObject() const { return m_globalObjectRegister != -1; }
+ void setGlobalObjectRegister(int globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
+ int globalObjectRegister() const { return m_globalObjectRegister; }
+
// Parameter information
void setNumParameters(int newValue) { m_numParameters = newValue; }
void addParameter() { m_numParameters++; }
@@ -272,7 +274,7 @@ public:
{
createRareDataIfNecessary();
unsigned size = m_rareData->m_regexps.size();
- m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_globalData, this, r));
+ m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r));
return size;
}
unsigned numberOfRegExps() const
@@ -295,7 +297,7 @@ public:
{
unsigned result = m_constantRegisters.size();
m_constantRegisters.append(WriteBarrier<Unknown>());
- m_constantRegisters.last().set(*m_globalData, this, v);
+ m_constantRegisters.last().set(*m_vm, this, v);
return result;
}
unsigned addOrFindConstant(JSValue);
@@ -320,7 +322,6 @@ public:
m_constantRegisters.shrinkToFit();
m_functionDecls.shrinkToFit();
m_functionExprs.shrinkToFit();
- m_lineInfo.shrinkToFit();
m_propertyAccessInstructions.shrinkToFit();
m_expressionInfo.shrinkToFit();
@@ -334,6 +335,7 @@ public:
m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
m_rareData->m_characterSwitchJumpTables.shrinkToFit();
m_rareData->m_stringSwitchJumpTables.shrinkToFit();
+ m_rareData->m_expressionInfoFatPositions.shrinkToFit();
}
}
@@ -363,7 +365,7 @@ public:
{
unsigned size = m_functionDecls.size();
m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
- m_functionDecls.last().set(*m_globalData, this, n);
+ m_functionDecls.last().set(*m_vm, this, n);
return size;
}
UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
@@ -372,7 +374,7 @@ public:
{
unsigned size = m_functionExprs.size();
m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
- m_functionExprs.last().set(*m_globalData, this, n);
+ m_functionExprs.last().set(*m_vm, this, n);
return size;
}
UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
@@ -385,7 +387,7 @@ public:
SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
- JSGlobalData* globalData() const { return m_globalData; }
+ VM* vm() const { return m_vm; }
unsigned addResolve() { return m_resolveOperationCount++; }
unsigned numberOfResolveOperations() const { return m_resolveOperationCount; }
@@ -396,6 +398,8 @@ public:
unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
+ UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
+ unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
unsigned numberOfValueProfiles() { return m_valueProfileCount; }
@@ -443,7 +447,8 @@ public:
int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
- void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
+ void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
+ int& startOffset, int& endOffset, unsigned& line, unsigned& column);
void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount)
{
@@ -458,16 +463,26 @@ public:
unsigned firstLine() const { return m_firstLine; }
unsigned lineCount() const { return m_lineCount; }
+ PassRefPtr<CodeCache> codeCacheForEval()
+ {
+ if (m_codeType == GlobalCode)
+ return m_vm->codeCache();
+ createRareDataIfNecessary();
+ if (!m_rareData->m_evalCodeCache)
+ m_rareData->m_evalCodeCache = CodeCache::create(CodeCache::NonGlobalCodeCache);
+ return m_rareData->m_evalCodeCache.get();
+ }
+
protected:
- UnlinkedCodeBlock(JSGlobalData*, Structure*, CodeType, const ExecutableInfo&);
+ UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&);
~UnlinkedCodeBlock();
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
if (codeType() == GlobalCode)
return;
- m_symbolTable.set(globalData, this, SharedSymbolTable::create(globalData));
+ m_symbolTable.set(vm, this, SharedSymbolTable::create(vm));
}
private:
@@ -481,11 +496,12 @@ private:
RefCountedArray<UnlinkedInstruction> m_unlinkedInstructions;
int m_numParameters;
- JSGlobalData* m_globalData;
+ VM* m_vm;
int m_thisRegister;
int m_argumentsRegister;
int m_activationRegister;
+ int m_globalObjectRegister;
bool m_needsFullScopeChain : 1;
bool m_usesEval : 1;
@@ -510,8 +526,6 @@ private:
WriteBarrier<SharedSymbolTable> m_symbolTable;
- Vector<LineInfo> m_lineInfo;
-
Vector<unsigned> m_propertyAccessInstructions;
#if ENABLE(BYTECODE_COMMENTS)
@@ -523,6 +537,7 @@ private:
unsigned m_putToBaseOperationCount;
unsigned m_arrayProfileCount;
unsigned m_arrayAllocationProfileCount;
+ unsigned m_objectAllocationProfileCount;
unsigned m_valueProfileCount;
unsigned m_llintCallLinkInfoCount;
@@ -542,8 +557,9 @@ public:
Vector<UnlinkedSimpleJumpTable> m_immediateSwitchJumpTables;
Vector<UnlinkedSimpleJumpTable> m_characterSwitchJumpTables;
Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
+ RefPtr<CodeCache> m_evalCodeCache;
- // Expression info - present if debugging.
+ Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
};
private:
@@ -564,8 +580,8 @@ public:
typedef UnlinkedCodeBlock Base;
protected:
- UnlinkedGlobalCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
- : Base(globalData, structure, codeType, info)
+ UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
+ : Base(vm, structure, codeType, info)
{
}
@@ -577,10 +593,10 @@ protected:
class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
private:
friend class CodeCache;
- static UnlinkedProgramCodeBlock* create(JSGlobalData* globalData, const ExecutableInfo& info)
+ static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
{
- UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(globalData->heap)) UnlinkedProgramCodeBlock(globalData, globalData->unlinkedProgramCodeBlockStructure.get(), info);
- instance->finishCreation(*globalData);
+ UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info);
+ instance->finishCreation(*vm);
return instance;
}
@@ -588,9 +604,9 @@ public:
typedef UnlinkedGlobalCodeBlock Base;
static void destroy(JSCell*);
- void addFunctionDeclaration(JSGlobalData& globalData, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
+ void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
{
- m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(globalData, this, functionExecutable)));
+ m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
}
void addVariableDeclaration(const Identifier& name, bool isConstant)
@@ -607,8 +623,8 @@ public:
static void visitChildren(JSCell*, SlotVisitor&);
private:
- UnlinkedProgramCodeBlock(JSGlobalData* globalData, Structure* structure, const ExecutableInfo& info)
- : Base(globalData, structure, GlobalCode, info)
+ UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
+ : Base(vm, structure, GlobalCode, info)
{
}
@@ -616,9 +632,9 @@ private:
FunctionDeclations m_functionDeclarations;
public:
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), &s_info);
}
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
@@ -630,10 +646,10 @@ class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
private:
friend class CodeCache;
- static UnlinkedEvalCodeBlock* create(JSGlobalData* globalData, const ExecutableInfo& info)
+ static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info)
{
- UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(globalData->heap)) UnlinkedEvalCodeBlock(globalData, globalData->unlinkedEvalCodeBlockStructure.get(), info);
- instance->finishCreation(*globalData);
+ UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info);
+ instance->finishCreation(*vm);
return instance;
}
@@ -643,24 +659,24 @@ public:
const Identifier& variable(unsigned index) { return m_variables[index]; }
unsigned numVariables() { return m_variables.size(); }
- void adoptVariables(Vector<Identifier>& variables)
+ void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables)
{
ASSERT(m_variables.isEmpty());
m_variables.swap(variables);
}
private:
- UnlinkedEvalCodeBlock(JSGlobalData* globalData, Structure* structure, const ExecutableInfo& info)
- : Base(globalData, structure, EvalCode, info)
+ UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
+ : Base(vm, structure, EvalCode, info)
{
}
- Vector<Identifier> m_variables;
+ Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
public:
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), &s_info);
}
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
@@ -669,30 +685,27 @@ public:
};
class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
-private:
- friend class CodeCache;
-
- static UnlinkedFunctionCodeBlock* create(JSGlobalData* globalData, CodeType codeType, const ExecutableInfo& info)
+public:
+ static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
{
- UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(globalData->heap)) UnlinkedFunctionCodeBlock(globalData, globalData->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
- instance->finishCreation(*globalData);
+ UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
+ instance->finishCreation(*vm);
return instance;
}
-public:
typedef UnlinkedCodeBlock Base;
static void destroy(JSCell*);
private:
- UnlinkedFunctionCodeBlock(JSGlobalData* globalData, Structure* structure, CodeType codeType, const ExecutableInfo& info)
- : Base(globalData, structure, codeType, info)
+ UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
+ : Base(vm, structure, codeType, info)
{
}
public:
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), &s_info);
}
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
diff --git a/Source/JavaScriptCore/bytecode/ValueProfile.h b/Source/JavaScriptCore/bytecode/ValueProfile.h
index e56e6eb6e..028c1f696 100644
--- a/Source/JavaScriptCore/bytecode/ValueProfile.h
+++ b/Source/JavaScriptCore/bytecode/ValueProfile.h
@@ -39,6 +39,7 @@
#include "Structure.h"
#include "WriteBarrier.h"
#include <wtf/PrintStream.h>
+#include <wtf/StringPrintStream.h>
namespace JSC {
@@ -110,6 +111,20 @@ struct ValueProfileBase {
return false;
}
+ CString briefDescription()
+ {
+ computeUpdatedPrediction();
+
+ StringPrintStream out;
+
+ if (m_singletonValueIsTop)
+ out.print("predicting ", SpeculationDump(m_prediction));
+ else if (m_singletonValue)
+ out.print("predicting ", m_singletonValue);
+
+ return out.toCString();
+ }
+
void dump(PrintStream& out)
{
out.print("samples = ", totalNumberOfSamples(), " prediction = ", SpeculationDump(m_prediction));
@@ -117,7 +132,7 @@ struct ValueProfileBase {
if (m_singletonValueIsTop)
out.printf("TOP");
else
- out.printf("%s", m_singletonValue.description());
+ out.print(m_singletonValue);
bool first = true;
for (unsigned i = 0; i < totalNumberOfBuckets; ++i) {
JSValue value = JSValue::decode(m_buckets[i]);
@@ -127,7 +142,7 @@ struct ValueProfileBase {
first = false;
} else
out.printf(", ");
- out.printf("%s", value.description());
+ out.print(value);
}
}
}
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h
index fc991a413..77d5a1030 100644
--- a/Source/JavaScriptCore/bytecode/ValueRecovery.h
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h
@@ -27,7 +27,7 @@
#define ValueRecovery_h
#include "DataFormat.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "MacroAssembler.h"
#include "VirtualRegister.h"
#include <stdio.h>
@@ -331,7 +331,7 @@ public:
out.printf("arguments");
break;
case Constant:
- out.printf("[%s]", constant().description());
+ out.print("[", constant(), "]");
break;
case DontKnow:
out.printf("!");
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 507241696..b4e3d3de8 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
* Copyright (C) 2012 Igalia, S.L.
*
@@ -32,95 +32,21 @@
#include "BytecodeGenerator.h"
#include "BatchedTransitionOptimizer.h"
-#include "Comment.h"
#include "Interpreter.h"
#include "JSActivation.h"
#include "JSFunction.h"
#include "JSNameScope.h"
#include "LowLevelInterpreter.h"
+#include "Operations.h"
#include "Options.h"
#include "StrongInlines.h"
+#include "UnlinkedCodeBlock.h"
#include <wtf/text/WTFString.h>
using namespace std;
namespace JSC {
-/*
- The layout of a register frame looks like this:
-
- For
-
- function f(x, y) {
- var v1;
- function g() { }
- var v2;
- return (x) * (y);
- }
-
- assuming (x) and (y) generated temporaries t1 and t2, you would have
-
- ------------------------------------
- | x | y | g | v2 | v1 | t1 | t2 | <-- value held
- ------------------------------------
- | -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index
- ------------------------------------
- | params->|<-locals | temps->
-
- Because temporary registers are allocated in a stack-like fashion, we
- can reclaim them with a simple popping algorithm. The same goes for labels.
- (We never reclaim parameter or local registers, because parameters and
- locals are DontDelete.)
-
- The register layout before a function call looks like this:
-
- For
-
- function f(x, y)
- {
- }
-
- f(1);
-
- > <------------------------------
- < > reserved: call frame | 1 | <-- value held
- > >snip< <------------------------------
- < > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index
- > <------------------------------
- | params->|<-locals | temps->
-
- The call instruction fills in the "call frame" registers. It also pads
- missing arguments at the end of the call:
-
- > <-----------------------------------
- < > reserved: call frame | 1 | ? | <-- value held ("?" stands for "undefined")
- > >snip< <-----------------------------------
- < > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index
- > <-----------------------------------
- | params->|<-locals | temps->
-
- After filling in missing arguments, the call instruction sets up the new
- stack frame to overlap the end of the old stack frame:
-
- |----------------------------------> <
- | reserved: call frame | 1 | ? < > <-- value held ("?" stands for "undefined")
- |----------------------------------> >snip< <
- | -7 | -6 | -5 | -4 | -3 | -2 | -1 < > <-- register index
- |----------------------------------> <
- | | params->|<-locals | temps->
-
- That way, arguments are "copied" into the callee's stack frame for free.
-
- If the caller supplies too many arguments, this trick doesn't work. The
- extra arguments protrude into space reserved for locals and temporaries.
- In that case, the call instruction makes a real copy of the call frame header,
- along with just the arguments expected by the callee, leaving the original
- call frame header and arguments behind. (The call instruction can't just discard
- extra arguments, because the "arguments" object may access them later.)
- This copying strategy ensures that all named values will be at the indices
- expected by the callee.
-*/
-
void Label::setLocation(unsigned location)
{
m_location = location;
@@ -141,8 +67,12 @@ void ResolveResult::checkValidity()
case Dynamic:
ASSERT(!m_local);
return;
+ case Lexical:
+ case ReadOnlyLexical:
+ ASSERT(!m_local);
+ return;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
#endif
@@ -154,7 +84,9 @@ ParserError BytecodeGenerator::generate()
m_codeBlock->setThisRegister(m_thisRegister.index());
m_scopeNode->emitBytecode(*this);
-
+
+ m_staticPropertyAnalyzer.kill();
+
for (unsigned i = 0; i < m_tryRanges.size(); ++i) {
TryRange& range = m_tryRanges[i];
int start = range.start->bind();
@@ -199,8 +131,8 @@ ParserError BytecodeGenerator::generate()
m_codeBlock->shrinkToFit();
if (m_expressionTooDeep)
- return ParserError::OutOfMemory;
- return ParserError::ErrorNone;
+ return ParserError(ParserError::OutOfMemory);
+ return ParserError(ParserError::ErrorNone);
}
bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
@@ -224,17 +156,15 @@ void BytecodeGenerator::preserveLastVar()
m_lastVar = &m_calleeRegisters.last();
}
-BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
+BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope*, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
: m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
, m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
-#if ENABLE(BYTECODE_COMMENTS)
- , m_currentCommentString(0)
-#endif
, m_symbolTable(0)
, m_scopeNode(programNode)
- , m_codeBlock(globalData, codeBlock)
+ , m_codeBlock(vm, codeBlock)
, m_thisRegister(CallFrame::thisArgumentOffset())
, m_emptyValueRegister(0)
+ , m_globalObjectRegister(0)
, m_finallyDepth(0)
, m_dynamicScopeDepth(0)
, m_codeType(GlobalCode)
@@ -243,12 +173,13 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, ProgramNode* prog
, m_hasCreatedActivation(true)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
- , m_globalData(&globalData)
+ , m_staticPropertyAnalyzer(&m_instructions)
+ , m_vm(&vm)
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
- , m_stack(wtfThreadData().stack())
+ , m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
@@ -257,7 +188,6 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, ProgramNode* prog
m_codeBlock->setNumParameters(1); // Allocate space for "this"
- prependComment("entering Program block");
emitOpcode(op_enter);
const VarStack& varStack = programNode->varStack();
@@ -266,7 +196,7 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, ProgramNode* prog
for (size_t i = 0; i < functionStack.size(); ++i) {
FunctionBodyNode* function = functionStack[i];
UnlinkedFunctionExecutable* unlinkedFunction = makeFunction(function);
- codeBlock->addFunctionDeclaration(*m_globalData, function->ident(), unlinkedFunction);
+ codeBlock->addFunctionDeclaration(*m_vm, function->ident(), unlinkedFunction);
}
for (size_t i = 0; i < varStack.size(); ++i)
@@ -274,17 +204,16 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, ProgramNode* prog
}
-BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode* functionBody, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
+BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope* scope, FunctionBodyNode* functionBody, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
: m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
, m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
, m_symbolTable(codeBlock->symbolTable())
-#if ENABLE(BYTECODE_COMMENTS)
- , m_currentCommentString(0)
-#endif
, m_scopeNode(functionBody)
- , m_codeBlock(globalData, codeBlock)
+ , m_scope(vm, scope)
+ , m_codeBlock(vm, codeBlock)
, m_activationRegister(0)
, m_emptyValueRegister(0)
+ , m_globalObjectRegister(0)
, m_finallyDepth(0)
, m_dynamicScopeDepth(0)
, m_codeType(FunctionCode)
@@ -293,12 +222,13 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
, m_hasCreatedActivation(false)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
- , m_globalData(&globalData)
+ , m_staticPropertyAnalyzer(&m_instructions)
+ , m_vm(&vm)
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
- , m_stack(wtfThreadData().stack())
+ , m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
@@ -308,11 +238,9 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
m_symbolTable->setParameterCountIncludingThis(functionBody->parameters()->size() + 1);
- prependComment("entering Function block");
emitOpcode(op_enter);
if (m_codeBlock->needsFullScopeChain()) {
m_activationRegister = addVar();
- prependComment("activation for Full Scope Chain");
emitInitLazyRegister(m_activationRegister);
m_codeBlock->setActivationRegister(m_activationRegister->index());
}
@@ -329,13 +257,10 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
codeBlock->setArgumentsRegister(argumentsRegister->index());
ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
- prependComment("arguments for Full Scope Chain");
emitInitLazyRegister(argumentsRegister);
- prependComment("unmodified arguments for Full Scope Chain");
emitInitLazyRegister(unmodifiedArgumentsRegister);
if (m_codeBlock->isStrictMode()) {
- prependComment("create arguments for strict mode");
emitOpcode(op_create_arguments);
instructions().append(argumentsRegister->index());
}
@@ -344,7 +269,6 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
// it from a call frame. In the long-term it should stop doing that (<rdar://problem/6911886>),
// but for now we force eager creation of the arguments object when debugging.
if (m_shouldEmitDebugHooks) {
- prependComment("create arguments for debug hooks");
emitOpcode(op_create_arguments);
instructions().append(argumentsRegister->index());
}
@@ -353,13 +277,13 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
bool capturesAnyArgumentByName = false;
- Vector<RegisterID*> capturedArguments;
+ Vector<RegisterID*, 0, UnsafeVectorOverflow> capturedArguments;
if (functionBody->hasCapturedVariables() || shouldCaptureAllTheThings) {
FunctionParameters& parameters = *functionBody->parameters();
capturedArguments.resize(parameters.size());
for (size_t i = 0; i < parameters.size(); ++i) {
capturedArguments[i] = 0;
- if (!functionBody->captures(parameters[i]) && !shouldCaptureAllTheThings)
+ if (!functionBody->captures(parameters.at(i)) && !shouldCaptureAllTheThings)
continue;
capturesAnyArgumentByName = true;
capturedArguments[i] = addVar();
@@ -396,12 +320,10 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
if (functionBody->captures(ident)) {
if (!m_hasCreatedActivation) {
m_hasCreatedActivation = true;
- prependComment("activation for captured vars");
emitOpcode(op_create_activation);
instructions().append(m_activationRegister->index());
}
m_functions.add(ident.impl());
- prependComment("captured function var");
emitNewFunction(addVar(ident, false), function);
}
}
@@ -414,7 +336,6 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
m_hasCreatedActivation = true;
- prependComment("cannot lazily create functions");
emitOpcode(op_create_activation);
instructions().append(m_activationRegister->index());
}
@@ -430,7 +351,6 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
RefPtr<RegisterID> reg = addVar(ident, false);
// Don't lazily create functions that override the name 'arguments'
// as this would complicate lazy instantiation of actual arguments.
- prependComment("a function that override 'arguments'");
if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
emitNewFunction(reg.get(), function);
else {
@@ -460,12 +380,12 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
for (size_t i = 0; i < parameters.size(); ++i, --nextParameterIndex) {
int index = nextParameterIndex;
if (capturedArguments.size() && capturedArguments[i]) {
- ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters[i])) || shouldCaptureAllTheThings);
+ ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters.at(i))) || shouldCaptureAllTheThings);
index = capturedArguments[i]->index();
RegisterID original(nextParameterIndex);
emitMove(capturedArguments[i], &original);
}
- addParameter(parameters[i], index);
+ addParameter(parameters.at(i), index);
}
preserveLastVar();
@@ -473,35 +393,24 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, FunctionBodyNode*
addCallee(functionBody, calleeRegister);
if (isConstructor()) {
- prependComment("'this' because we are a Constructor function");
-
- RefPtr<RegisterID> func = newTemporary();
-
- UnlinkedValueProfile profile = emitProfiledOpcode(op_get_callee);
- instructions().append(func->index());
- instructions().append(profile);
-
- emitOpcode(op_create_this);
- instructions().append(m_thisRegister.index());
- instructions().append(func->index());
+ emitCreateThis(&m_thisRegister);
} else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) {
UnlinkedValueProfile profile = emitProfiledOpcode(op_convert_this);
- instructions().append(m_thisRegister.index());
+ instructions().append(kill(&m_thisRegister));
instructions().append(profile);
}
}
-BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
+BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope* scope, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
: m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
, m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
, m_symbolTable(codeBlock->symbolTable())
-#if ENABLE(BYTECODE_COMMENTS)
- , m_currentCommentString(0)
-#endif
, m_scopeNode(evalNode)
- , m_codeBlock(globalData, codeBlock)
+ , m_scope(vm, scope)
+ , m_codeBlock(vm, codeBlock)
, m_thisRegister(CallFrame::thisArgumentOffset())
, m_emptyValueRegister(0)
+ , m_globalObjectRegister(0)
, m_finallyDepth(0)
, m_dynamicScopeDepth(0)
, m_codeType(EvalCode)
@@ -510,12 +419,13 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, EvalNode* evalNod
, m_hasCreatedActivation(true)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
- , m_globalData(&globalData)
+ , m_staticPropertyAnalyzer(&m_instructions)
+ , m_vm(&vm)
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
, m_lastOpcodePosition(0)
#endif
- , m_stack(wtfThreadData().stack())
+ , m_stack(vm, wtfThreadData().stack())
, m_usesExceptions(false)
, m_expressionTooDeep(false)
{
@@ -524,7 +434,6 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, EvalNode* evalNod
m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
m_codeBlock->setNumParameters(1);
- prependComment("entering Eval block");
emitOpcode(op_enter);
const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
@@ -533,7 +442,7 @@ BytecodeGenerator::BytecodeGenerator(JSGlobalData& globalData, EvalNode* evalNod
const DeclarationStacks::VarStack& varStack = evalNode->varStack();
unsigned numVariables = varStack.size();
- Vector<Identifier> variables;
+ Vector<Identifier, 0, UnsafeVectorOverflow> variables;
variables.reserveCapacity(numVariables);
for (size_t i = 0; i < numVariables; ++i)
variables.append(*varStack[i].first);
@@ -656,7 +565,7 @@ RegisterID* BytecodeGenerator::newTemporary()
return result;
}
-PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
+LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
{
// Reclaim free label scopes.
while (m_labelScopes.size() && !m_labelScopes.last().refCount())
@@ -665,7 +574,7 @@ PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, c
// Allocate new label scope.
LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
m_labelScopes.append(scope);
- return &m_labelScopes.last();
+ return LabelScopePtr(&m_labelScopes, m_labelScopes.size() - 1);
}
PassRefPtr<Label> BytecodeGenerator::newLabel()
@@ -707,31 +616,10 @@ void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
m_lastOpcodePosition = opcodePosition;
#endif
- emitComment();
instructions().append(opcodeID);
m_lastOpcodeID = opcodeID;
}
-#if ENABLE(BYTECODE_COMMENTS)
-// Record a comment in the CodeBlock's comments list for the current opcode
-// that is about to be emitted.
-void BytecodeGenerator::emitComment()
-{
- if (m_currentCommentString) {
- size_t opcodePosition = instructions().size();
- Comment comment = { opcodePosition, m_currentCommentString };
- m_codeBlock->bytecodeComments().append(comment);
- m_currentCommentString = 0;
- }
-}
-
-// Register a comment to be associated with the next opcode that will be emitted.
-void BytecodeGenerator::prependComment(const char* string)
-{
- m_currentCommentString = string;
-}
-#endif
-
UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
{
#if ENABLE(VALUE_PROFILER)
@@ -750,6 +638,11 @@ UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
#endif
}
+UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
+{
+ return m_codeBlock->addObjectAllocationProfile();
+}
+
UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
{
#if ENABLE(VALUE_PROFILER)
@@ -763,9 +656,7 @@ UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
void BytecodeGenerator::emitLoopHint()
{
-#if ENABLE(DFG_JIT)
emitOpcode(op_loop_hint);
-#endif
}
void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
@@ -802,7 +693,7 @@ void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
{
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jmp : op_loop);
+ emitOpcode(op_jmp);
instructions().append(target->bind(begin, instructions().size()));
return target;
}
@@ -820,7 +711,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jless : op_loop_if_less);
+ emitOpcode(op_jless);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
@@ -837,7 +728,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
+ emitOpcode(op_jlesseq);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
@@ -854,7 +745,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jgreater : op_loop_if_greater);
+ emitOpcode(op_jgreater);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
@@ -871,7 +762,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
rewindBinaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jgreatereq : op_loop_if_greatereq);
+ emitOpcode(op_jgreatereq);
instructions().append(src1Index);
instructions().append(src2Index);
instructions().append(target->bind(begin, instructions().size()));
@@ -911,7 +802,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
+ emitOpcode(op_jtrue);
instructions().append(cond->index());
instructions().append(target->bind(begin, instructions().size()));
return target;
@@ -997,7 +888,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
rewindUnaryOp();
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
+ emitOpcode(op_jtrue);
instructions().append(srcIndex);
instructions().append(target->bind(begin, instructions().size()));
return target;
@@ -1035,7 +926,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
}
size_t begin = instructions().size();
- emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false);
+ emitOpcode(op_jfalse);
instructions().append(cond->index());
instructions().append(target->bind(begin, instructions().size()));
return target;
@@ -1068,7 +959,7 @@ unsigned BytecodeGenerator::addConstant(const Identifier& ident)
StringImpl* rep = ident.impl();
IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
if (result.isNewEntry)
- m_codeBlock->addIdentifier(Identifier(m_globalData, rep));
+ m_codeBlock->addIdentifier(Identifier(m_vm, rep));
return result.iterator->value;
}
@@ -1110,6 +1001,8 @@ unsigned BytecodeGenerator::addRegExp(RegExp* r)
RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
{
+ m_staticPropertyAnalyzer.mov(dst->index(), src->index());
+
emitOpcode(op_mov);
instructions().append(dst->index());
instructions().append(src->index());
@@ -1124,36 +1017,20 @@ RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, R
return dst;
}
-RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
{
- emitOpcode(op_pre_inc);
+ emitOpcode(op_inc);
instructions().append(srcDst->index());
return srcDst;
}
-RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
{
- emitOpcode(op_pre_dec);
+ emitOpcode(op_dec);
instructions().append(srcDst->index());
return srcDst;
}
-RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
-{
- emitOpcode(op_post_inc);
- instructions().append(dst->index());
- instructions().append(srcDst->index());
- return dst;
-}
-
-RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
-{
- emitOpcode(op_post_dec);
- instructions().append(dst->index());
- instructions().append(srcDst->index());
- return dst;
-}
-
RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
{
emitOpcode(opcodeID);
@@ -1243,7 +1120,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
// FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time.
// Later we can do the extra work to handle that like the other cases. They also don't
// work correctly with NaN as a key.
- if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
+ if (std::isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
return emitLoad(dst, jsNumber(number));
JSValue& valueInMap = m_numberMap.add(number, JSValue()).iterator->value;
if (!valueInMap)
@@ -1255,7 +1132,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& ident
{
JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->value;
if (!stringInMap)
- stringInMap = jsOwnedString(globalData(), identifier.string());
+ stringInMap = jsOwnedString(vm(), identifier.string());
return emitLoad(dst, JSValue(stringInMap));
}
@@ -1267,6 +1144,21 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
return constantID;
}
+RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
+{
+ if (!m_globalObjectRegister) {
+ int index = m_nextConstantOffset;
+ m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
+ ++m_nextConstantOffset;
+ m_codeBlock->addConstant(JSValue());
+ m_globalObjectRegister = &m_constantPoolRegisters[index];
+ m_codeBlock->setGlobalObjectRegister(index);
+ }
+ if (dst)
+ emitMove(dst, m_globalObjectRegister);
+ return m_globalObjectRegister;
+}
+
ResolveResult BytecodeGenerator::resolve(const Identifier& property)
{
if (property == propertyNames().thisIdentifier)
@@ -1283,13 +1175,51 @@ ResolveResult BytecodeGenerator::resolve(const Identifier& property)
return ResolveResult::registerResolve(local, flags);
}
}
+ // Cases where we cannot statically optimize the lookup.
+ if (property == propertyNames().arguments || !canOptimizeNonLocals())
+ return ResolveResult::dynamicResolve();
+
+ if (!m_scope || m_codeType != FunctionCode || m_shouldEmitDebugHooks)
+ return ResolveResult::dynamicResolve();
+
+ ScopeChainIterator iter = m_scope->begin();
+ ScopeChainIterator end = m_scope->end();
+ size_t depth = m_codeBlock->needsFullScopeChain();
+ unsigned flags = 0;
+ for (; iter != end; ++iter, ++depth) {
+ JSObject* currentScope = iter.get();
+ if (!currentScope->isStaticScopeObject())
+ return ResolveResult::dynamicResolve();
+
+ JSSymbolTableObject* currentVariableObject = jsCast<JSSymbolTableObject*>(currentScope);
+ SymbolTableEntry entry = currentVariableObject->symbolTable()->get(property.impl());
+
+ // Found the property
+ if (!entry.isNull()) {
+ if (entry.isReadOnly())
+ flags |= ResolveResult::ReadOnlyFlag;
+ if (++iter == end)
+ return ResolveResult::dynamicResolve();
+#if !ASSERT_DISABLED
+ if (JSActivation* activation = jsDynamicCast<JSActivation*>(currentVariableObject))
+ ASSERT(activation->isValid(entry));
+#endif
+ return ResolveResult::lexicalResolve(entry.getIndex(), depth, flags);
+ }
+ bool scopeRequiresDynamicChecks = false;
+ if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
+ break;
+ if (scopeRequiresDynamicChecks)
+ flags |= ResolveResult::DynamicFlag;
+ }
+
return ResolveResult::dynamicResolve();
}
ResolveResult BytecodeGenerator::resolveConstDecl(const Identifier& property)
{
// Register-allocated const declarations.
- if (m_codeType != EvalCode && m_codeType != GlobalCode && m_symbolTable) {
+ if (m_codeType == FunctionCode && m_symbolTable) {
SymbolTableEntry entry = symbolTable().get(property.impl());
if (!entry.isNull()) {
unsigned flags = entry.isReadOnly() ? ResolveResult::ReadOnlyFlag : 0;
@@ -1328,11 +1258,11 @@ bool BytecodeGenerator::shouldAvoidResolveGlobal()
RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const ResolveResult& resolveResult, const Identifier& property)
{
- if (resolveResult.isRegister())
- return emitGetLocalVar(dst, resolveResult, property);
+ if (resolveResult.isStatic())
+ return emitGetStaticVar(dst, resolveResult, property);
UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
instructions().append(addConstant(property));
instructions().append(getResolveOperations(property));
instructions().append(profile);
@@ -1341,10 +1271,14 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const ResolveResult&
RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const ResolveResult& resolveResult, const Identifier& property)
{
- ASSERT_UNUSED(resolveResult, !resolveResult.isRegister());
+ if (!resolveResult.isDynamic()) {
+ // Global object is the base
+ return emitLoadGlobalObject(dst);
+ }
+
// We can't optimise at all :-(
UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_base);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
instructions().append(addConstant(property));
instructions().append(false);
instructions().append(getResolveBaseOperations(property));
@@ -1353,12 +1287,11 @@ RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const ResolveRes
return dst;
}
-RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const ResolveResult& resolveResult, const Identifier& property, NonlocalResolveInfo& verifier)
+RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const ResolveResult&, const Identifier& property, NonlocalResolveInfo& verifier)
{
- ASSERT_UNUSED(resolveResult, !resolveResult.isRegister());
// We can't optimise at all :-(
UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_base);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
instructions().append(addConstant(property));
instructions().append(m_codeBlock->isStrictMode());
uint32_t putToBaseIndex = 0;
@@ -1371,9 +1304,9 @@ RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const Reso
RegisterID* BytecodeGenerator::emitResolveWithBaseForPut(RegisterID* baseDst, RegisterID* propDst, const ResolveResult& resolveResult, const Identifier& property, NonlocalResolveInfo& verifier)
{
- ASSERT_UNUSED(resolveResult, !resolveResult.isRegister());
+ ASSERT_UNUSED(resolveResult, !resolveResult.isStatic());
UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_with_base);
- instructions().append(baseDst->index());
+ instructions().append(kill(baseDst));
instructions().append(propDst->index());
instructions().append(addConstant(property));
uint32_t putToBaseIndex = 0;
@@ -1386,14 +1319,14 @@ RegisterID* BytecodeGenerator::emitResolveWithBaseForPut(RegisterID* baseDst, Re
RegisterID* BytecodeGenerator::emitResolveWithThis(RegisterID* baseDst, RegisterID* propDst, const ResolveResult& resolveResult, const Identifier& property)
{
- if (resolveResult.isRegister()) {
+ if (resolveResult.isStatic()) {
emitLoad(baseDst, jsUndefined());
- emitGetLocalVar(propDst, resolveResult, property);
+ emitGetStaticVar(propDst, resolveResult, property);
return baseDst;
}
UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_with_this);
- instructions().append(baseDst->index());
+ instructions().append(kill(baseDst));
instructions().append(propDst->index());
instructions().append(addConstant(property));
instructions().append(getResolveWithThisOperations(property));
@@ -1401,8 +1334,9 @@ RegisterID* BytecodeGenerator::emitResolveWithThis(RegisterID* baseDst, Register
return baseDst;
}
-RegisterID* BytecodeGenerator::emitGetLocalVar(RegisterID* dst, const ResolveResult& resolveResult, const Identifier&)
+RegisterID* BytecodeGenerator::emitGetStaticVar(RegisterID* dst, const ResolveResult& resolveResult, const Identifier&)
{
+ ASSERT(m_codeType == FunctionCode);
switch (resolveResult.type()) {
case ResolveResult::Register:
case ResolveResult::ReadOnlyRegister:
@@ -1410,8 +1344,18 @@ RegisterID* BytecodeGenerator::emitGetLocalVar(RegisterID* dst, const ResolveRes
return 0;
return moveToDestinationIfNeeded(dst, resolveResult.local());
+ case ResolveResult::Lexical:
+ case ResolveResult::ReadOnlyLexical: {
+ UnlinkedValueProfile profile = emitProfiledOpcode(op_get_scoped_var);
+ instructions().append(dst->index());
+ instructions().append(resolveResult.index());
+ instructions().append(resolveResult.depth());
+ instructions().append(profile);
+ return dst;
+ }
+
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
}
@@ -1427,12 +1371,34 @@ RegisterID* BytecodeGenerator::emitInitGlobalConst(const Identifier& identifier,
return value;
}
+RegisterID* BytecodeGenerator::emitPutStaticVar(const ResolveResult& resolveResult, const Identifier&, RegisterID* value)
+{
+ ASSERT(m_codeType == FunctionCode);
+ switch (resolveResult.type()) {
+ case ResolveResult::Register:
+ case ResolveResult::ReadOnlyRegister:
+ return moveToDestinationIfNeeded(resolveResult.local(), value);
+
+ case ResolveResult::Lexical:
+ case ResolveResult::ReadOnlyLexical:
+ emitOpcode(op_put_scoped_var);
+ instructions().append(resolveResult.index());
+ instructions().append(resolveResult.depth());
+ instructions().append(value->index());
+ return value;
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return 0;
+ }
+}
+
RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
{
m_codeBlock->addPropertyAccessInstruction(instructions().size());
UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
instructions().append(base->index());
instructions().append(addConstant(property));
instructions().append(0);
@@ -1455,11 +1421,15 @@ RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterI
RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
{
+ unsigned propertyIndex = addConstant(property);
+
+ m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
+
m_codeBlock->addPropertyAccessInstruction(instructions().size());
emitOpcode(op_put_by_id);
instructions().append(base->index());
- instructions().append(addConstant(property));
+ instructions().append(propertyIndex);
instructions().append(value->index());
instructions().append(0);
instructions().append(0);
@@ -1481,27 +1451,35 @@ RegisterID* BytecodeGenerator::emitPutToBase(RegisterID* base, const Identifier&
RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
{
+ unsigned propertyIndex = addConstant(property);
+
+ m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
+
m_codeBlock->addPropertyAccessInstruction(instructions().size());
emitOpcode(op_put_by_id);
instructions().append(base->index());
- instructions().append(addConstant(property));
+ instructions().append(propertyIndex);
instructions().append(value->index());
instructions().append(0);
instructions().append(0);
instructions().append(0);
instructions().append(0);
instructions().append(
- property != m_globalData->propertyNames->underscoreProto
+ property != m_vm->propertyNames->underscoreProto
&& PropertyName(property).asIndex() == PropertyName::NotAnIndex);
return value;
}
void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, RegisterID* getter, RegisterID* setter)
{
+ unsigned propertyIndex = addConstant(property);
+
+ m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
+
emitOpcode(op_put_getter_setter);
instructions().append(base->index());
- instructions().append(addConstant(property));
+ instructions().append(propertyIndex);
instructions().append(getter->index());
instructions().append(setter->index());
}
@@ -1519,7 +1497,7 @@ RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID*
{
UnlinkedArrayProfile arrayProfile = newArrayProfile();
UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
ASSERT(base->index() == m_codeBlock->argumentsRegister());
instructions().append(base->index());
instructions().append(property->index());
@@ -1545,7 +1523,7 @@ RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, R
}
UnlinkedArrayProfile arrayProfile = newArrayProfile();
UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
instructions().append(base->index());
instructions().append(property->index());
instructions().append(arrayProfile);
@@ -1582,10 +1560,33 @@ RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index,
return value;
}
+RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
+{
+ RefPtr<RegisterID> func = newTemporary();
+
+ UnlinkedValueProfile profile = emitProfiledOpcode(op_get_callee);
+ instructions().append(func->index());
+ instructions().append(profile);
+
+ size_t begin = instructions().size();
+ m_staticPropertyAnalyzer.createThis(m_thisRegister.index(), begin + 3);
+
+ emitOpcode(op_create_this);
+ instructions().append(m_thisRegister.index());
+ instructions().append(func->index());
+ instructions().append(0);
+ return dst;
+}
+
RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
{
+ size_t begin = instructions().size();
+ m_staticPropertyAnalyzer.newObject(dst->index(), begin + 2);
+
emitOpcode(op_new_object);
instructions().append(dst->index());
+ instructions().append(0);
+ instructions().append(newObjectAllocationProfile());
return dst;
}
@@ -1598,7 +1599,7 @@ JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
{
JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->value;
if (!stringInMap) {
- stringInMap = jsString(globalData(), identifier.string());
+ stringInMap = jsString(vm(), identifier.string());
addConstantValue(stringInMap);
}
return stringInMap;
@@ -1612,7 +1613,7 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen
bool hadVariableExpression = false;
if (length) {
for (ElementNode* n = elements; n; n = n->next()) {
- if (!n->value()->isNumber() && !n->value()->isString()) {
+ if (!n->value()->isConstant()) {
hadVariableExpression = true;
break;
}
@@ -1628,12 +1629,8 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen
JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
unsigned index = 0;
for (ElementNode* n = elements; index < length; n = n->next()) {
- if (n->value()->isNumber())
- constantBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value());
- else {
- ASSERT(n->value()->isString());
- constantBuffer[index++] = addStringConstant(static_cast<StringNode*>(n->value())->value());
- }
+ ASSERT(n->value()->isConstant());
+ constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this);
}
emitOpcode(op_new_array_buffer);
instructions().append(dst->index());
@@ -1644,7 +1641,7 @@ RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elemen
}
}
- Vector<RefPtr<RegisterID>, 16> argv;
+ Vector<RefPtr<RegisterID>, 16, UnsafeVectorOverflow> argv;
for (ElementNode* n = elements; n; n = n->next()) {
if (n->elision())
break;
@@ -1704,9 +1701,9 @@ RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExp
return r0;
}
-RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
{
- return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, startOffset, endOffset);
+ return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, startOffset, endOffset, line, lineStart);
}
void BytecodeGenerator::createArgumentsIfNecessary()
@@ -1737,16 +1734,16 @@ void BytecodeGenerator::createActivationIfNecessary()
instructions().append(m_activationRegister->index());
}
-RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
{
- return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, startOffset, endOffset);
+ return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, startOffset, endOffset, line, lineStart);
}
ExpectedFunction BytecodeGenerator::expectedFunctionForIdentifier(const Identifier& identifier)
{
- if (identifier == m_globalData->propertyNames->Object)
+ if (identifier == m_vm->propertyNames->Object)
return ExpectObjectConstructor;
- if (identifier == m_globalData->propertyNames->Array)
+ if (identifier == m_vm->propertyNames->Array)
return ExpectArrayConstructor;
return NoExpectedFunction;
}
@@ -1766,10 +1763,8 @@ ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst,
instructions().append(Special::ObjectConstructor);
instructions().append(realCall->bind(begin, instructions().size()));
- if (dst != ignoredResult()) {
- emitOpcode(op_new_object);
- instructions().append(dst->index());
- }
+ if (dst != ignoredResult())
+ emitNewObject(dst);
break;
}
@@ -1819,7 +1814,7 @@ ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst,
return expectedFunction;
}
-RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
{
ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
ASSERT(func->refCount());
@@ -1833,7 +1828,7 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
emitNode(callArguments.argumentRegister(argument++), n);
// Reserve space for call frame.
- Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize> callFrame;
+ Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize, UnsafeVectorOverflow> callFrame;
for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i)
callFrame.append(newTemporary());
@@ -1842,7 +1837,7 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
instructions().append(callArguments.profileHookRegister()->index());
}
- emitExpressionInfo(divot, startOffset, endOffset);
+ emitExpressionInfo(divot, startOffset, endOffset, line, lineStart);
RefPtr<Label> done = newLabel();
expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
@@ -1861,7 +1856,7 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
instructions().append(arrayProfile);
if (dst != ignoredResult()) {
UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
- instructions().append(dst->index()); // dst
+ instructions().append(kill(dst));
instructions().append(profile);
}
@@ -1876,7 +1871,7 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
return dst;
}
-RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, RegisterID* profileHookRegister, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, RegisterID* profileHookRegister, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
{
if (m_shouldEmitProfileHooks) {
emitMove(profileHookRegister, func);
@@ -1884,7 +1879,7 @@ RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func
instructions().append(profileHookRegister->index());
}
- emitExpressionInfo(divot, startOffset, endOffset);
+ emitExpressionInfo(divot, startOffset, endOffset, line, lineStart);
// Emit call.
emitOpcode(op_call_varargs);
@@ -1894,7 +1889,7 @@ RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func
instructions().append(firstFreeRegister->index());
if (dst != ignoredResult()) {
UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
- instructions().append(dst->index());
+ instructions().append(kill(dst));
instructions().append(profile);
}
if (m_shouldEmitProfileHooks) {
@@ -1936,7 +1931,7 @@ RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* s
return src;
}
-RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
{
ASSERT(func->refCount());
@@ -1956,11 +1951,11 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func,
}
// Reserve space for call frame.
- Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize> callFrame;
+ Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize, UnsafeVectorOverflow> callFrame;
for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i)
callFrame.append(newTemporary());
- emitExpressionInfo(divot, startOffset, endOffset);
+ emitExpressionInfo(divot, startOffset, endOffset, line, lineStart);
RefPtr<Label> done = newLabel();
expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
@@ -1977,7 +1972,7 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func,
instructions().append(0);
if (dst != ignoredResult()) {
UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
- instructions().append(dst->index()); // dst
+ instructions().append(kill(dst));
instructions().append(profile);
}
@@ -2030,7 +2025,7 @@ void BytecodeGenerator::emitPopScope()
m_dynamicScopeDepth--;
}
-void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine, int column)
+void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, unsigned firstLine, unsigned lastLine, unsigned charOffset, unsigned lineStart)
{
#if ENABLE(DEBUG_WITH_BREAKPOINT)
if (debugHookID != DidReachBreakpoint)
@@ -2039,11 +2034,13 @@ void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, in
if (!m_shouldEmitDebugHooks)
return;
#endif
+ emitExpressionInfo(charOffset, 0, 0, firstLine, lineStart);
+ unsigned charPosition = charOffset - m_scopeNode->source().startOffset();
emitOpcode(op_debug);
instructions().append(debugHookID);
instructions().append(firstLine);
instructions().append(lastLine);
- instructions().append(column);
+ instructions().append(charPosition);
}
void BytecodeGenerator::pushFinallyContext(StatementNode* finallyBlock)
@@ -2151,7 +2148,7 @@ LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
return 0;
}
-PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
+void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, ControlFlowContext* bottomScope)
{
while (topScope > bottomScope) {
// First we count the number of dynamic scopes we need to remove to get
@@ -2165,32 +2162,21 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro
}
if (nNormalScopes) {
- size_t begin = instructions().size();
-
// We need to remove a number of dynamic scopes to get to the next
// finally block
- emitOpcode(op_jmp_scopes);
- instructions().append(nNormalScopes);
-
- // If topScope == bottomScope then there isn't actually a finally block
- // left to emit, so make the jmp_scopes jump directly to the target label
- if (topScope == bottomScope) {
- instructions().append(target->bind(begin, instructions().size()));
- return target;
- }
+ while (nNormalScopes--)
+ emitOpcode(op_pop_scope);
- // Otherwise we just use jmp_scopes to pop a group of scopes and go
- // to the next instruction
- RefPtr<Label> nextInsn = newLabel();
- instructions().append(nextInsn->bind(begin, instructions().size()));
- emitLabel(nextInsn.get());
+ // If topScope == bottomScope then there isn't a finally block left to emit.
+ if (topScope == bottomScope)
+ return;
}
Vector<ControlFlowContext> savedScopeContextStack;
Vector<SwitchInfo> savedSwitchContextStack;
Vector<ForInContext> savedForInContextStack;
Vector<TryContext> poppedTryContexts;
- SegmentedVector<LabelScope, 8> savedLabelScopes;
+ LabelScopeStore savedLabelScopes;
while (topScope > bottomScope && topScope->isFinallyBlock) {
RefPtr<Label> beforeFinally = emitLabel(newLabel().get());
@@ -2273,28 +2259,24 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro
--topScope;
}
}
- return emitJump(target);
}
-PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
+void BytecodeGenerator::emitPopScopes(int targetScopeDepth)
{
ASSERT(scopeDepth() - targetScopeDepth >= 0);
- ASSERT(target->isForward());
size_t scopeDelta = scopeDepth() - targetScopeDepth;
ASSERT(scopeDelta <= m_scopeContextStack.size());
if (!scopeDelta)
- return emitJump(target);
-
- if (m_finallyDepth)
- return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
+ return;
- size_t begin = instructions().size();
+ if (!m_finallyDepth) {
+ while (scopeDelta--)
+ emitOpcode(op_pop_scope);
+ return;
+ }
- emitOpcode(op_jmp_scopes);
- instructions().append(scopeDelta);
- instructions().append(target->bind(begin, instructions().size()));
- return target;
+ emitComplexPopScopes(&m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
}
RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
@@ -2365,7 +2347,7 @@ RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID*
void BytecodeGenerator::emitThrowReferenceError(const String& message)
{
emitOpcode(op_throw_static_error);
- instructions().append(addConstantValue(jsString(globalData(), message))->index());
+ instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, message)))->index());
instructions().append(true);
}
@@ -2396,7 +2378,7 @@ void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::S
emitOpcode(op_switch_string);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
instructions().append(0); // place holder for table index
@@ -2523,7 +2505,7 @@ void BytecodeGenerator::emitReadOnlyExceptionIfNeeded()
if (!isStrictMode())
return;
emitOpcode(op_throw_static_error);
- instructions().append(addConstantValue(jsString(globalData(), StrictModeReadonlyPropertyWriteError))->index());
+ instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
instructions().append(false);
}
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index a5bb95b6c..c268b9165 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
* Copyright (C) 2012 Igalia, S.L.
*
@@ -37,11 +37,14 @@
#include "Label.h"
#include "LabelScope.h"
#include "Interpreter.h"
+#include "ParserError.h"
#include "RegisterID.h"
#include "SymbolTable.h"
#include "Debugger.h"
#include "Nodes.h"
+#include "StaticPropertyAnalyzer.h"
#include "UnlinkedCodeBlock.h"
+#include "VMStackBounds.h"
#include <wtf/PassRefPtr.h>
#include <wtf/SegmentedVector.h>
#include <wtf/Vector.h>
@@ -74,7 +77,7 @@ namespace JSC {
RefPtr<RegisterID> m_profileHookRegister;
ArgumentsNode* m_argumentsNode;
- Vector<RefPtr<RegisterID>, 8> m_argv;
+ Vector<RefPtr<RegisterID>, 8, UnsafeVectorOverflow> m_argv;
};
struct FinallyContext {
@@ -126,14 +129,22 @@ namespace JSC {
DynamicFlag = 0x2,
// The resolved binding is immutable.
ReadOnlyFlag = 0x4,
+ // The property has a static location
+ StaticFlag = 0x8,
+ // Entry at scope distance "m_depth" and located at "m_index"
+ ScopedFlag = 0x10
};
enum Type {
// The property is local, and stored in a register.
- Register = RegisterFlag,
+ Register = RegisterFlag | StaticFlag,
// A read-only local, created by "const".
- ReadOnlyRegister = RegisterFlag | ReadOnlyFlag,
- // Any form of non-local lookup
+ ReadOnlyRegister = RegisterFlag | ReadOnlyFlag | StaticFlag,
+ // Lexically fixed location in the scope chain
+ Lexical = ScopedFlag | StaticFlag,
+ // A read-only Lexical, created by "const".
+ ReadOnlyLexical = ScopedFlag | ReadOnlyFlag | StaticFlag,
+ // Any other form of lookup
Dynamic = DynamicFlag,
};
@@ -145,6 +156,12 @@ namespace JSC {
{
return ResolveResult(Dynamic, 0);
}
+ static ResolveResult lexicalResolve(int index, size_t depth, unsigned flags)
+ {
+ if (flags & DynamicFlag)
+ return dynamicResolve();
+ return ResolveResult(Lexical | flags, index, depth);
+ }
unsigned type() const { return m_type; }
// Returns the register corresponding to a local variable, or 0 if no
@@ -153,13 +170,30 @@ namespace JSC {
RegisterID* local() const { return m_local; }
bool isRegister() const { return m_type & RegisterFlag; }
+ bool isStatic() const { return (m_type & StaticFlag) && !isDynamic(); }
bool isDynamic() const { return m_type & DynamicFlag; }
bool isReadOnly() const { return (m_type & ReadOnlyFlag) && !isDynamic(); }
+ unsigned depth() const { ASSERT(isStatic()); return m_depth; }
+ int32_t index() const { ASSERT(isStatic()); return m_index; }
+
private:
ResolveResult(unsigned type, RegisterID* local)
: m_type(type)
, m_local(local)
+ , m_index(0)
+ , m_depth(0)
+ {
+#ifndef NDEBUG
+ checkValidity();
+#endif
+ }
+
+ ResolveResult(unsigned type, int index, unsigned depth)
+ : m_type(type)
+ , m_local(0)
+ , m_index(index)
+ , m_depth(depth)
{
#ifndef NDEBUG
checkValidity();
@@ -172,6 +206,8 @@ namespace JSC {
unsigned m_type;
RegisterID* m_local; // Local register, if RegisterFlag is set
+ int m_index;
+ unsigned m_depth;
};
struct NonlocalResolveInfo {
@@ -209,14 +245,14 @@ namespace JSC {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- BytecodeGenerator(JSGlobalData&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, ProfilerMode);
- BytecodeGenerator(JSGlobalData&, FunctionBodyNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, ProfilerMode);
- BytecodeGenerator(JSGlobalData&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, ProfilerMode);
+ BytecodeGenerator(VM&, JSScope*, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, ProfilerMode);
+ BytecodeGenerator(VM&, JSScope*, FunctionBodyNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, ProfilerMode);
+ BytecodeGenerator(VM&, JSScope*, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, ProfilerMode);
~BytecodeGenerator();
- JSGlobalData* globalData() const { return m_globalData; }
- const CommonIdentifiers& propertyNames() const { return *m_globalData->propertyNames; }
+ VM* vm() const { return m_vm; }
+ const CommonIdentifiers& propertyNames() const { return *m_vm->propertyNames; }
bool isConstructor() { return m_codeBlock->isConstructor(); }
@@ -296,65 +332,70 @@ namespace JSC {
return dst == ignoredResult() ? 0 : (dst && dst != src) ? emitMove(dst, src) : src;
}
- PassRefPtr<LabelScope> newLabelScope(LabelScope::Type, const Identifier* = 0);
+ LabelScopePtr newLabelScope(LabelScope::Type, const Identifier* = 0);
PassRefPtr<Label> newLabel();
- // The emitNode functions are just syntactic sugar for calling
- // Node::emitCode. These functions accept a 0 for the register,
- // meaning that the node should allocate a register, or ignoredResult(),
- // meaning that the node need not put the result in a register.
- // Other emit functions do not accept 0 or ignoredResult().
- RegisterID* emitNode(RegisterID* dst, Node* n)
+ void emitNode(RegisterID* dst, StatementNode* n)
{
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
- addLineInfo(n->lineNo());
- return m_stack.isSafeToRecurse()
- ? n->emitBytecode(*this, dst)
- : emitThrowExpressionTooDeepException();
+ if (!m_stack.isSafeToRecurse()) {
+ emitThrowExpressionTooDeepException();
+ return;
+ }
+ n->emitBytecode(*this, dst);
}
- RegisterID* emitNode(Node* n)
+ void emitNode(StatementNode* n)
+ {
+ emitNode(0, n);
+ }
+
+ RegisterID* emitNode(RegisterID* dst, ExpressionNode* n)
+ {
+ // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
+ ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
+ if (!m_stack.isSafeToRecurse())
+ return emitThrowExpressionTooDeepException();
+ return n->emitBytecode(*this, dst);
+ }
+
+ RegisterID* emitNode(ExpressionNode* n)
{
return emitNode(0, n);
}
- void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
+ void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
{
- addLineInfo(n->lineNo());
- if (m_stack.isSafeToRecurse())
- n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
- else
+ if (!m_stack.isSafeToRecurse()) {
emitThrowExpressionTooDeepException();
+ return;
+ }
+
+ n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMode);
}
- void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
- {
- divot -= m_scopeNode->source().startOffset();
- if (divot > ExpressionRangeInfo::MaxDivot) {
- // Overflow has occurred, we can only give line number info for errors for this region
- divot = 0;
- startOffset = 0;
- endOffset = 0;
- } else if (startOffset > ExpressionRangeInfo::MaxOffset) {
- // If the start offset is out of bounds we clear both offsets
- // so we only get the divot marker. Error message will have to be reduced
- // to line and column number.
- startOffset = 0;
- endOffset = 0;
- } else if (endOffset > ExpressionRangeInfo::MaxOffset) {
- // The end offset is only used for additional context, and is much more likely
- // to overflow (eg. function call arguments) so we are willing to drop it without
- // dropping the rest of the range.
- endOffset = 0;
- }
-
- ExpressionRangeInfo info;
- info.instructionOffset = instructions().size();
- info.divotPoint = divot;
- info.startOffset = startOffset;
- info.endOffset = endOffset;
- m_codeBlock->addExpressionInfo(info);
+ void emitExpressionInfo(int divot, int startOffset, int endOffset, unsigned line, int lineStart)
+ {
+ int sourceOffset = m_scopeNode->source().startOffset();
+ unsigned firstLine = m_scopeNode->source().firstLine();
+
+ ASSERT(divot >= lineStart);
+ ASSERT(divot >= sourceOffset);
+ divot -= sourceOffset;
+
+ if (lineStart > sourceOffset)
+ lineStart -= sourceOffset;
+ else
+ lineStart = 0;
+
+ ASSERT(line >= firstLine);
+ line -= firstLine;
+
+ unsigned instructionOffset = instructions().size();
+ ASSERT(divot >= lineStart);
+ unsigned column = divot - lineStart;
+ m_codeBlock->addExpressionInfo(instructionOffset, divot, startOffset, endOffset, line, column);
}
ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
@@ -377,12 +418,14 @@ namespace JSC {
RegisterID* emitLoad(RegisterID* dst, double);
RegisterID* emitLoad(RegisterID* dst, const Identifier&);
RegisterID* emitLoad(RegisterID* dst, JSValue);
+ RegisterID* emitLoadGlobalObject(RegisterID* dst);
RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
+ RegisterID* emitCreateThis(RegisterID* dst);
RegisterID* emitNewObject(RegisterID* dst);
RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
@@ -394,18 +437,17 @@ namespace JSC {
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
- RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); }
- RegisterID* emitPreInc(RegisterID* srcDst);
- RegisterID* emitPreDec(RegisterID* srcDst);
- RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
- RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
+ RegisterID* emitToNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_number, dst, src); }
+ RegisterID* emitInc(RegisterID* srcDst);
+ RegisterID* emitDec(RegisterID* srcDst);
void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target);
RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype);
RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
- RegisterID* emitGetLocalVar(RegisterID* dst, const ResolveResult&, const Identifier&);
+ RegisterID* emitGetStaticVar(RegisterID* dst, const ResolveResult&, const Identifier&);
+ RegisterID* emitPutStaticVar(const ResolveResult&, const Identifier&, RegisterID* value);
RegisterID* emitInitGlobalConst(const Identifier&, RegisterID* value);
RegisterID* emitResolve(RegisterID* dst, const ResolveResult&, const Identifier& property);
@@ -429,15 +471,15 @@ namespace JSC {
void emitPutGetterSetter(RegisterID* base, const Identifier& property, RegisterID* getter, RegisterID* setter);
ExpectedFunction expectedFunctionForIdentifier(const Identifier&);
- RegisterID* emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, RegisterID* profileHookRegister, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
+ RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
+ RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, RegisterID* profileHookRegister, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
RegisterID* emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* args);
RegisterID* emitReturn(RegisterID* src);
RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
- RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
void emitToPrimitive(RegisterID* dst, RegisterID* src);
@@ -448,7 +490,7 @@ namespace JSC {
PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
- PassRefPtr<Label> emitJumpScopes(Label* target, int targetScopeDepth);
+ void emitPopScopes(int targetScopeDepth);
RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget);
RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target);
@@ -473,7 +515,7 @@ namespace JSC {
RegisterID* emitPushWithScope(RegisterID* scope);
void emitPopScope();
- void emitDebugHook(DebugHookID, int firstLine, int lastLine, int column);
+ void emitDebugHook(DebugHookID, unsigned firstLine, unsigned lastLine, unsigned charOffset, unsigned lineStart);
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
bool hasFinaliser() { return m_finallyDepth != 0; }
@@ -501,34 +543,31 @@ namespace JSC {
CodeType codeType() const { return m_codeType; }
bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; }
+ bool shouldEmitDebugHooks() { return m_shouldEmitDebugHooks; }
bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
private:
friend class Label;
-#if ENABLE(BYTECODE_COMMENTS)
- // Record a comment in the CodeBlock's comments list for the current
- // opcode that is about to be emitted.
- void emitComment();
- // Register a comment to be associated with the next opcode that will
- // be emitted.
- void prependComment(const char* string);
-#else
- ALWAYS_INLINE void emitComment() { }
- ALWAYS_INLINE void prependComment(const char*) { }
-#endif
-
void emitOpcode(OpcodeID);
UnlinkedArrayAllocationProfile newArrayAllocationProfile();
+ UnlinkedObjectAllocationProfile newObjectAllocationProfile();
UnlinkedArrayProfile newArrayProfile();
UnlinkedValueProfile emitProfiledOpcode(OpcodeID);
+ int kill(RegisterID* dst)
+ {
+ int index = dst->index();
+ m_staticPropertyAnalyzer.kill(index);
+ return index;
+ }
+
void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
ALWAYS_INLINE void rewindBinaryOp();
ALWAYS_INLINE void rewindUnaryOp();
- PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
+ void emitComplexPopScopes(ControlFlowContext* topScope, ControlFlowContext* bottomScope);
typedef HashMap<double, JSValue> NumberMap;
typedef HashMap<StringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap;
@@ -544,7 +583,7 @@ namespace JSC {
// (i.e. "Object()" is identical to "new Object()").
ExpectedFunction emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, Label* done);
- RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
RegisterID* newRegister();
@@ -595,25 +634,17 @@ namespace JSC {
UnlinkedFunctionExecutable* makeFunction(FunctionBodyNode* body)
{
- return UnlinkedFunctionExecutable::create(m_globalData, m_scopeNode->source(), body);
- }
-
- JSString* addStringConstant(const Identifier&);
-
- void addLineInfo(unsigned lineNo)
- {
- m_codeBlock->addLineInfo(instructions().size(), lineNo - m_scopeNode->firstLine());
+ return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), body);
}
RegisterID* emitInitLazyRegister(RegisterID*);
public:
- Vector<UnlinkedInstruction>& instructions() { return m_instructions; }
+ JSString* addStringConstant(const Identifier&);
+
+ Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
SharedSymbolTable& symbolTable() { return *m_symbolTable; }
-#if ENABLE(BYTECODE_COMMENTS)
- Vector<Comment>& comments() { return m_comments; }
-#endif
bool shouldOptimizeLocals()
{
@@ -646,19 +677,15 @@ namespace JSC {
void createActivationIfNecessary();
RegisterID* createLazyRegisterIfNecessary(RegisterID*);
- Vector<UnlinkedInstruction> m_instructions;
+ Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
bool m_shouldEmitDebugHooks;
bool m_shouldEmitProfileHooks;
SharedSymbolTable* m_symbolTable;
-#if ENABLE(BYTECODE_COMMENTS)
- Vector<Comment> m_comments;
- const char *m_currentCommentString;
-#endif
-
ScopeNode* m_scopeNode;
+ Strong<JSScope> m_scope;
Strong<UnlinkedCodeBlock> m_codeBlock;
// Some of these objects keep pointers to one another. They are arranged
@@ -669,17 +696,18 @@ namespace JSC {
RegisterID m_calleeRegister;
RegisterID* m_activationRegister;
RegisterID* m_emptyValueRegister;
+ RegisterID* m_globalObjectRegister;
SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
SegmentedVector<RegisterID, 32> m_calleeRegisters;
SegmentedVector<RegisterID, 32> m_parameters;
SegmentedVector<Label, 32> m_labels;
- SegmentedVector<LabelScope, 8> m_labelScopes;
+ LabelScopeStore m_labelScopes;
RefPtr<RegisterID> m_lastVar;
int m_finallyDepth;
int m_dynamicScopeDepth;
CodeType m_codeType;
- Vector<ControlFlowContext> m_scopeContextStack;
+ Vector<ControlFlowContext, 0, UnsafeVectorOverflow> m_scopeContextStack;
Vector<SwitchInfo> m_switchContextStack;
Vector<ForInContext> m_forInContextStack;
Vector<TryContext> m_tryContextStack;
@@ -775,14 +803,16 @@ namespace JSC {
IdentifierResolvePutMap m_resolveBaseForPutMap;
IdentifierResolvePutMap m_resolveWithBaseForPutMap;
- JSGlobalData* m_globalData;
+ StaticPropertyAnalyzer m_staticPropertyAnalyzer;
+
+ VM* m_vm;
OpcodeID m_lastOpcodeID;
#ifndef NDEBUG
size_t m_lastOpcodePosition;
#endif
- StackBounds m_stack;
+ VMStackBounds m_stack;
bool m_usesExceptions;
bool m_expressionTooDeep;
diff --git a/Source/JavaScriptCore/bytecompiler/Label.h b/Source/JavaScriptCore/bytecompiler/Label.h
index 8b444de91..d29ab8ff3 100644
--- a/Source/JavaScriptCore/bytecompiler/Label.h
+++ b/Source/JavaScriptCore/bytecompiler/Label.h
@@ -37,6 +37,8 @@
namespace JSC {
+ class BytecodeGenerator;
+
class Label {
public:
explicit Label(BytecodeGenerator* generator)
diff --git a/Source/JavaScriptCore/bytecompiler/LabelScope.h b/Source/JavaScriptCore/bytecompiler/LabelScope.h
index cc21fffd1..2df6f1b9b 100644
--- a/Source/JavaScriptCore/bytecompiler/LabelScope.h
+++ b/Source/JavaScriptCore/bytecompiler/LabelScope.h
@@ -49,13 +49,6 @@ namespace JSC {
, m_continueTarget(continueTarget)
{
}
-
- void ref() { ++m_refCount; }
- void deref()
- {
- --m_refCount;
- ASSERT(m_refCount >= 0);
- }
int refCount() const { return m_refCount; }
Label* breakTarget() const { return m_breakTarget.get(); }
@@ -66,6 +59,15 @@ namespace JSC {
int scopeDepth() const { return m_scopeDepth; }
private:
+ friend class LabelScopePtr;
+
+ void ref() { ++m_refCount; }
+ void deref()
+ {
+ --m_refCount;
+ ASSERT(m_refCount >= 0);
+ }
+
int m_refCount;
Type m_type;
const Identifier* m_name;
@@ -74,6 +76,57 @@ namespace JSC {
RefPtr<Label> m_continueTarget;
};
+ typedef Vector<LabelScope, 8> LabelScopeStore;
+
+ class LabelScopePtr {
+ public:
+ LabelScopePtr()
+ : m_owner(0)
+ , m_index(0)
+ {
+ }
+ LabelScopePtr(LabelScopeStore* owner, size_t index)
+ : m_owner(owner)
+ , m_index(index)
+ {
+ m_owner->at(index).ref();
+ }
+
+ LabelScopePtr(const LabelScopePtr& other)
+ : m_owner(other.m_owner)
+ , m_index(other.m_index)
+ {
+ if (m_owner)
+ m_owner->at(m_index).ref();
+ }
+
+ const LabelScopePtr& operator=(const LabelScopePtr& other)
+ {
+ if (other.m_owner)
+ other.m_owner->at(other.m_index).ref();
+ if (m_owner)
+ m_owner->at(m_index).deref();
+ m_owner = other.m_owner;
+ m_index = other.m_index;
+ return *this;
+ }
+
+ ~LabelScopePtr()
+ {
+ if (m_owner)
+ m_owner->at(m_index).deref();
+ }
+
+ LabelScope& operator*() { ASSERT(m_owner); return m_owner->at(m_index); }
+ LabelScope* operator->() { ASSERT(m_owner); return &m_owner->at(m_index); }
+ const LabelScope& operator*() const { ASSERT(m_owner); return m_owner->at(m_index); }
+ const LabelScope* operator->() const { ASSERT(m_owner); return &m_owner->at(m_index); }
+
+ private:
+ LabelScopeStore* m_owner;
+ size_t m_index;
+ };
+
} // namespace JSC
#endif // LabelScope_h
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 71b6c7cac..40f703c08 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
-* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -74,49 +74,49 @@ namespace JSC {
because the assignment node, "x =", passes r[x] as dst to the number node, "1".
*/
+void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
+{
+ RegisterID* result = generator.emitNode(this);
+ if (fallThroughMode == FallThroughMeansTrue)
+ generator.emitJumpIfFalse(result, falseTarget);
+ else
+ generator.emitJumpIfTrue(result, trueTarget);
+}
+
// ------------------------------ ThrowableExpressionData --------------------------------
RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
{
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitThrowReferenceError(message);
return generator.newTemporary();
}
-// ------------------------------ NullNode -------------------------------------
+// ------------------------------ ConstantNode ----------------------------------
-RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, jsNull());
-}
-
-// ------------------------------ BooleanNode ----------------------------------
+ TriState value = jsValue(generator).pureToBoolean();
+ if (value == MixedTriState)
+ ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
+ else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse)
+ generator.emitJump(trueTarget);
+ else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue)
+ generator.emitJump(falseTarget);
-RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, m_value);
+ // All other cases are unconditional fall-throughs, like "if (true)".
}
-// ------------------------------ NumberNode -----------------------------------
-
-RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (dst == generator.ignoredResult())
return 0;
- return generator.emitLoad(dst, m_value);
+ return generator.emitLoad(dst, jsValue(generator));
}
-// ------------------------------ StringNode -----------------------------------
-
-RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+JSValue StringNode::jsValue(BytecodeGenerator& generator) const
{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, m_value);
+ return generator.addStringConstant(m_value);
}
// ------------------------------ RegExpNode -----------------------------------
@@ -125,7 +125,7 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
{
if (dst == generator.ignoredResult())
return 0;
- return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.globalData(), m_pattern.string(), regExpFlags(m_flags.string())));
+ return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())));
}
// ------------------------------ ThisNode -------------------------------------
@@ -141,7 +141,7 @@ RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst
bool ResolveNode::isPure(BytecodeGenerator& generator) const
{
- return generator.resolve(m_ident).isRegister();
+ return generator.resolve(m_ident).isStatic();
}
RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
@@ -153,7 +153,8 @@ RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
return generator.moveToDestinationIfNeeded(dst, local);
}
- generator.emitExpressionInfo(m_startOffset + m_ident.length(), m_ident.length(), 0);
+ unsigned divot = m_startOffset + m_ident.length();
+ generator.emitExpressionInfo(divot, m_ident.length(), 0, m_divotLine, m_divotLineStart);
return generator.emitResolve(generator.finalDestination(dst), resolveResult, m_ident);
}
@@ -201,7 +202,7 @@ bool ArrayNode::isSimpleArray() const
return true;
}
-ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNumber, int columnNumber) const
+ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPosition) const
{
ASSERT(!m_elision && !m_optional);
ElementNode* ptr = m_element;
@@ -209,13 +210,13 @@ ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNu
return 0;
JSTokenLocation location;
location.line = lineNumber;
- location.column = columnNumber;
- ArgumentListNode* head = new (globalData) ArgumentListNode(location, ptr->value());
+ location.startOffset = startPosition;
+ ArgumentListNode* head = new (vm) ArgumentListNode(location, ptr->value());
ArgumentListNode* tail = head;
ptr = ptr->next();
for (; ptr; ptr = ptr->next()) {
ASSERT(!ptr->elision());
- tail = new (globalData) ArgumentListNode(location, tail, ptr->value());
+ tail = new (vm) ArgumentListNode(location, tail, ptr->value());
}
return head;
}
@@ -324,13 +325,13 @@ RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, Regi
&& generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())
&& !generator.symbolTable().slowArguments()) {
RegisterID* property = generator.emitNode(m_subscript);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
}
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
RegisterID* property = generator.emitNode(m_subscript);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
}
@@ -344,13 +345,13 @@ RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, Register
ResolveNode* resolveNode = static_cast<ResolveNode*>(m_base);
if (!generator.willResolveToArguments(resolveNode->identifier()))
goto nonArgumentsPath;
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments());
}
nonArgumentsPath:
RegisterID* base = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
}
@@ -373,7 +374,7 @@ RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
expectedFunction = NoExpectedFunction;
RefPtr<RegisterID> func = generator.emitNode(m_expr);
CallArguments callArguments(generator, m_args);
- return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset());
+ return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
inline CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode)
@@ -408,9 +409,9 @@ RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, Reg
{
RefPtr<RegisterID> func = generator.tempDestination(dst);
CallArguments callArguments(generator, m_args);
- generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
+ generator.emitExpressionInfo(divot() - divotStartOffset() + 4, 4, 0, divotLine(), divotLineStart());
generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), generator.resolve(generator.propertyNames().eval), generator.propertyNames().eval);
- return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
+ return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
// ------------------------------ FunctionCallValueNode ----------------------------------
@@ -420,7 +421,7 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re
RefPtr<RegisterID> func = generator.emitNode(m_expr);
CallArguments callArguments(generator, m_args);
generator.emitLoad(callArguments.thisRegister(), jsUndefined());
- return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
// ------------------------------ FunctionCallResolveNode ----------------------------------
@@ -436,16 +437,24 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
generator.emitLoad(callArguments.thisRegister(), jsUndefined());
// This passes NoExpectedFunction because we expect that if the function is in a
// local variable, then it's not one of our built-in constructors.
- return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), func.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), func.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
+ }
+
+ if (resolveResult.isStatic()) {
+ RefPtr<RegisterID> func = generator.newTemporary();
+ CallArguments callArguments(generator, m_args);
+ generator.emitGetStaticVar(func.get(), resolveResult, m_ident);
+ generator.emitLoad(callArguments.thisRegister(), jsUndefined());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
RefPtr<RegisterID> func = generator.newTemporary();
CallArguments callArguments(generator, m_args);
- int identifierStart = divot() - startOffset();
+ int identifierStart = divot() - divotStartOffset();
- generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0);
+ generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0, divotLine(), divotLineStart());
generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), resolveResult, m_ident);
- return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
// ------------------------------ FunctionCallBracketNode ----------------------------------
@@ -454,11 +463,11 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator,
{
RefPtr<RegisterID> base = generator.emitNode(m_base);
RegisterID* property = generator.emitNode(m_subscript);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
CallArguments callArguments(generator, m_args);
generator.emitMove(callArguments.thisRegister(), base.get());
- return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
// ------------------------------ FunctionCallDotNode ----------------------------------
@@ -468,9 +477,9 @@ RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, Regi
RefPtr<RegisterID> function = generator.tempDestination(dst);
CallArguments callArguments(generator, m_args);
generator.emitNode(callArguments.thisRegister(), m_base);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
- return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
@@ -478,7 +487,7 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<Label> realCall = generator.newLabel();
RefPtr<Label> end = generator.newLabel();
RefPtr<RegisterID> base = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
@@ -490,7 +499,7 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
- generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitJump(end.get());
m_args->m_listNode = oldList;
@@ -498,7 +507,7 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
generator.emitLoad(callArguments.thisRegister(), jsUndefined());
- generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitJump(end.get());
}
}
@@ -506,7 +515,7 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
{
CallArguments callArguments(generator, m_args);
generator.emitMove(callArguments.thisRegister(), base.get());
- generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
generator.emitLabel(end.get());
return finalDestinationOrIgnored.get();
@@ -528,7 +537,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<Label> realCall = generator.newLabel();
RefPtr<Label> end = generator.newLabel();
RefPtr<RegisterID> base = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
@@ -539,24 +548,24 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
if (m_args->m_listNode->m_next) {
ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
ASSERT(!m_args->m_listNode->m_next->m_next);
- m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.globalData(), 0, 0);
+ m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.vm(), 0, 0);
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
- generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
} else {
m_args->m_listNode = m_args->m_listNode->m_next;
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
- generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
m_args->m_listNode = oldList;
} else {
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
generator.emitLoad(callArguments.thisRegister(), jsUndefined());
- generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
} else {
ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
@@ -577,7 +586,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
while ((args = args->m_next))
generator.emitNode(args->m_expr);
- generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), profileHookRegister.get(), divot(), startOffset(), endOffset());
+ generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), profileHookRegister.get(), divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
generator.emitJump(end.get());
}
@@ -585,7 +594,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
{
CallArguments callArguments(generator, m_args);
generator.emitMove(callArguments.thisRegister(), base.get());
- generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
+ generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
}
generator.emitLabel(end.get());
return finalDestinationOrIgnored.get();
@@ -593,52 +602,60 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
// ------------------------------ PostfixNode ----------------------------------
-static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
+static RegisterID* emitIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
{
- return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
+ return (oper == OpPlusPlus) ? generator.emitInc(srcDst) : generator.emitDec(srcDst);
}
static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
{
- if (srcDst == dst)
- return generator.emitToJSNumber(dst, srcDst);
- return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
+ if (dst == srcDst)
+ return generator.emitToNumber(generator.finalDestination(dst), srcDst);
+ RefPtr<RegisterID> tmp = generator.emitToNumber(generator.tempDestination(dst), srcDst);
+ emitIncOrDec(generator, srcDst, oper);
+ return generator.moveToDestinationIfNeeded(dst, tmp.get());
}
RegisterID* PostfixNode::emitResolve(BytecodeGenerator& generator, RegisterID* dst)
{
+ if (dst == generator.ignoredResult())
+ return PrefixNode::emitResolve(generator, dst);
+
ASSERT(m_expr->isResolveNode());
ResolveNode* resolve = static_cast<ResolveNode*>(m_expr);
const Identifier& ident = resolve->identifier();
ResolveResult resolveResult = generator.resolve(ident);
- if (RegisterID* local = resolveResult.local()) {
+ if (RefPtr<RegisterID> local = resolveResult.local()) {
if (resolveResult.isReadOnly()) {
generator.emitReadOnlyExceptionIfNeeded();
- return generator.emitToJSNumber(generator.finalDestination(dst), local);
+ local = generator.emitMove(generator.tempDestination(dst), local.get());
}
- if (dst == generator.ignoredResult())
- return emitPreIncOrDec(generator, local, m_operator);
- return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
+ return emitPostIncOrDec(generator, generator.finalDestination(dst), local.get(), m_operator);
}
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+
+ if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
+ RefPtr<RegisterID> value = generator.emitGetStaticVar(generator.newTemporary(), resolveResult, ident);
+ RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
+ generator.emitPutStaticVar(resolveResult, ident, value.get());
+ return oldValue.get();
+ }
+
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RefPtr<RegisterID> value = generator.newTemporary();
NonlocalResolveInfo resolveInfo;
RefPtr<RegisterID> base = generator.emitResolveWithBaseForPut(generator.newTemporary(), value.get(), resolveResult, ident, resolveInfo);
- RegisterID* oldValue;
- if (dst == generator.ignoredResult()) {
- oldValue = 0;
- emitPreIncOrDec(generator, value.get(), m_operator);
- } else
- oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
+ RefPtr<RegisterID> oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
generator.emitPutToBase(base.get(), ident, value.get(), resolveInfo);
- return oldValue;
+ return oldValue.get();
}
RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* dst)
{
+ if (dst == generator.ignoredResult())
+ return PrefixNode::emitBracket(generator, dst);
+
ASSERT(m_expr->isBracketAccessorNode());
BracketAccessorNode* bracketAccessor = static_cast<BracketAccessorNode*>(m_expr);
ExpressionNode* baseNode = bracketAccessor->base();
@@ -647,22 +664,19 @@ RegisterID* PostfixNode::emitBracket(BytecodeGenerator& generator, RegisterID* d
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(baseNode, bracketAccessor->subscriptHasAssignments(), subscript->isPure(generator));
RefPtr<RegisterID> property = generator.emitNode(subscript);
- generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
+ generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStartOffset(), bracketAccessor->divotEndOffset(), bracketAccessor->divotLine(), bracketAccessor->divotLineStart());
RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
- if (dst == generator.ignoredResult()) {
- emitPreIncOrDec(generator, value.get(), m_operator);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutByVal(base.get(), property.get(), value.get());
- return 0;
- }
RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitPutByVal(base.get(), property.get(), value.get());
return generator.moveToDestinationIfNeeded(dst, oldValue);
}
RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
{
+ if (dst == generator.ignoredResult())
+ return PrefixNode::emitDot(generator, dst);
+
ASSERT(m_expr->isDotAccessorNode());
DotAccessorNode* dotAccessor = static_cast<DotAccessorNode*>(m_expr);
ExpressionNode* baseNode = dotAccessor->base();
@@ -670,16 +684,10 @@ RegisterID* PostfixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
RefPtr<RegisterID> base = generator.emitNode(baseNode);
- generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
+ generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStartOffset(), dotAccessor->divotEndOffset(), dotAccessor->divotLine(), dotAccessor->divotLineStart());
RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
- if (dst == generator.ignoredResult()) {
- emitPreIncOrDec(generator, value.get(), m_operator);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutById(base.get(), ident, value.get());
- return 0;
- }
RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitPutById(base.get(), ident, value.get());
return generator.moveToDestinationIfNeeded(dst, oldValue);
}
@@ -708,7 +716,7 @@ RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
if (resolveResult.isRegister())
return generator.emitLoad(generator.finalDestination(dst), false);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), resolveResult, m_ident);
return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
}
@@ -720,7 +728,7 @@ RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
RefPtr<RegisterID> r0 = generator.emitNode(m_base);
RegisterID* r1 = generator.emitNode(m_subscript);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
}
@@ -730,7 +738,7 @@ RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
{
RegisterID* r0 = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
}
@@ -767,6 +775,11 @@ RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
return generator.emitTypeOf(generator.finalDestination(dst), local);
}
+ if (resolveResult.isStatic()) {
+ RefPtr<RegisterID> scratch = generator.emitGetStaticVar(generator.tempDestination(dst), resolveResult, m_ident);
+ return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
+ }
+
RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), resolveResult, m_ident);
generator.emitGetById(scratch.get(), scratch.get(), m_ident);
if (dst == generator.ignoredResult())
@@ -795,24 +808,27 @@ RegisterID* PrefixNode::emitResolve(BytecodeGenerator& generator, RegisterID* ds
const Identifier& ident = resolve->identifier();
ResolveResult resolveResult = generator.resolve(ident);
- if (RegisterID* local = resolveResult.local()) {
+ if (RefPtr<RegisterID> local = resolveResult.local()) {
if (resolveResult.isReadOnly()) {
generator.emitReadOnlyExceptionIfNeeded();
- if (dst == generator.ignoredResult())
- return generator.emitToJSNumber(generator.newTemporary(), local);
- RefPtr<RegisterID> r0 = generator.emitLoad(generator.tempDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
- generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
- return generator.moveToDestinationIfNeeded(dst, r0.get());
+ local = generator.emitMove(generator.tempDestination(dst), local.get());
}
- emitPreIncOrDec(generator, local, m_operator);
- return generator.moveToDestinationIfNeeded(dst, local);
+ emitIncOrDec(generator, local.get(), m_operator);
+ return generator.moveToDestinationIfNeeded(dst, local.get());
+ }
+
+ if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
+ RefPtr<RegisterID> propDst = generator.emitGetStaticVar(generator.tempDestination(dst), resolveResult, ident);
+ emitIncOrDec(generator, propDst.get(), m_operator);
+ generator.emitPutStaticVar(resolveResult, ident, propDst.get());
+ return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
NonlocalResolveInfo resolveVerifier;
RefPtr<RegisterID> base = generator.emitResolveWithBaseForPut(generator.newTemporary(), propDst.get(), resolveResult, ident, resolveVerifier);
- emitPreIncOrDec(generator, propDst.get(), m_operator);
+ emitIncOrDec(generator, propDst.get(), m_operator);
generator.emitPutToBase(base.get(), ident, propDst.get(), resolveVerifier);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
@@ -828,10 +844,10 @@ RegisterID* PrefixNode::emitBracket(BytecodeGenerator& generator, RegisterID* ds
RefPtr<RegisterID> property = generator.emitNode(subscript);
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
- generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
+ generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStartOffset(), bracketAccessor->divotEndOffset(), bracketAccessor->divotLine(), bracketAccessor->divotLineStart());
RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
- emitPreIncOrDec(generator, value, m_operator);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ emitIncOrDec(generator, value, m_operator);
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitPutByVal(base.get(), property.get(), value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
@@ -846,10 +862,10 @@ RegisterID* PrefixNode::emitDot(BytecodeGenerator& generator, RegisterID* dst)
RefPtr<RegisterID> base = generator.emitNode(baseNode);
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
- generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
+ generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStartOffset(), dotAccessor->divotEndOffset(), dotAccessor->divotLine(), dotAccessor->divotLineStart());
RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
- emitPreIncOrDec(generator, value, m_operator);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ emitIncOrDec(generator, value, m_operator);
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitPutById(base.get(), ident, value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
@@ -875,6 +891,7 @@ RegisterID* PrefixNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RegisterID* src = generator.emitNode(m_expr);
+ generator.emitExpressionInfo(startOffset(), 0, 0, lineNo(), lineStartOffset());
return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
}
@@ -889,12 +906,10 @@ RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterI
// ------------------------------ LogicalNotNode -----------------------------------
-void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
+void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
{
- ASSERT(expr()->hasConditionContextCodegen());
-
// reverse the true and false targets
- generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, !fallThroughMeansTrue);
+ generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, invert(fallThroughMode));
}
@@ -1008,7 +1023,7 @@ RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* d
// Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
// If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
if (emitExpressionInfoForMe)
- generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
+ generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStartOffset(), emitExpressionInfoForMe->divotEndOffset(), emitExpressionInfoForMe->divotLine(), emitExpressionInfoForMe->divotLineStart());
// If there is an assignment convert the lhs now. This will also copy lhs to
// the temporary register we allocated for it.
@@ -1018,12 +1033,72 @@ RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* d
return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
}
+void BinaryOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
+{
+ TriState branchCondition;
+ ExpressionNode* branchExpression;
+ tryFoldToBranch(generator, branchCondition, branchExpression);
+
+ if (branchCondition == MixedTriState)
+ ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode);
+ else if (branchCondition == TrueTriState)
+ generator.emitNodeInConditionContext(branchExpression, trueTarget, falseTarget, fallThroughMode);
+ else
+ generator.emitNodeInConditionContext(branchExpression, falseTarget, trueTarget, invert(fallThroughMode));
+}
+
+static inline bool canFoldToBranch(OpcodeID opcodeID, ExpressionNode* branchExpression, JSValue constant)
+{
+ ResultType expressionType = branchExpression->resultDescriptor();
+
+ if (expressionType.definitelyIsBoolean() && constant.isBoolean())
+ return true;
+ else if (expressionType.definitelyIsBoolean() && constant.isInt32() && (constant.asInt32() == 0 || constant.asInt32() == 1))
+ return opcodeID == op_eq || opcodeID == op_neq; // Strict equality is false in the case of type mismatch.
+ else if (expressionType.isInt32() && constant.isInt32() && constant.asInt32() == 0)
+ return true;
+
+ return false;
+}
+
+void BinaryOpNode::tryFoldToBranch(BytecodeGenerator& generator, TriState& branchCondition, ExpressionNode*& branchExpression)
+{
+ branchCondition = MixedTriState;
+ branchExpression = 0;
+
+ ConstantNode* constant = 0;
+ if (m_expr1->isConstant()) {
+ constant = static_cast<ConstantNode*>(m_expr1);
+ branchExpression = m_expr2;
+ } else if (m_expr2->isConstant()) {
+ constant = static_cast<ConstantNode*>(m_expr2);
+ branchExpression = m_expr1;
+ }
+
+ if (!constant)
+ return;
+ ASSERT(branchExpression);
+
+ OpcodeID opcodeID = this->opcodeID();
+ JSValue value = constant->jsValue(generator);
+ bool canFoldToBranch = JSC::canFoldToBranch(opcodeID, branchExpression, value);
+ if (!canFoldToBranch)
+ return;
+
+ if (opcodeID == op_eq || opcodeID == op_stricteq)
+ branchCondition = triState(value.pureToBoolean());
+ else if (opcodeID == op_neq || opcodeID == op_nstricteq)
+ branchCondition = triState(!value.pureToBoolean());
+}
+
RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
OpcodeID opcodeID = this->opcodeID();
- if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString())
+ if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) {
+ generator.emitExpressionInfo(startOffset(), 0, 0, lineNo(), lineStartOffset());
return emitStrcat(generator, dst);
+ }
if (opcodeID == op_neq) {
if (m_expr1->isNull() || m_expr2->isNull()) {
@@ -1033,19 +1108,28 @@ RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
}
}
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
- if (generator.m_lastOpcodeID == op_typeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
+ ExpressionNode* left = m_expr1;
+ ExpressionNode* right = m_expr2;
+ if (opcodeID == op_neq || opcodeID == op_nstricteq) {
+ if (left->isString())
+ std::swap(left, right);
+ }
+
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, right->isPure(generator));
+ bool wasTypeof = generator.m_lastOpcodeID == op_typeof;
+ RegisterID* src2 = generator.emitNode(right);
+ generator.emitExpressionInfo(startOffset(), 0, 0, lineNo(), lineStartOffset());
+ if (wasTypeof && (opcodeID == op_neq || opcodeID == op_nstricteq)) {
RefPtr<RegisterID> tmp = generator.tempDestination(dst);
if (opcodeID == op_neq)
generator.emitEqualityOp(op_eq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2);
else if (opcodeID == op_nstricteq)
generator.emitEqualityOp(op_stricteq, generator.finalDestination(tmp.get(), src1.get()), src1.get(), src2);
else
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return generator.emitUnaryOp(op_not, generator.finalDestination(dst, tmp.get()), tmp.get());
}
- return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
+ return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(left->resultDescriptor(), right->resultDescriptor()));
}
RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
@@ -1056,15 +1140,25 @@ RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
}
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
+ ExpressionNode* left = m_expr1;
+ ExpressionNode* right = m_expr2;
+ if (left->isString())
+ std::swap(left, right);
+
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(right);
return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
+ ExpressionNode* left = m_expr1;
+ ExpressionNode* right = m_expr2;
+ if (left->isString())
+ std::swap(left, right);
+
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(left, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(right);
return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
@@ -1072,7 +1166,7 @@ RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, Re
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_expr2);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
}
@@ -1084,13 +1178,13 @@ RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterI
RefPtr<RegisterID> dstReg = generator.finalDestination(dst, src1.get());
RefPtr<Label> target = generator.newLabel();
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get());
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitGetById(prototype.get(), src2.get(), generator.globalData()->propertyNames->prototype);
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
+ generator.emitGetById(prototype.get(), src2.get(), generator.vm()->propertyNames->prototype);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), prototype.get());
generator.emitLabel(target.get());
return result;
@@ -1114,32 +1208,16 @@ RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID
return generator.moveToDestinationIfNeeded(dst, temp.get());
}
-void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
+void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode)
{
- if (m_expr1->hasConditionContextCodegen()) {
- RefPtr<Label> afterExpr1 = generator.newLabel();
- if (m_operator == OpLogicalAnd)
- generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, true);
- else
- generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), false);
- generator.emitLabel(afterExpr1.get());
- } else {
- RegisterID* temp = generator.emitNode(m_expr1);
- if (m_operator == OpLogicalAnd)
- generator.emitJumpIfFalse(temp, falseTarget);
- else
- generator.emitJumpIfTrue(temp, trueTarget);
- }
+ RefPtr<Label> afterExpr1 = generator.newLabel();
+ if (m_operator == OpLogicalAnd)
+ generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, FallThroughMeansTrue);
+ else
+ generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), FallThroughMeansFalse);
+ generator.emitLabel(afterExpr1.get());
- if (m_expr2->hasConditionContextCodegen())
- generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMeansTrue);
- else {
- RegisterID* temp = generator.emitNode(m_expr2);
- if (fallThroughMeansTrue)
- generator.emitJumpIfFalse(temp, falseTarget);
- else
- generator.emitJumpIfTrue(temp, trueTarget);
- }
+ generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMode);
}
// ------------------------------ ConditionalNode ------------------------------
@@ -1150,14 +1228,9 @@ RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, Register
RefPtr<Label> beforeElse = generator.newLabel();
RefPtr<Label> afterElse = generator.newLabel();
- if (m_logical->hasConditionContextCodegen()) {
- RefPtr<Label> beforeThen = generator.newLabel();
- generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true);
- generator.emitLabel(beforeThen.get());
- } else {
- RegisterID* cond = generator.emitNode(m_logical);
- generator.emitJumpIfFalse(cond, beforeElse.get());
- }
+ RefPtr<Label> beforeThen = generator.newLabel();
+ generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), FallThroughMeansTrue);
+ generator.emitLabel(beforeThen.get());
generator.emitNode(newDst.get(), m_expr1);
generator.emitJump(afterElse.get());
@@ -1213,7 +1286,7 @@ static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& gen
opcodeID = op_mod;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return dst;
}
@@ -1222,7 +1295,7 @@ static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& gen
// Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
// If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
if (emitExpressionInfoForMe)
- generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
+ generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStartOffset(), emitExpressionInfoForMe->divotEndOffset(), emitExpressionInfoForMe->divotLine(), emitExpressionInfoForMe->divotLineStart());
return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
}
@@ -1249,8 +1322,15 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re
return generator.moveToDestinationIfNeeded(dst, result);
}
+ if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
+ RefPtr<RegisterID> src1 = generator.emitGetStaticVar(generator.tempDestination(dst), resolveResult, m_ident);
+ RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+ generator.emitPutStaticVar(resolveResult, m_ident, result);
+ return result;
+ }
+
RefPtr<RegisterID> src1 = generator.tempDestination(dst);
- generator.emitExpressionInfo(divot() - startOffset() + m_ident.length(), m_ident.length(), 0);
+ generator.emitExpressionInfo(divot() - divotStartOffset() + m_ident.length(), m_ident.length(), 0, divotLine(), divotLineStart());
NonlocalResolveInfo resolveVerifier;
RefPtr<RegisterID> base = generator.emitResolveWithBaseForPut(generator.newTemporary(), src1.get(), resolveResult, m_ident, resolveVerifier);
RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
@@ -1272,12 +1352,22 @@ RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
return generator.moveToDestinationIfNeeded(dst, result);
}
+ if (resolveResult.isStatic() && !resolveResult.isReadOnly()) {
+ if (dst == generator.ignoredResult())
+ dst = 0;
+ RegisterID* value = generator.emitNode(dst, m_right);
+ generator.emitPutStaticVar(resolveResult, m_ident, value);
+ return value;
+ }
+
NonlocalResolveInfo resolveVerifier;
+ if (generator.isStrictMode())
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RefPtr<RegisterID> base = generator.emitResolveBaseForPut(generator.newTemporary(), resolveResult, m_ident, resolveVerifier);
if (dst == generator.ignoredResult())
dst = 0;
RegisterID* value = generator.emitNode(dst, m_right);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitPutToBase(base.get(), m_ident, value, resolveVerifier);
}
@@ -1288,7 +1378,7 @@ RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
RegisterID* result = generator.emitNode(value.get(), m_right);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
generator.emitPutById(base.get(), m_ident, forwardResult);
return generator.moveToDestinationIfNeeded(dst, forwardResult);
@@ -1300,11 +1390,11 @@ RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, Regist
{
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
return generator.emitPutById(base.get(), m_ident, updatedValue);
}
@@ -1324,7 +1414,7 @@ RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
RegisterID* result = generator.emitNode(value.get(), m_right);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
generator.emitPutByVal(base.get(), property.get(), forwardResult);
return generator.moveToDestinationIfNeeded(dst, forwardResult);
@@ -1337,11 +1427,11 @@ RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, Re
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitPutByVal(base.get(), property.get(), updatedValue);
return updatedValue;
@@ -1373,10 +1463,9 @@ RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
- if (generator.codeType() == GlobalCode) {
- if (RegisterID* result = generator.emitInitGlobalConst(m_ident, value.get()))
- return result;
- }
+ if (generator.codeType() == GlobalCode)
+ return generator.emitInitGlobalConst(m_ident, value.get());
+
if (generator.codeType() != EvalCode)
return value.get();
@@ -1396,10 +1485,10 @@ RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID
// ------------------------------ ConstStatementNode -----------------------------
-RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+void ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return generator.emitNode(m_next);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
+ generator.emitNode(m_next);
}
// ------------------------------ SourceElements -------------------------------
@@ -1430,142 +1519,143 @@ inline StatementNode* BlockNode::singleStatement() const
return m_statements ? m_statements->singleStatement() : 0;
}
-RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_statements)
- m_statements->emitBytecode(generator, dst);
- return 0;
+ if (!m_statements)
+ return;
+ m_statements->emitBytecode(generator, dst);
}
// ------------------------------ EmptyStatementNode ---------------------------
-RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return dst;
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
}
// ------------------------------ DebuggerStatementNode ---------------------------
-RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), column());
- return dst;
+ generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), startOffset(), lineStartOffset());
}
// ------------------------------ ExprStatementNode ----------------------------
-RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return generator.emitNode(dst, m_expr);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
+ generator.emitNode(dst, m_expr);
}
// ------------------------------ VarStatementNode ----------------------------
-RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+void VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return generator.emitNode(m_expr);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
+ generator.emitNode(m_expr);
}
-// ------------------------------ IfNode ---------------------------------------
+// ------------------------------ IfElseNode ---------------------------------------
-RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+static inline StatementNode* singleStatement(StatementNode* statementNode)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- RefPtr<Label> afterThen = generator.newLabel();
+ if (statementNode->isBlock())
+ return static_cast<BlockNode*>(statementNode)->singleStatement();
+ return statementNode;
+}
- if (m_condition->hasConditionContextCodegen()) {
- RefPtr<Label> beforeThen = generator.newLabel();
- generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), true);
- generator.emitLabel(beforeThen.get());
- } else {
- RegisterID* cond = generator.emitNode(m_condition);
- generator.emitJumpIfFalse(cond, afterThen.get());
+bool IfElseNode::tryFoldBreakAndContinue(BytecodeGenerator& generator, StatementNode* ifBlock,
+ Label*& trueTarget, FallThroughMode& fallThroughMode)
+{
+ StatementNode* singleStatement = JSC::singleStatement(ifBlock);
+ if (!singleStatement)
+ return false;
+
+ if (singleStatement->isBreak()) {
+ BreakNode* breakNode = static_cast<BreakNode*>(singleStatement);
+ Label* target = breakNode->trivialTarget(generator);
+ if (!target)
+ return false;
+ trueTarget = target;
+ fallThroughMode = FallThroughMeansFalse;
+ return true;
}
- generator.emitNode(dst, m_ifBlock);
- generator.emitLabel(afterThen.get());
+ if (singleStatement->isContinue()) {
+ ContinueNode* continueNode = static_cast<ContinueNode*>(singleStatement);
+ Label* target = continueNode->trivialTarget(generator);
+ if (!target)
+ return false;
+ trueTarget = target;
+ fallThroughMode = FallThroughMeansFalse;
+ return true;
+ }
- // FIXME: This should return the last statement executed so that it can be returned as a Completion.
- return 0;
+ return false;
}
-// ------------------------------ IfElseNode ---------------------------------------
-
-RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
+ RefPtr<Label> beforeThen = generator.newLabel();
RefPtr<Label> beforeElse = generator.newLabel();
RefPtr<Label> afterElse = generator.newLabel();
- if (m_condition->hasConditionContextCodegen()) {
- RefPtr<Label> beforeThen = generator.newLabel();
- generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), true);
- generator.emitLabel(beforeThen.get());
- } else {
- RegisterID* cond = generator.emitNode(m_condition);
- generator.emitJumpIfFalse(cond, beforeElse.get());
- }
+ Label* trueTarget = beforeThen.get();
+ Label* falseTarget = beforeElse.get();
+ FallThroughMode fallThroughMode = FallThroughMeansTrue;
+ bool didFoldIfBlock = tryFoldBreakAndContinue(generator, m_ifBlock, trueTarget, fallThroughMode);
- generator.emitNode(dst, m_ifBlock);
- generator.emitJump(afterElse.get());
+ generator.emitNodeInConditionContext(m_condition, trueTarget, falseTarget, fallThroughMode);
+ generator.emitLabel(beforeThen.get());
+
+ if (!didFoldIfBlock) {
+ generator.emitNode(dst, m_ifBlock);
+ if (m_elseBlock)
+ generator.emitJump(afterElse.get());
+ }
generator.emitLabel(beforeElse.get());
- generator.emitNode(dst, m_elseBlock);
+ if (m_elseBlock)
+ generator.emitNode(dst, m_elseBlock);
generator.emitLabel(afterElse.get());
-
- // FIXME: This should return the last statement executed so that it can be returned as a Completion.
- return 0;
}
// ------------------------------ DoWhileNode ----------------------------------
-RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
generator.emitLoopHint();
- generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), startOffset(), lineStartOffset());
- RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
+ generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), column());
- if (m_expr->hasConditionContextCodegen())
- generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
- else {
- RegisterID* cond = generator.emitNode(m_expr);
- generator.emitJumpIfTrue(cond, topOfLoop.get());
- }
+ generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), startOffset(), lineStartOffset());
+ generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
generator.emitLabel(scope->breakTarget());
- return result.get();
}
// ------------------------------ WhileNode ------------------------------------
-RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
RefPtr<Label> topOfLoop = generator.newLabel();
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->columnNo());
- if (m_expr->hasConditionContextCodegen())
- generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), true);
- else {
- RegisterID* cond = generator.emitNode(m_expr);
- generator.emitJumpIfFalse(cond, scope->breakTarget());
- }
+ generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->startOffset(), m_expr->lineStartOffset());
+ generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
generator.emitLabel(topOfLoop.get());
generator.emitLoopHint();
@@ -1573,76 +1663,58 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
- if (m_expr->hasConditionContextCodegen())
- generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
- else {
- RegisterID* cond = generator.emitNode(m_expr);
- generator.emitJumpIfTrue(cond, topOfLoop.get());
- }
+ generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
generator.emitLabel(scope->breakTarget());
-
- // FIXME: This should return the last statement executed so that it can be returned as a Completion
- return 0;
}
// ------------------------------ ForNode --------------------------------------
-RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
if (m_expr1)
generator.emitNode(generator.ignoredResult(), m_expr1);
RefPtr<Label> topOfLoop = generator.newLabel();
- if (m_expr2) {
- if (m_expr2->hasConditionContextCodegen())
- generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), true);
- else {
- RegisterID* cond = generator.emitNode(m_expr2);
- generator.emitJumpIfFalse(cond, scope->breakTarget());
- }
- }
+ if (m_expr2)
+ generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
generator.emitLabel(topOfLoop.get());
generator.emitLoopHint();
- RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
+ generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
if (m_expr3)
generator.emitNode(generator.ignoredResult(), m_expr3);
- if (m_expr2) {
- if (m_expr2->hasConditionContextCodegen())
- generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false);
- else {
- RegisterID* cond = generator.emitNode(m_expr2);
- generator.emitJumpIfTrue(cond, topOfLoop.get());
- }
- } else
+ if (m_expr2)
+ generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
+ else
generator.emitJump(topOfLoop.get());
generator.emitLabel(scope->breakTarget());
- return result.get();
}
// ------------------------------ ForInNode ------------------------------------
-RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
- if (!m_lexpr->isLocation())
- return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
+ if (!m_lexpr->isLocation()) {
+ emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
+ return;
+ }
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
if (m_init)
generator.emitNode(generator.ignoredResult(), m_init);
@@ -1669,9 +1741,11 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
propertyName = generator.newTemporary();
RefPtr<RegisterID> protect = propertyName;
NonlocalResolveInfo resolveVerifier;
+ if (generator.isStrictMode())
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
RegisterID* base = generator.emitResolveBaseForPut(generator.newTemporary(), resolveResult, ident, resolveVerifier);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitPutToBase(base, ident, propertyName, resolveVerifier);
} else {
expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
@@ -1685,7 +1759,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RefPtr<RegisterID> protect = propertyName;
RegisterID* base = generator.emitNode(assignNode->base());
- generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
+ generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStartOffset(), assignNode->divotEndOffset(), assignNode->divotLine(), assignNode->divotLineStart());
generator.emitPutById(base, ident, propertyName);
} else {
ASSERT(m_lexpr->isBracketAccessorNode());
@@ -1695,7 +1769,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
RegisterID* subscript = generator.emitNode(assignNode->subscript());
- generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
+ generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStartOffset(), assignNode->divotEndOffset(), assignNode->divotLine(), assignNode->divotLineStart());
generator.emitPutByVal(base.get(), subscript, propertyName);
}
@@ -1706,83 +1780,104 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitLabel(scope->continueTarget());
generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
generator.emitLabel(scope->breakTarget());
- return dst;
}
// ------------------------------ ContinueNode ---------------------------------
-// ECMA 12.7
-RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+Label* ContinueNode::trivialTarget(BytecodeGenerator& generator)
+{
+ if (generator.shouldEmitDebugHooks())
+ return 0;
+
+ LabelScope* scope = generator.continueTarget(m_ident);
+ ASSERT(scope);
+
+ if (generator.scopeDepth() != scope->scopeDepth())
+ return 0;
+
+ return scope->continueTarget();
+}
+
+void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
LabelScope* scope = generator.continueTarget(m_ident);
ASSERT(scope);
- generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
- return dst;
+ generator.emitPopScopes(scope->scopeDepth());
+ generator.emitJump(scope->continueTarget());
}
// ------------------------------ BreakNode ------------------------------------
-// ECMA 12.8
-RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+Label* BreakNode::trivialTarget(BytecodeGenerator& generator)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ if (generator.shouldEmitDebugHooks())
+ return 0;
+
+ LabelScope* scope = generator.breakTarget(m_ident);
+ ASSERT(scope);
+
+ if (generator.scopeDepth() != scope->scopeDepth())
+ return 0;
+
+ return scope->breakTarget();
+}
+
+void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
LabelScope* scope = generator.breakTarget(m_ident);
ASSERT(scope);
- generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
- return dst;
+ generator.emitPopScopes(scope->scopeDepth());
+ generator.emitJump(scope->breakTarget());
}
// ------------------------------ ReturnNode -----------------------------------
-RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
ASSERT(generator.codeType() == FunctionCode);
if (dst == generator.ignoredResult())
dst = 0;
- RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
- RefPtr<RegisterID> returnRegister;
+
+ RefPtr<RegisterID> returnRegister = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
if (generator.scopeDepth()) {
- RefPtr<Label> l0 = generator.newLabel();
- if (generator.hasFinaliser()) {
- returnRegister = generator.emitMove(generator.newTemporary(), r0);
- r0 = returnRegister.get();
- }
- generator.emitJumpScopes(l0.get(), 0);
- generator.emitLabel(l0.get());
+ returnRegister = generator.emitMove(generator.newTemporary(), returnRegister.get());
+ generator.emitPopScopes(0);
}
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
- return generator.emitReturn(r0);
+
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), startOffset(), lineStartOffset());
+ generator.emitReturn(returnRegister.get());
}
// ------------------------------ WithNode -------------------------------------
-RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
RefPtr<RegisterID> scope = generator.emitNode(m_expr);
- generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
+ generator.emitExpressionInfo(m_divot, m_expressionLength, 0, m_divotLine, m_divotLineStart);
generator.emitPushWithScope(scope.get());
- RegisterID* result = generator.emitNode(dst, m_statement);
+ generator.emitNode(dst, m_statement);
generator.emitPopScope();
- return result;
}
// ------------------------------ CaseClauseNode --------------------------------
inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_statements)
- m_statements->emitBytecode(generator, dst);
+ if (!m_statements)
+ return;
+ m_statements->emitBytecode(generator, dst);
}
// ------------------------------ CaseBlockNode --------------------------------
@@ -1833,9 +1928,22 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>&
break;
}
}
-
-SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
+
+static inline size_t length(ClauseListNode* list1, ClauseListNode* list2)
+{
+ size_t length = 0;
+ for (ClauseListNode* node = list1; node; node = node->getNext())
+ ++length;
+ for (ClauseListNode* node = list2; node; node = node->getNext())
+ ++length;
+ return length;
+}
+
+SwitchInfo::SwitchType CaseBlockNode::tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
{
+ if (length(m_list1, m_list2) < s_tableSwitchMinimum)
+ return SwitchInfo::SwitchNone;
+
SwitchKind typeForTable = SwitchUnset;
bool singleCharacterSwitch = true;
@@ -1863,14 +1971,14 @@ SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*,
return SwitchInfo::SwitchString;
}
-RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
+void CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
{
RefPtr<Label> defaultLabel;
Vector<RefPtr<Label>, 8> labelVector;
Vector<ExpressionNode*, 8> literalVector;
int32_t min_num = std::numeric_limits<int32_t>::max();
int32_t max_num = std::numeric_limits<int32_t>::min();
- SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
+ SwitchInfo::SwitchType switchType = tryTableSwitch(literalVector, min_num, max_num);
if (switchType != SwitchInfo::SwitchNone) {
// Prepare the various labels
@@ -1899,8 +2007,6 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
generator.emitJump(defaultLabel.get());
}
- RegisterID* result = 0;
-
size_t i = 0;
for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
generator.emitLabel(labelVector[i++].get());
@@ -1924,61 +2030,57 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
ASSERT(labelVector.size() == literalVector.size());
generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
}
- return result;
}
// ------------------------------ SwitchNode -----------------------------------
-RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
- RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
+ m_block->emitBytecodeForBlock(generator, r0.get(), dst);
generator.emitLabel(scope->breakTarget());
- return r1;
}
// ------------------------------ LabelNode ------------------------------------
-RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
ASSERT(!generator.breakTarget(m_name));
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
- RegisterID* r0 = generator.emitNode(dst, m_statement);
+ LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
+ generator.emitNode(dst, m_statement);
generator.emitLabel(scope->breakTarget());
- return r0;
}
// ------------------------------ ThrowNode ------------------------------------
-RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
if (dst == generator.ignoredResult())
dst = 0;
RefPtr<RegisterID> expr = generator.emitNode(m_expr);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
generator.emitThrow(expr.get());
- return 0;
}
// ------------------------------ TryNode --------------------------------------
-RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
// NOTE: The catch and finally blocks must be labeled explicitly, so the
// optimizer knows they may be jumped to from anywhere.
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
ASSERT(m_catchBlock || m_finallyBlock);
@@ -2031,53 +2133,50 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
generator.emitLabel(finallyEndLabel.get());
}
-
- return dst;
}
// ------------------------------ ScopeNode -----------------------------
inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_statements)
- m_statements->emitBytecode(generator, dst);
+ if (!m_statements)
+ return;
+ m_statements->emitBytecode(generator, dst);
}
// ------------------------------ ProgramNode -----------------------------
-RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startStartOffset(), startLineStartOffset());
RefPtr<RegisterID> dstRegister = generator.newTemporary();
generator.emitLoad(dstRegister.get(), jsUndefined());
emitStatementsBytecode(generator, dstRegister.get());
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), startOffset(), lineStartOffset());
generator.emitEnd(dstRegister.get());
- return 0;
}
// ------------------------------ EvalNode -----------------------------
-RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startStartOffset(), startLineStartOffset());
RefPtr<RegisterID> dstRegister = generator.newTemporary();
generator.emitLoad(dstRegister.get(), jsUndefined());
emitStatementsBytecode(generator, dstRegister.get());
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), startOffset(), lineStartOffset());
generator.emitEnd(dstRegister.get());
- return 0;
}
// ------------------------------ FunctionBodyNode -----------------------------
-RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+void FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidEnterCallFrame, startLine(), startLine(), startStartOffset(), startLineStartOffset());
emitStatementsBytecode(generator, generator.ignoredResult());
StatementNode* singleStatement = this->singleStatement();
@@ -2093,9 +2192,10 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe
// If there is no return we must automatically insert one.
if (!returnNode) {
RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
+ ASSERT((startOffset() - 1) >= lineStartOffset());
+ generator.emitDebugHook(WillLeaveCallFrame, lastLine(), lastLine(), startOffset() - 1, lineStartOffset());
generator.emitReturn(r0);
- return 0;
+ return;
}
// If there is a return statment, and it is the only statement in the function, check if this is a numeric compare.
@@ -2113,17 +2213,12 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe
}
}
}
-
- return 0;
}
// ------------------------------ FuncDeclNode ---------------------------------
-RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+void FuncDeclNode::emitBytecode(BytecodeGenerator&, RegisterID*)
{
- if (dst == generator.ignoredResult())
- dst = 0;
- return dst;
}
// ------------------------------ FuncExprNode ---------------------------------
diff --git a/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h
new file mode 100644
index 000000000..78ee17adf
--- /dev/null
+++ b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalysis.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StaticPropertyAnalysis_h
+#define StaticPropertyAnalysis_h
+
+#include "Executable.h"
+#include "JSGlobalObject.h"
+#include <wtf/HashSet.h>
+
+namespace JSC {
+
+// Reference count indicates number of live registers that alias this object.
+class StaticPropertyAnalysis : public RefCounted<StaticPropertyAnalysis> {
+public:
+ static PassRefPtr<StaticPropertyAnalysis> create(Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* instructions, unsigned target)
+ {
+ return adoptRef(new StaticPropertyAnalysis(instructions, target));
+ }
+
+ void addPropertyIndex(unsigned propertyIndex) { m_propertyIndexes.add(propertyIndex); }
+
+ void record()
+ {
+ (*m_instructions)[m_target] = m_propertyIndexes.size();
+ }
+
+ int propertyIndexCount() { return m_propertyIndexes.size(); }
+
+private:
+ StaticPropertyAnalysis(Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* instructions, unsigned target)
+ : m_instructions(instructions)
+ , m_target(target)
+ {
+ }
+
+ Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* m_instructions;
+ unsigned m_target;
+ typedef HashSet<unsigned, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > PropertyIndexSet;
+ PropertyIndexSet m_propertyIndexes;
+};
+
+} // namespace JSC
+
+#endif // StaticPropertyAnalysis_h
diff --git a/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h
new file mode 100644
index 000000000..dd7f0ab38
--- /dev/null
+++ b/Source/JavaScriptCore/bytecompiler/StaticPropertyAnalyzer.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StaticPropertyAnalyzer_h
+#define StaticPropertyAnalyzer_h
+
+#include "StaticPropertyAnalysis.h"
+#include <wtf/HashMap.h>
+
+namespace JSC {
+
+// Used for flow-insensitive static analysis of the number of properties assigned to an object.
+// We use this analysis with other runtime data to produce an optimization guess. This analysis
+// is understood to be lossy, and it's OK if it turns out to be wrong sometimes.
+class StaticPropertyAnalyzer {
+public:
+ StaticPropertyAnalyzer(Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>*);
+
+ void createThis(int dst, unsigned offsetOfInlineCapacityOperand);
+ void newObject(int dst, unsigned offsetOfInlineCapacityOperand);
+ void putById(int dst, unsigned propertyIndex); // propertyIndex is an index into a uniqued set of strings.
+ void mov(int dst, int src);
+
+ void kill();
+ void kill(int dst);
+
+private:
+ void kill(StaticPropertyAnalysis*);
+
+ Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* m_instructions;
+ typedef HashMap<int, RefPtr<StaticPropertyAnalysis>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int> > AnalysisMap;
+ AnalysisMap m_analyses;
+};
+
+inline StaticPropertyAnalyzer::StaticPropertyAnalyzer(Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>* instructions)
+ : m_instructions(instructions)
+{
+}
+
+inline void StaticPropertyAnalyzer::createThis(int dst, unsigned offsetOfInlineCapacityOperand)
+{
+ AnalysisMap::AddResult addResult = m_analyses.add(
+ dst, StaticPropertyAnalysis::create(m_instructions, offsetOfInlineCapacityOperand));
+ ASSERT_UNUSED(addResult, addResult.isNewEntry); // Can't have two 'this' in the same constructor.
+}
+
+inline void StaticPropertyAnalyzer::newObject(int dst, unsigned offsetOfInlineCapacityOperand)
+{
+ RefPtr<StaticPropertyAnalysis> analysis = StaticPropertyAnalysis::create(m_instructions, offsetOfInlineCapacityOperand);
+ AnalysisMap::AddResult addResult = m_analyses.add(dst, analysis);
+ if (!addResult.isNewEntry) {
+ kill(addResult.iterator->value.get());
+ addResult.iterator->value = analysis.release();
+ }
+}
+
+inline void StaticPropertyAnalyzer::putById(int dst, unsigned propertyIndex)
+{
+ StaticPropertyAnalysis* analysis = m_analyses.get(dst);
+ if (!analysis)
+ return;
+ analysis->addPropertyIndex(propertyIndex);
+}
+
+inline void StaticPropertyAnalyzer::mov(int dst, int src)
+{
+ RefPtr<StaticPropertyAnalysis> analysis = m_analyses.get(src);
+ if (!analysis) {
+ kill(dst);
+ return;
+ }
+
+ AnalysisMap::AddResult addResult = m_analyses.add(dst, analysis);
+ if (!addResult.isNewEntry) {
+ kill(addResult.iterator->value.get());
+ addResult.iterator->value = analysis.release();
+ }
+}
+
+inline void StaticPropertyAnalyzer::kill(StaticPropertyAnalysis* analysis)
+{
+ if (!analysis)
+ return;
+ if (!analysis->hasOneRef()) // Aliases for this object still exist, so it might acquire more properties.
+ return;
+ analysis->record();
+}
+
+inline void StaticPropertyAnalyzer::kill(int dst)
+{
+ // We observe kills in order to avoid piling on properties to an object after
+ // its bytecode register has been recycled.
+
+ // Consider these cases:
+
+ // (1) Aliased temporary
+ // var o1 = { name: name };
+ // var o2 = { name: name };
+
+ // (2) Aliased local -- no control flow
+ // var local;
+ // local = new Object;
+ // local.name = name;
+ // ...
+
+ // local = lookup();
+ // local.didLookup = true;
+ // ...
+
+ // (3) Aliased local -- control flow
+ // var local;
+ // if (condition)
+ // local = { };
+ // else {
+ // local = new Object;
+ // }
+ // local.name = name;
+
+ // (Note: our default codegen for "new Object" looks like case (3).)
+
+ // Case (1) is easy because temporaries almost never survive across control flow.
+
+ // Cases (2) and (3) are hard. Case (2) should kill "local", while case (3) should
+ // not. There is no great way to solve these cases with simple static analysis.
+
+ // Since this is a simple static analysis, we just try to catch the simplest cases,
+ // so we accept kills to any registers except for registers that have no inferred
+ // properties yet.
+
+ AnalysisMap::iterator it = m_analyses.find(dst);
+ if (it == m_analyses.end())
+ return;
+ if (!it->value->propertyIndexCount())
+ return;
+
+ kill(it->value.get());
+ m_analyses.remove(it);
+}
+
+inline void StaticPropertyAnalyzer::kill()
+{
+ while (m_analyses.size())
+ kill(m_analyses.take(m_analyses.begin()->key).get());
+}
+
+} // namespace JSC
+
+#endif // StaticPropertyAnalyzer_h
diff --git a/Source/JavaScriptCore/config.h b/Source/JavaScriptCore/config.h
index 68ebc960d..4e1d2b91c 100644
--- a/Source/JavaScriptCore/config.h
+++ b/Source/JavaScriptCore/config.h
@@ -29,22 +29,18 @@
#include <wtf/Platform.h>
#include <wtf/ExportMacros.h>
-// WTF cannot depend on JSC even if USE(JSC).
-#if USE(JSC) && !defined(BUILDING_WTF)
+#if !defined(BUILDING_WTF)
#include "JSExportMacros.h"
-#elif PLATFORM(CHROMIUM)
-// Chromium doesn't have runtime/ in its include paths.
-#include "runtime/JSExportMacros.h"
#endif
#if OS(WINDOWS)
#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0502
#endif
#ifndef WINVER
-#define WINVER 0x0500
+#define WINVER 0x0502
#endif
// If we don't define these, they get defined in windef.h.
diff --git a/Source/JavaScriptCore/create_hash_table b/Source/JavaScriptCore/create_hash_table
index cb2809d76..1bd531ae1 100755
--- a/Source/JavaScriptCore/create_hash_table
+++ b/Source/JavaScriptCore/create_hash_table
@@ -271,8 +271,6 @@ sub output() {
}
my $intrinsic = "NoIntrinsic";
- $intrinsic = "CharCodeAtIntrinsic" if ($key eq "charCodeAt");
- $intrinsic = "CharAtIntrinsic" if ($key eq "charAt");
$intrinsic = "FromCharCodeIntrinsic" if ($key eq "fromCharCode");
if ($name eq "mathTable") {
$intrinsic = "MinIntrinsic" if ($key eq "min");
@@ -285,6 +283,7 @@ sub output() {
$intrinsic = "RoundIntrinsic" if ($key eq "round");
$intrinsic = "ExpIntrinsic" if ($key eq "exp");
$intrinsic = "LogIntrinsic" if ($key eq "log");
+ $intrinsic = "IMulIntrinsic" if ($key eq "imul");
}
if ($name eq "arrayPrototypeTable") {
$intrinsic = "ArrayPushIntrinsic" if ($key eq "push");
diff --git a/Source/JavaScriptCore/create_regex_tables b/Source/JavaScriptCore/create_regex_tables
index bd799ba04..7544b75cd 100644
--- a/Source/JavaScriptCore/create_regex_tables
+++ b/Source/JavaScriptCore/create_regex_tables
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 Apple Inc. All rights reserved.
+# Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -90,11 +90,11 @@ for name, classes in types.items():
function += ("{\n")
if emitTables and classes["UseTable"]:
if "Inverse" in classes:
- function += (" CharacterClass* characterClass = new CharacterClass(CharacterClassTable::create(_%sData, true));\n" % (classes["Inverse"]))
+ function += (" CharacterClass* characterClass = new CharacterClass(_%sData, true);\n" % (classes["Inverse"]))
else:
- function += (" CharacterClass* characterClass = new CharacterClass(CharacterClassTable::create(_%sData, false));\n" % (name))
+ function += (" CharacterClass* characterClass = new CharacterClass(_%sData, false);\n" % (name))
else:
- function += (" CharacterClass* characterClass = new CharacterClass(0);\n")
+ function += (" CharacterClass* characterClass = new CharacterClass;\n")
for (min, max) in ranges:
if (min == max):
if (min > 127):
diff --git a/Source/JavaScriptCore/debugger/Debugger.cpp b/Source/JavaScriptCore/debugger/Debugger.cpp
index 7eda52dc8..2c5a1261a 100644
--- a/Source/JavaScriptCore/debugger/Debugger.cpp
+++ b/Source/JavaScriptCore/debugger/Debugger.cpp
@@ -26,6 +26,7 @@
#include "Interpreter.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
#include "Parser.h"
#include "Protect.h"
@@ -110,34 +111,34 @@ void Debugger::detach(JSGlobalObject* globalObject)
globalObject->setDebugger(0);
}
-void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
+void Debugger::recompileAllJSFunctions(VM* vm)
{
// If JavaScript is running, it's not safe to recompile, since we'll end
// up throwing away code that is live on the stack.
- ASSERT(!globalData->dynamicGlobalObject);
- if (globalData->dynamicGlobalObject)
+ ASSERT(!vm->dynamicGlobalObject);
+ if (vm->dynamicGlobalObject)
return;
Recompiler recompiler(this);
- globalData->heap.objectSpace().forEachLiveCell(recompiler);
+ vm->heap.objectSpace().forEachLiveCell(recompiler);
}
JSValue evaluateInGlobalCallFrame(const String& script, JSValue& exception, JSGlobalObject* globalObject)
{
CallFrame* globalCallFrame = globalObject->globalExec();
- JSGlobalData& globalData = globalObject->globalData();
+ VM& vm = globalObject->vm();
- EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
+ EvalExecutable* eval = EvalExecutable::create(globalCallFrame, vm.codeCache(), makeSource(script), false);
if (!eval) {
- exception = globalData.exception;
- globalData.exception = JSValue();
+ exception = vm.exception;
+ vm.exception = JSValue();
return exception;
}
- JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scope());
- if (globalData.exception) {
- exception = globalData.exception;
- globalData.exception = JSValue();
+ JSValue result = vm.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scope());
+ if (vm.exception) {
+ exception = vm.exception;
+ vm.exception = JSValue();
}
ASSERT(result);
return result;
diff --git a/Source/JavaScriptCore/debugger/Debugger.h b/Source/JavaScriptCore/debugger/Debugger.h
index 3c4a4ed76..95dd62b06 100644
--- a/Source/JavaScriptCore/debugger/Debugger.h
+++ b/Source/JavaScriptCore/debugger/Debugger.h
@@ -28,7 +28,7 @@ namespace JSC {
class DebuggerCallFrame;
class ExecState;
- class JSGlobalData;
+ class VM;
class JSGlobalObject;
class JSValue;
class SourceProvider;
@@ -52,7 +52,7 @@ namespace JSC {
virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int, int) = 0;
- void recompileAllJSFunctions(JSGlobalData*);
+ void recompileAllJSFunctions(VM*);
private:
HashSet<JSGlobalObject*> m_globalObjects;
diff --git a/Source/JavaScriptCore/debugger/DebuggerActivation.cpp b/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
index e23468035..eec2d6bd7 100644
--- a/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.cpp
@@ -27,6 +27,7 @@
#include "DebuggerActivation.h"
#include "JSActivation.h"
+#include "Operations.h"
namespace JSC {
@@ -34,17 +35,17 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(DebuggerActivation);
const ClassInfo DebuggerActivation::s_info = { "DebuggerActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(DebuggerActivation) };
-DebuggerActivation::DebuggerActivation(JSGlobalData& globalData)
- : JSNonFinalObject(globalData, globalData.debuggerActivationStructure.get())
+DebuggerActivation::DebuggerActivation(VM& vm)
+ : JSNonFinalObject(vm, vm.debuggerActivationStructure.get())
{
}
-void DebuggerActivation::finishCreation(JSGlobalData& globalData, JSObject* activation)
+void DebuggerActivation::finishCreation(VM& vm, JSObject* activation)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(activation);
ASSERT(activation->isActivationObject());
- m_activation.set(globalData, this, jsCast<JSActivation*>(activation));
+ m_activation.set(vm, this, jsCast<JSActivation*>(activation));
}
void DebuggerActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/debugger/DebuggerActivation.h b/Source/JavaScriptCore/debugger/DebuggerActivation.h
index c934407fc..a33d6ddb2 100644
--- a/Source/JavaScriptCore/debugger/DebuggerActivation.h
+++ b/Source/JavaScriptCore/debugger/DebuggerActivation.h
@@ -34,10 +34,10 @@ namespace JSC {
public:
typedef JSNonFinalObject Base;
- static DebuggerActivation* create(JSGlobalData& globalData, JSObject* object)
+ static DebuggerActivation* create(VM& vm, JSObject* object)
{
- DebuggerActivation* activation = new (NotNull, allocateCell<DebuggerActivation>(globalData.heap)) DebuggerActivation(globalData);
- activation->finishCreation(globalData, object);
+ DebuggerActivation* activation = new (NotNull, allocateCell<DebuggerActivation>(vm.heap)) DebuggerActivation(vm);
+ activation->finishCreation(vm, object);
return activation;
}
@@ -53,18 +53,18 @@ namespace JSC {
JS_EXPORTDATA static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | JSObject::StructureFlags;
- JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, JSObject* activation);
+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject* activation);
private:
- JS_EXPORT_PRIVATE DebuggerActivation(JSGlobalData&);
+ JS_EXPORT_PRIVATE DebuggerActivation(VM&);
WriteBarrier<JSActivation> m_activation;
};
diff --git a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index e924ad34c..a5d045cb9 100644
--- a/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -32,6 +32,7 @@
#include "JSFunction.h"
#include "CodeBlock.h"
#include "Interpreter.h"
+#include "Operations.h"
#include "Parser.h"
namespace JSC {
@@ -89,17 +90,17 @@ JSValue DebuggerCallFrame::evaluate(const String& script, JSValue& exception) co
if (!m_callFrame->codeBlock())
return JSValue();
- JSGlobalData& globalData = m_callFrame->globalData();
- EvalExecutable* eval = EvalExecutable::create(m_callFrame, makeSource(script), m_callFrame->codeBlock()->isStrictMode());
- if (globalData.exception) {
- exception = globalData.exception;
- globalData.exception = JSValue();
+ VM& vm = m_callFrame->vm();
+ EvalExecutable* eval = EvalExecutable::create(m_callFrame, m_callFrame->codeBlock()->unlinkedCodeBlock()->codeCacheForEval(), makeSource(script), m_callFrame->codeBlock()->isStrictMode());
+ if (vm.exception) {
+ exception = vm.exception;
+ vm.exception = JSValue();
}
- JSValue result = globalData.interpreter->execute(eval, m_callFrame, thisObject(), m_callFrame->scope());
- if (globalData.exception) {
- exception = globalData.exception;
- globalData.exception = JSValue();
+ JSValue result = vm.interpreter->execute(eval, m_callFrame, thisObject(), m_callFrame->scope());
+ if (vm.exception) {
+ exception = vm.exception;
+ vm.exception = JSValue();
}
ASSERT(result);
return result;
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 89b2a971b..2ac79c7c9 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,7 +31,9 @@
#include "CodeBlock.h"
#include "DFGBasicBlock.h"
#include "GetByIdStatus.h"
+#include "Operations.h"
#include "PutByIdStatus.h"
+#include "StringObject.h"
namespace JSC { namespace DFG {
@@ -41,7 +43,6 @@ AbstractState::AbstractState(Graph& graph)
, m_variables(m_codeBlock->numParameters(), graph.m_localVars)
, m_block(0)
{
- m_nodes.resize(graph.size());
}
AbstractState::~AbstractState() { }
@@ -54,12 +55,8 @@ void AbstractState::beginBasicBlock(BasicBlock* basicBlock)
ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals());
ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->variablesAtTail.numberOfLocals());
- // This is usually a no-op, but it is possible that the graph has grown since the
- // abstract state was last used.
- m_nodes.resize(m_graph.size());
-
for (size_t i = 0; i < basicBlock->size(); i++)
- m_nodes[basicBlock->at(i)].clear();
+ forNode(basicBlock->at(i)).clear();
m_variables = basicBlock->valuesAtHead;
m_haveStructures = false;
@@ -91,21 +88,14 @@ void AbstractState::initialize(Graph& graph)
root->cfaHasVisited = false;
root->cfaFoundConstants = false;
for (size_t i = 0; i < root->valuesAtHead.numberOfArguments(); ++i) {
- Node& node = graph[root->variablesAtHead.argument(i)];
- ASSERT(node.op() == SetArgument);
- if (!node.shouldGenerate()) {
- // The argument is dead. We don't do any checks for such arguments, and so
- // for the purpose of the analysis, they contain no value.
- root->valuesAtHead.argument(i).clear();
- continue;
- }
-
- if (node.variableAccessData()->isCaptured()) {
+ Node* node = root->variablesAtHead.argument(i);
+ ASSERT(node->op() == SetArgument);
+ if (!node->variableAccessData()->shouldUnboxIfPossible()) {
root->valuesAtHead.argument(i).makeTop();
continue;
}
- SpeculatedType prediction = node.variableAccessData()->prediction();
+ SpeculatedType prediction = node->variableAccessData()->prediction();
if (isInt32Speculation(prediction))
root->valuesAtHead.argument(i).set(SpecInt32);
else if (isBooleanSpeculation(prediction))
@@ -118,8 +108,8 @@ void AbstractState::initialize(Graph& graph)
root->valuesAtTail.argument(i).clear();
}
for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
- NodeIndex nodeIndex = root->variablesAtHead.local(i);
- if (nodeIndex != NoNode && graph[nodeIndex].variableAccessData()->isCaptured())
+ Node* node = root->variablesAtHead.local(i);
+ if (node && node->variableAccessData()->isCaptured())
root->valuesAtHead.local(i).makeTop();
else
root->valuesAtHead.local(i).clear();
@@ -217,11 +207,11 @@ void AbstractState::reset()
m_branchDirection = InvalidBranchDirection;
}
-AbstractState::BooleanResult AbstractState::booleanResult(Node& node, AbstractValue& value)
+AbstractState::BooleanResult AbstractState::booleanResult(Node* node, AbstractValue& value)
{
JSValue childConst = value.value();
if (childConst) {
- if (childConst.toBoolean(m_codeBlock->globalObjectFor(node.codeOrigin)->globalExec()))
+ if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->codeOrigin)->globalExec()))
return DefinitelyTrue;
return DefinitelyFalse;
}
@@ -230,7 +220,7 @@ AbstractState::BooleanResult AbstractState::booleanResult(Node& node, AbstractVa
if (isCellSpeculation(value.m_type)
&& value.m_currentKnownStructure.hasSingleton()) {
Structure* structure = value.m_currentKnownStructure.singleton();
- if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin))
+ if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
&& structure->typeInfo().type() != StringType)
return DefinitelyTrue;
}
@@ -238,96 +228,109 @@ AbstractState::BooleanResult AbstractState::booleanResult(Node& node, AbstractVa
return UnknownBooleanResult;
}
-bool AbstractState::execute(unsigned indexInBlock)
+bool AbstractState::startExecuting(Node* node)
{
ASSERT(m_block);
ASSERT(m_isValid);
m_didClobber = false;
- NodeIndex nodeIndex = m_block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
-
- if (!node.shouldGenerate())
- return true;
-
- switch (node.op()) {
+ node->setCanExit(false);
+
+ if (!node->shouldGenerate())
+ return false;
+
+ return true;
+}
+
+bool AbstractState::startExecuting(unsigned indexInBlock)
+{
+ return startExecuting(m_block->at(indexInBlock));
+}
+
+void AbstractState::executeEdges(Node* node)
+{
+ DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
+}
+
+void AbstractState::executeEdges(unsigned indexInBlock)
+{
+ executeEdges(m_block->at(indexInBlock));
+}
+
+void AbstractState::verifyEdge(Node*, Edge edge)
+{
+ RELEASE_ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
+}
+
+void AbstractState::verifyEdges(Node* node)
+{
+ DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
+}
+
+bool AbstractState::executeEffects(unsigned indexInBlock, Node* node)
+{
+ if (!ASSERT_DISABLED)
+ verifyEdges(node);
+
+ switch (node->op()) {
case JSConstant:
case WeakJSConstant:
case PhantomArguments: {
- forNode(nodeIndex).set(m_graph.valueOfJSConstant(nodeIndex));
- node.setCanExit(false);
+ forNode(node).set(m_graph.valueOfJSConstant(node));
break;
}
case Identity: {
- forNode(nodeIndex) = forNode(node.child1());
- node.setCanExit(false);
+ forNode(node) = forNode(node->child1());
break;
}
case GetLocal: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->prediction() == SpecNone) {
m_isValid = false;
- node.setCanExit(true);
break;
}
- bool canExit = false;
AbstractValue value = m_variables.operand(variableAccessData->local());
if (!variableAccessData->isCaptured()) {
if (value.isClear())
- canExit |= true;
+ node->setCanExit(true);
}
if (value.value())
m_foundConstants = true;
- forNode(nodeIndex) = value;
- node.setCanExit(canExit);
+ forNode(node) = value;
break;
}
case GetLocalUnlinked: {
- AbstractValue value = m_variables.operand(node.unlinkedLocal());
+ AbstractValue value = m_variables.operand(node->unlinkedLocal());
if (value.value())
m_foundConstants = true;
- forNode(nodeIndex) = value;
- node.setCanExit(false);
+ forNode(node) = value;
break;
}
case SetLocal: {
- if (node.variableAccessData()->isCaptured()
- || m_graph.isCreatedThisArgument(node.local())) {
- m_variables.operand(node.local()) = forNode(node.child1());
- node.setCanExit(false);
- break;
- }
-
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- speculateNumberUnary(node);
- m_variables.operand(node.local()).set(SpecDouble);
- break;
- }
+ m_variables.operand(node->local()) = forNode(node->child1());
+ break;
+ }
- SpeculatedType predictedType = node.variableAccessData()->argumentAwarePrediction();
- if (isInt32Speculation(predictedType))
- speculateInt32Unary(node);
- else if (isCellSpeculation(predictedType)) {
- node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
- forNode(node.child1()).filter(SpecCell);
- } else if (isBooleanSpeculation(predictedType))
- speculateBooleanUnary(node);
- else
- node.setCanExit(false);
+ case MovHintAndCheck: {
+ // Don't need to do anything. A MovHint is effectively a promise that the SetLocal
+ // was dead.
+ break;
+ }
- m_variables.operand(node.local()) = forNode(node.child1());
+ case MovHint:
+ case ZombieHint: {
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
case SetArgument:
// Assert that the state of arguments has been set.
- ASSERT(!m_block->valuesAtHead.operand(node.local()).isClear());
- node.setCanExit(false);
+ ASSERT(!m_block->valuesAtHead.operand(node->local()).isClear());
break;
case BitAnd:
@@ -336,230 +339,225 @@ bool AbstractState::execute(unsigned indexInBlock)
case BitRShift:
case BitLShift:
case BitURShift: {
- JSValue left = forNode(node.child1()).value();
- JSValue right = forNode(node.child2()).value();
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
if (left && right && left.isInt32() && right.isInt32()) {
int32_t a = left.asInt32();
int32_t b = right.asInt32();
bool constantWasSet;
- switch (node.op()) {
+ switch (node->op()) {
case BitAnd:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a & b));
+ constantWasSet = trySetConstant(node, JSValue(a & b));
break;
case BitOr:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a | b));
+ constantWasSet = trySetConstant(node, JSValue(a | b));
break;
case BitXor:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a ^ b));
+ constantWasSet = trySetConstant(node, JSValue(a ^ b));
break;
case BitRShift:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a >> static_cast<uint32_t>(b)));
+ constantWasSet = trySetConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
break;
case BitLShift:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a << static_cast<uint32_t>(b)));
+ constantWasSet = trySetConstant(node, JSValue(a << static_cast<uint32_t>(b)));
break;
case BitURShift:
- constantWasSet = trySetConstant(nodeIndex, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
+ constantWasSet = trySetConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
constantWasSet = false;
}
if (constantWasSet) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
}
- speculateInt32Binary(node);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
}
case UInt32ToNumber: {
- JSValue child = forNode(node.child1()).value();
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()) {
ASSERT(child.isInt32());
- if (trySetConstant(nodeIndex, JSValue(child.asUInt32()))) {
+ if (trySetConstant(node, JSValue(child.asUInt32()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
}
- if (!node.canSpeculateInteger()) {
- forNode(nodeIndex).set(SpecDouble);
- node.setCanExit(false);
- } else {
- forNode(nodeIndex).set(SpecInt32);
- node.setCanExit(true);
+ if (!node->canSpeculateInteger())
+ forNode(node).set(SpecDouble);
+ else {
+ forNode(node).set(SpecInt32);
+ node->setCanExit(true);
}
break;
}
-
case DoubleAsInt32: {
- JSValue child = forNode(node.child1()).value();
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()) {
double asDouble = child.asNumber();
int32_t asInt = JSC::toInt32(asDouble);
if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)
- && trySetConstant(nodeIndex, JSValue(asInt))) {
+ && trySetConstant(node, JSValue(asInt))) {
m_foundConstants = true;
break;
}
}
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecNumber);
- forNode(nodeIndex).set(SpecInt32);
+ node->setCanExit(true);
+ forNode(node).set(SpecInt32);
break;
}
case ValueToInt32: {
- JSValue child = forNode(node.child1()).value();
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()) {
bool constantWasSet;
if (child.isInt32())
- constantWasSet = trySetConstant(nodeIndex, child);
+ constantWasSet = trySetConstant(node, child);
else
- constantWasSet = trySetConstant(nodeIndex, JSValue(JSC::toInt32(child.asDouble())));
+ constantWasSet = trySetConstant(node, JSValue(JSC::toInt32(child.asDouble())));
if (constantWasSet) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
}
- if (m_graph[node.child1()].shouldSpeculateInteger())
- speculateInt32Unary(node);
- else if (m_graph[node.child1()].shouldSpeculateNumber())
- speculateNumberUnary(node);
- else if (m_graph[node.child1()].shouldSpeculateBoolean())
- speculateBooleanUnary(node);
- else
- node.setCanExit(false);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
}
-
- case Int32ToDouble: {
- JSValue child = forNode(node.child1()).value();
+
+ case Int32ToDouble:
+ case ForwardInt32ToDouble: {
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()
- && trySetConstant(nodeIndex, JSValue(JSValue::EncodeAsDouble, child.asNumber()))) {
+ && trySetConstant(node, JSValue(JSValue::EncodeAsDouble, child.asNumber()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- speculateNumberUnary(node);
- if (isInt32Speculation(forNode(node.child1()).m_type))
- forNode(nodeIndex).set(SpecDoubleReal);
+ if (isInt32Speculation(forNode(node->child1()).m_type))
+ forNode(node).set(SpecDoubleReal);
else
- forNode(nodeIndex).set(SpecDouble);
+ forNode(node).set(SpecDouble);
break;
}
- case CheckNumber:
- forNode(node.child1()).filter(SpecNumber);
- break;
-
case ValueAdd:
case ArithAdd: {
- JSValue left = forNode(node.child1()).value();
- JSValue right = forNode(node.child2()).value();
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
if (left && right && left.isNumber() && right.isNumber()
- && trySetConstant(nodeIndex, JSValue(left.asNumber() + right.asNumber()))) {
+ && trySetConstant(node, JSValue(left.asNumber() + right.asNumber()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- if (m_graph.addShouldSpeculateInteger(node)) {
- speculateInt32Binary(
- node, !nodeCanTruncateInteger(node.arithNodeFlags()));
- forNode(nodeIndex).set(SpecInt32);
+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ forNode(node).set(SpecInt32);
+ if (!nodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setCanExit(true);
break;
- }
- if (Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()])) {
- speculateNumberBinary(node);
- if (isRealNumberSpeculation(forNode(node.child1()).m_type)
- && isRealNumberSpeculation(forNode(node.child2()).m_type))
- forNode(nodeIndex).set(SpecDoubleReal);
+ case NumberUse:
+ if (isRealNumberSpeculation(forNode(node->child1()).m_type)
+ && isRealNumberSpeculation(forNode(node->child2()).m_type))
+ forNode(node).set(SpecDoubleReal);
else
- forNode(nodeIndex).set(SpecDouble);
+ forNode(node).set(SpecDouble);
break;
- }
- if (node.op() == ValueAdd) {
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).set(SpecString | SpecInt32 | SpecNumber);
- node.setCanExit(false);
+ default:
+ RELEASE_ASSERT(node->op() == ValueAdd);
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).set(SpecString | SpecInt32 | SpecNumber);
break;
}
- // We don't handle this yet. :-(
- m_isValid = false;
- node.setCanExit(true);
+ break;
+ }
+
+ case MakeRope: {
+ forNode(node).set(m_graph.m_vm.stringStructure.get());
break;
}
case ArithSub: {
- JSValue left = forNode(node.child1()).value();
- JSValue right = forNode(node.child2()).value();
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
if (left && right && left.isNumber() && right.isNumber()
- && trySetConstant(nodeIndex, JSValue(left.asNumber() - right.asNumber()))) {
+ && trySetConstant(node, JSValue(left.asNumber() - right.asNumber()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- if (m_graph.addShouldSpeculateInteger(node)) {
- speculateInt32Binary(
- node, !nodeCanTruncateInteger(node.arithNodeFlags()));
- forNode(nodeIndex).set(SpecInt32);
+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ forNode(node).set(SpecInt32);
+ if (!nodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ forNode(node).set(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- speculateNumberBinary(node);
- forNode(nodeIndex).set(SpecDouble);
break;
}
case ArithNegate: {
- JSValue child = forNode(node.child1()).value();
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()
- && trySetConstant(nodeIndex, JSValue(-child.asNumber()))) {
+ && trySetConstant(node, JSValue(-child.asNumber()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- if (m_graph.negateShouldSpeculateInteger(node)) {
- speculateInt32Unary(
- node, !nodeCanTruncateInteger(node.arithNodeFlags()));
- forNode(nodeIndex).set(SpecInt32);
+ switch (node->child1().useKind()) {
+ case Int32Use:
+ forNode(node).set(SpecInt32);
+ if (!nodeCanTruncateInteger(node->arithNodeFlags()))
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ forNode(node).set(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- speculateNumberUnary(node);
- forNode(nodeIndex).set(SpecDouble);
break;
}
case ArithMul: {
- JSValue left = forNode(node.child1()).value();
- JSValue right = forNode(node.child2()).value();
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
if (left && right && left.isNumber() && right.isNumber()
- && trySetConstant(nodeIndex, JSValue(left.asNumber() * right.asNumber()))) {
+ && trySetConstant(node, JSValue(left.asNumber() * right.asNumber()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- if (m_graph.mulShouldSpeculateInteger(node)) {
- speculateInt32Binary(
- node,
- !nodeCanTruncateInteger(node.arithNodeFlags())
- || !nodeCanIgnoreNegativeZero(node.arithNodeFlags()));
- forNode(nodeIndex).set(SpecInt32);
+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ forNode(node).set(SpecInt32);
+ if (!nodeCanTruncateInteger(node->arithNodeFlags())
+ || !nodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ if (isRealNumberSpeculation(forNode(node->child1()).m_type)
+ || isRealNumberSpeculation(forNode(node->child2()).m_type))
+ forNode(node).set(SpecDoubleReal);
+ else
+ forNode(node).set(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- speculateNumberBinary(node);
- if (isRealNumberSpeculation(forNode(node.child1()).m_type)
- || isRealNumberSpeculation(forNode(node.child2()).m_type))
- forNode(nodeIndex).set(SpecDoubleReal);
- else
- forNode(nodeIndex).set(SpecDouble);
+ break;
+ }
+
+ case ArithIMul: {
+ forNode(node).set(SpecInt32);
break;
}
@@ -567,110 +565,113 @@ bool AbstractState::execute(unsigned indexInBlock)
case ArithMin:
case ArithMax:
case ArithMod: {
- JSValue left = forNode(node.child1()).value();
- JSValue right = forNode(node.child2()).value();
+ JSValue left = forNode(node->child1()).value();
+ JSValue right = forNode(node->child2()).value();
if (left && right && left.isNumber() && right.isNumber()) {
double a = left.asNumber();
double b = right.asNumber();
bool constantWasSet;
- switch (node.op()) {
+ switch (node->op()) {
case ArithDiv:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a / b));
+ constantWasSet = trySetConstant(node, JSValue(a / b));
break;
case ArithMin:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a < b ? a : (b <= a ? b : a + b)));
+ constantWasSet = trySetConstant(node, JSValue(a < b ? a : (b <= a ? b : a + b)));
break;
case ArithMax:
- constantWasSet = trySetConstant(nodeIndex, JSValue(a > b ? a : (b >= a ? b : a + b)));
+ constantWasSet = trySetConstant(node, JSValue(a > b ? a : (b >= a ? b : a + b)));
break;
case ArithMod:
- constantWasSet = trySetConstant(nodeIndex, JSValue(fmod(a, b)));
+ constantWasSet = trySetConstant(node, JSValue(fmod(a, b)));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
constantWasSet = false;
break;
}
if (constantWasSet) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
}
- if (Node::shouldSpeculateIntegerForArithmetic(
- m_graph[node.child1()], m_graph[node.child2()])
- && node.canSpeculateInteger()) {
- speculateInt32Binary(node, true); // forcing can-exit, which is a bit on the conservative side.
- forNode(nodeIndex).set(SpecInt32);
+ switch (node->binaryUseKind()) {
+ case Int32Use:
+ forNode(node).set(SpecInt32);
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ forNode(node).set(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- speculateNumberBinary(node);
- forNode(nodeIndex).set(SpecDouble);
break;
}
case ArithAbs: {
- JSValue child = forNode(node.child1()).value();
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()
- && trySetConstant(nodeIndex, JSValue(fabs(child.asNumber())))) {
+ && trySetConstant(node, JSValue(fabs(child.asNumber())))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic()
- && node.canSpeculateInteger()) {
- speculateInt32Unary(node, true);
- forNode(nodeIndex).set(SpecInt32);
+ switch (node->child1().useKind()) {
+ case Int32Use:
+ forNode(node).set(SpecInt32);
+ node->setCanExit(true);
+ break;
+ case NumberUse:
+ forNode(node).set(SpecDouble);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- speculateNumberUnary(node);
- forNode(nodeIndex).set(SpecDouble);
break;
}
case ArithSqrt: {
- JSValue child = forNode(node.child1()).value();
+ JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()
- && trySetConstant(nodeIndex, JSValue(sqrt(child.asNumber())))) {
+ && trySetConstant(node, JSValue(sqrt(child.asNumber())))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- speculateNumberUnary(node);
- forNode(nodeIndex).set(SpecDouble);
+ forNode(node).set(SpecDouble);
break;
}
case LogicalNot: {
bool didSetConstant = false;
- switch (booleanResult(node, forNode(node.child1()))) {
+ switch (booleanResult(node, forNode(node->child1()))) {
case DefinitelyTrue:
- didSetConstant = trySetConstant(nodeIndex, jsBoolean(false));
+ didSetConstant = trySetConstant(node, jsBoolean(false));
break;
case DefinitelyFalse:
- didSetConstant = trySetConstant(nodeIndex, jsBoolean(true));
+ didSetConstant = trySetConstant(node, jsBoolean(true));
break;
default:
break;
}
if (didSetConstant) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- Node& child = m_graph[node.child1()];
- if (isBooleanSpeculation(child.prediction()))
- speculateBooleanUnary(node);
- else if (child.shouldSpeculateNonStringCellOrOther()) {
- node.setCanExit(true);
- forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
- } else if (child.shouldSpeculateInteger())
- speculateInt32Unary(node);
- else if (child.shouldSpeculateNumber())
- speculateNumberUnary(node);
- else
- node.setCanExit(false);
- forNode(nodeIndex).set(SpecBoolean);
+ switch (node->child1().useKind()) {
+ case BooleanUse:
+ case Int32Use:
+ case NumberUse:
+ case UntypedUse:
+ break;
+ case ObjectOrOtherUse:
+ node->setCanExit(true);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ forNode(node).set(SpecBoolean);
break;
}
@@ -680,33 +681,38 @@ bool AbstractState::execute(unsigned indexInBlock)
case IsString:
case IsObject:
case IsFunction: {
- node.setCanExit(node.op() == IsUndefined && m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
- JSValue child = forNode(node.child1()).value();
+ node->setCanExit(node->op() == IsUndefined && m_codeBlock->globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
+ JSValue child = forNode(node->child1()).value();
if (child) {
bool constantWasSet;
- switch (node.op()) {
+ switch (node->op()) {
case IsUndefined:
- if (m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(
+ if (m_codeBlock->globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ constantWasSet = trySetConstant(node, jsBoolean(
child.isCell()
? false
: child.isUndefined()));
} else {
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(
+ constantWasSet = trySetConstant(node, jsBoolean(
child.isCell()
- ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin))
+ ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
: child.isUndefined()));
}
break;
case IsBoolean:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(child.isBoolean()));
+ constantWasSet = trySetConstant(node, jsBoolean(child.isBoolean()));
break;
case IsNumber:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(child.isNumber()));
+ constantWasSet = trySetConstant(node, jsBoolean(child.isNumber()));
break;
case IsString:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(isJSString(child)));
+ constantWasSet = trySetConstant(node, jsBoolean(isJSString(child)));
break;
+ case IsObject:
+ if (child.isNull() || !child.isObject()) {
+ constantWasSet = trySetConstant(node, jsBoolean(child.isNull()));
+ break;
+ }
default:
constantWasSet = false;
break;
@@ -716,7 +722,65 @@ bool AbstractState::execute(unsigned indexInBlock)
break;
}
}
- forNode(nodeIndex).set(SpecBoolean);
+
+ forNode(node).set(SpecBoolean);
+ break;
+ }
+
+ case TypeOf: {
+ VM* vm = m_codeBlock->vm();
+ JSValue child = forNode(node->child1()).value();
+ AbstractValue& abstractChild = forNode(node->child1());
+ if (child) {
+ JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->codeOrigin), child);
+ if (trySetConstant(node, typeString)) {
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isNumberSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.numberString())) {
+ forNode(node->child1()).filter(SpecNumber);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isStringSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.stringString())) {
+ forNode(node->child1()).filter(SpecString);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.objectString())) {
+ forNode(node->child1()).filter(SpecFinalObject | SpecArray | SpecArguments);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isFunctionSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.functionString())) {
+ forNode(node->child1()).filter(SpecFunction);
+ m_foundConstants = true;
+ break;
+ }
+ } else if (isBooleanSpeculation(abstractChild.m_type)) {
+ if (trySetConstant(node, vm->smallStrings.booleanString())) {
+ forNode(node->child1()).filter(SpecBoolean);
+ m_foundConstants = true;
+ break;
+ }
+ }
+
+ switch (node->child1().useKind()) {
+ case StringUse:
+ case CellUse:
+ node->setCanExit(true);
+ break;
+ case UntypedUse:
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ forNode(node).set(m_graph.m_vm.stringStructure.get());
break;
}
@@ -724,266 +788,169 @@ bool AbstractState::execute(unsigned indexInBlock)
case CompareLessEq:
case CompareGreater:
case CompareGreaterEq:
- case CompareEq: {
+ case CompareEq:
+ case CompareEqConstant: {
bool constantWasSet = false;
- JSValue leftConst = forNode(node.child1()).value();
- JSValue rightConst = forNode(node.child2()).value();
+ JSValue leftConst = forNode(node->child1()).value();
+ JSValue rightConst = forNode(node->child2()).value();
if (leftConst && rightConst && leftConst.isNumber() && rightConst.isNumber()) {
double a = leftConst.asNumber();
double b = rightConst.asNumber();
- switch (node.op()) {
+ switch (node->op()) {
case CompareLess:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(a < b));
+ constantWasSet = trySetConstant(node, jsBoolean(a < b));
break;
case CompareLessEq:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(a <= b));
+ constantWasSet = trySetConstant(node, jsBoolean(a <= b));
break;
case CompareGreater:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(a > b));
+ constantWasSet = trySetConstant(node, jsBoolean(a > b));
break;
case CompareGreaterEq:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(a >= b));
+ constantWasSet = trySetConstant(node, jsBoolean(a >= b));
break;
case CompareEq:
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(a == b));
+ constantWasSet = trySetConstant(node, jsBoolean(a == b));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
constantWasSet = false;
break;
}
}
- if (!constantWasSet && node.op() == CompareEq) {
- SpeculatedType leftType = forNode(node.child1()).m_type;
- SpeculatedType rightType = forNode(node.child2()).m_type;
+ if (!constantWasSet && (node->op() == CompareEqConstant || node->op() == CompareEq)) {
+ SpeculatedType leftType = forNode(node->child1()).m_type;
+ SpeculatedType rightType = forNode(node->child2()).m_type;
if ((isInt32Speculation(leftType) && isOtherSpeculation(rightType))
|| (isOtherSpeculation(leftType) && isInt32Speculation(rightType)))
- constantWasSet = trySetConstant(nodeIndex, jsBoolean(false));
+ constantWasSet = trySetConstant(node, jsBoolean(false));
}
if (constantWasSet) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- forNode(nodeIndex).set(SpecBoolean);
+ forNode(node).set(SpecBoolean);
- Node& left = m_graph[node.child1()];
- Node& right = m_graph[node.child2()];
- SpeculatedType filter;
- SpeculatedTypeChecker checker;
- if (Node::shouldSpeculateInteger(left, right)) {
- filter = SpecInt32;
- checker = isInt32Speculation;
- } else if (Node::shouldSpeculateNumber(left, right)) {
- filter = SpecNumber;
- checker = isNumberSpeculation;
- } else if (node.op() == CompareEq) {
- if ((m_graph.isConstant(node.child1().index())
- && m_graph.valueOfJSConstant(node.child1().index()).isNull())
- || (m_graph.isConstant(node.child2().index())
- && m_graph.valueOfJSConstant(node.child2().index()).isNull())) {
- // We can exit if we haven't fired the MasqueradesAsUndefind watchpoint yet.
- node.setCanExit(m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
- break;
- }
-
- if (left.shouldSpeculateString() || right.shouldSpeculateString()) {
- node.setCanExit(false);
- break;
- }
- if (left.shouldSpeculateNonStringCell() && right.shouldSpeculateNonStringCellOrOther()) {
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecCell & ~SpecString);
- forNode(node.child2()).filter((SpecCell & ~SpecString) | SpecOther);
- break;
- }
- if (left.shouldSpeculateNonStringCellOrOther() && right.shouldSpeculateNonStringCell()) {
- node.setCanExit(true);
- forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
- forNode(node.child2()).filter(SpecCell & ~SpecString);
- break;
- }
- if (left.shouldSpeculateNonStringCell() && right.shouldSpeculateNonStringCell()) {
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecCell & ~SpecString);
- forNode(node.child2()).filter(SpecCell & ~SpecString);
- break;
- }
-
- filter = SpecTop;
- checker = isAnySpeculation;
- clobberWorld(node.codeOrigin, indexInBlock);
- } else {
- filter = SpecTop;
- checker = isAnySpeculation;
- clobberWorld(node.codeOrigin, indexInBlock);
- }
- node.setCanExit(
- !checker(forNode(node.child1()).m_type)
- || !checker(forNode(node.child2()).m_type));
- forNode(node.child1()).filter(filter);
- forNode(node.child2()).filter(filter);
+ // This is overly conservative. But the only thing this prevents is store elimination,
+ // and how likely is it, really, that you'll have redundant stores across a comparison
+ // operation? Comparison operations are typically at the end of basic blocks, so
+ // unless we have global store elimination (super unlikely given how unprofitable that
+ // optimization is to begin with), you aren't going to be wanting to store eliminate
+ // across an equality op.
+ node->setCanExit(true);
break;
}
- case CompareStrictEq: {
- JSValue left = forNode(node.child1()).value();
- JSValue right = forNode(node.child2()).value();
+ case CompareStrictEq:
+ case CompareStrictEqConstant: {
+ Node* leftNode = node->child1().node();
+ Node* rightNode = node->child2().node();
+ JSValue left = forNode(leftNode).value();
+ JSValue right = forNode(rightNode).value();
if (left && right && left.isNumber() && right.isNumber()
- && trySetConstant(nodeIndex, jsBoolean(left.asNumber() == right.asNumber()))) {
+ && trySetConstant(node, jsBoolean(left.asNumber() == right.asNumber()))) {
m_foundConstants = true;
- node.setCanExit(false);
- break;
- }
- forNode(nodeIndex).set(SpecBoolean);
- if (m_graph.isJSConstant(node.child1().index())) {
- JSValue value = m_graph.valueOfJSConstant(node.child1().index());
- if (!value.isNumber() && !value.isString()) {
- node.setCanExit(false);
- break;
- }
- }
- if (m_graph.isJSConstant(node.child2().index())) {
- JSValue value = m_graph.valueOfJSConstant(node.child2().index());
- if (!value.isNumber() && !value.isString()) {
- node.setCanExit(false);
- break;
- }
- }
- if (Node::shouldSpeculateInteger(
- m_graph[node.child1()], m_graph[node.child2()])) {
- speculateInt32Binary(node);
break;
}
- if (Node::shouldSpeculateNumber(
- m_graph[node.child1()], m_graph[node.child2()])) {
- speculateNumberBinary(node);
- break;
- }
- Node& leftNode = m_graph[node.child1()];
- Node& rightNode = m_graph[node.child2()];
- if (leftNode.shouldSpeculateString() || rightNode.shouldSpeculateString()) {
- node.setCanExit(false);
- break;
- }
- if (leftNode.shouldSpeculateNonStringCell() && rightNode.shouldSpeculateNonStringCell()) {
- node.setCanExit(true);
- forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
- forNode(node.child2()).filter((SpecCell & ~SpecString) | SpecOther);
- break;
- }
- node.setCanExit(false);
+ forNode(node).set(SpecBoolean);
+ node->setCanExit(true); // This is overly conservative.
break;
}
case StringCharCodeAt:
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecString);
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ node->setCanExit(true);
+ forNode(node).set(SpecInt32);
break;
+ case StringFromCharCode:
+ forNode(node).set(SpecString);
+ break;
+
case StringCharAt:
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecString);
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecString);
+ node->setCanExit(true);
+ forNode(node).set(m_graph.m_vm.stringStructure.get());
break;
case GetByVal: {
- node.setCanExit(true);
- switch (node.arrayMode().type()) {
+ node->setCanExit(true);
+ switch (node->arrayMode().type()) {
case Array::SelectUsingPredictions:
case Array::Unprofiled:
case Array::Undecided:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
case Array::ForceExit:
m_isValid = false;
break;
case Array::Generic:
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
break;
case Array::String:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecString);
+ forNode(node).set(m_graph.m_vm.stringStructure.get());
break;
case Array::Arguments:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).makeTop();
+ forNode(node).makeTop();
break;
case Array::Int32:
- forNode(node.child2()).filter(SpecInt32);
- if (node.arrayMode().isOutOfBounds()) {
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ if (node->arrayMode().isOutOfBounds()) {
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
} else
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Double:
- forNode(node.child2()).filter(SpecInt32);
- if (node.arrayMode().isOutOfBounds()) {
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
- } else if (node.arrayMode().isSaneChain())
- forNode(nodeIndex).set(SpecDouble);
+ if (node->arrayMode().isOutOfBounds()) {
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
+ } else if (node->arrayMode().isSaneChain())
+ forNode(node).set(SpecDouble);
else
- forNode(nodeIndex).set(SpecDoubleReal);
+ forNode(node).set(SpecDoubleReal);
break;
case Array::Contiguous:
case Array::ArrayStorage:
case Array::SlowPutArrayStorage:
- forNode(node.child2()).filter(SpecInt32);
- if (node.arrayMode().isOutOfBounds())
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ if (node->arrayMode().isOutOfBounds())
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
break;
case Array::Int8Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Int16Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Int32Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Uint8Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Uint8ClampedArray:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Uint16Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecInt32);
+ forNode(node).set(SpecInt32);
break;
case Array::Uint32Array:
- forNode(node.child2()).filter(SpecInt32);
- if (node.shouldSpeculateInteger())
- forNode(nodeIndex).set(SpecInt32);
+ if (node->shouldSpeculateInteger())
+ forNode(node).set(SpecInt32);
else
- forNode(nodeIndex).set(SpecDouble);
+ forNode(node).set(SpecDouble);
break;
case Array::Float32Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecDouble);
+ forNode(node).set(SpecDouble);
break;
case Array::Float64Array:
- forNode(node.child2()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecDouble);
+ forNode(node).set(SpecDouble);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
break;
@@ -991,286 +958,189 @@ bool AbstractState::execute(unsigned indexInBlock)
case PutByVal:
case PutByValAlias: {
- node.setCanExit(true);
- Edge child1 = m_graph.varArgChild(node, 0);
- Edge child2 = m_graph.varArgChild(node, 1);
- Edge child3 = m_graph.varArgChild(node, 2);
- switch (node.arrayMode().modeForPut().type()) {
+ node->setCanExit(true);
+ switch (node->arrayMode().modeForPut().type()) {
case Array::ForceExit:
m_isValid = false;
break;
case Array::Generic:
- clobberWorld(node.codeOrigin, indexInBlock);
+ clobberWorld(node->codeOrigin, indexInBlock);
break;
case Array::Int32:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- forNode(child3).filter(SpecInt32);
- if (node.arrayMode().isOutOfBounds())
- clobberWorld(node.codeOrigin, indexInBlock);
+ if (node->arrayMode().isOutOfBounds())
+ clobberWorld(node->codeOrigin, indexInBlock);
break;
case Array::Double:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- forNode(child3).filter(SpecRealNumber);
- if (node.arrayMode().isOutOfBounds())
- clobberWorld(node.codeOrigin, indexInBlock);
+ if (node->arrayMode().isOutOfBounds())
+ clobberWorld(node->codeOrigin, indexInBlock);
break;
case Array::Contiguous:
case Array::ArrayStorage:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (node.arrayMode().isOutOfBounds())
- clobberWorld(node.codeOrigin, indexInBlock);
+ if (node->arrayMode().isOutOfBounds())
+ clobberWorld(node->codeOrigin, indexInBlock);
break;
case Array::SlowPutArrayStorage:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (node.arrayMode().mayStoreToHole())
- clobberWorld(node.codeOrigin, indexInBlock);
- break;
- case Array::Arguments:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- break;
- case Array::Int8Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Int16Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Int32Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Uint8Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Uint8ClampedArray:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Uint16Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Uint32Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- if (m_graph[child3].shouldSpeculateInteger())
- forNode(child3).filter(SpecInt32);
- else
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Float32Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- forNode(child3).filter(SpecNumber);
- break;
- case Array::Float64Array:
- forNode(child1).filter(SpecCell);
- forNode(child2).filter(SpecInt32);
- forNode(child3).filter(SpecNumber);
+ if (node->arrayMode().mayStoreToHole())
+ clobberWorld(node->codeOrigin, indexInBlock);
break;
default:
- CRASH();
break;
}
break;
}
case ArrayPush:
- node.setCanExit(true);
- switch (node.arrayMode().type()) {
- case Array::Int32:
- forNode(node.child2()).filter(SpecInt32);
- break;
- case Array::Double:
- forNode(node.child2()).filter(SpecRealNumber);
- break;
- default:
- break;
- }
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).set(SpecNumber);
+ node->setCanExit(true);
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).set(SpecNumber);
break;
case ArrayPop:
- node.setCanExit(true);
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ node->setCanExit(true);
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
break;
case RegExpExec:
+ forNode(node).makeTop();
+ break;
+
case RegExpTest:
- node.setCanExit(
- !isCellSpeculation(forNode(node.child1()).m_type)
- || !isCellSpeculation(forNode(node.child2()).m_type));
- forNode(node.child1()).filter(SpecCell);
- forNode(node.child2()).filter(SpecCell);
- forNode(nodeIndex).makeTop();
+ forNode(node).set(SpecBoolean);
break;
case Jump:
- node.setCanExit(false);
break;
case Branch: {
- BooleanResult result = booleanResult(node, forNode(node.child1()));
+ Node* child = node->child1().node();
+ BooleanResult result = booleanResult(node, forNode(child));
if (result == DefinitelyTrue) {
m_branchDirection = TakeTrue;
- node.setCanExit(false);
break;
}
if (result == DefinitelyFalse) {
m_branchDirection = TakeFalse;
- node.setCanExit(false);
break;
}
// FIXME: The above handles the trivial cases of sparse conditional
// constant propagation, but we can do better:
// We can specialize the source variable's value on each direction of
// the branch.
- Node& child = m_graph[node.child1()];
- if (child.shouldSpeculateBoolean())
- speculateBooleanUnary(node);
- else if (child.shouldSpeculateNonStringCellOrOther()) {
- node.setCanExit(true);
- forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
- } else if (child.shouldSpeculateInteger())
- speculateInt32Unary(node);
- else if (child.shouldSpeculateNumber())
- speculateNumberUnary(node);
- else
- node.setCanExit(false);
+ node->setCanExit(true); // This is overly conservative.
m_branchDirection = TakeBoth;
break;
}
case Return:
m_isValid = false;
- node.setCanExit(false);
break;
case Throw:
case ThrowReferenceError:
m_isValid = false;
- node.setCanExit(true);
+ node->setCanExit(true);
break;
case ToPrimitive: {
- JSValue childConst = forNode(node.child1()).value();
- if (childConst && childConst.isNumber() && trySetConstant(nodeIndex, childConst)) {
+ JSValue childConst = forNode(node->child1()).value();
+ if (childConst && childConst.isNumber() && trySetConstant(node, childConst)) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- Node& child = m_graph[node.child1()];
- if (child.shouldSpeculateInteger()) {
- speculateInt32Unary(node);
- forNode(nodeIndex).set(SpecInt32);
- break;
- }
-
- AbstractValue& source = forNode(node.child1());
- AbstractValue& destination = forNode(nodeIndex);
-
+ ASSERT(node->child1().useKind() == UntypedUse);
+
+ AbstractValue& source = forNode(node->child1());
+ AbstractValue& destination = forNode(node);
+
+ // NB. The more canonical way of writing this would have been:
+ //
+ // destination = source;
+ // if (destination.m_type & !(SpecNumber | SpecString | SpecBoolean)) {
+ // destination.filter(SpecNumber | SpecString | SpecBoolean);
+ // AbstractValue string;
+ // string.set(vm->stringStructure);
+ // destination.merge(string);
+ // }
+ //
+ // The reason why this would, in most other cases, have been better is that
+ // then destination would preserve any non-SpeculatedType knowledge of source.
+ // As it stands, the code below forgets any non-SpeculatedType knowledge that
+ // source would have had. Fortunately, though, for things like strings and
+ // numbers and booleans, we don't care about the non-SpeculatedType knowedge:
+ // the structure won't tell us anything we don't already know, and neither
+ // will ArrayModes. And if the source was a meaningful constant then we
+ // would have handled that above. Unfortunately, this does mean that
+ // ToPrimitive will currently forget string constants. But that's not a big
+ // deal since we don't do any optimization on those currently.
+
+ clobberWorld(node->codeOrigin, indexInBlock);
+
SpeculatedType type = source.m_type;
if (type & ~(SpecNumber | SpecString | SpecBoolean)) {
type &= (SpecNumber | SpecString | SpecBoolean);
type |= SpecString;
}
destination.set(type);
- node.setCanExit(false);
break;
}
-
- case StrCat:
- node.setCanExit(false);
- forNode(nodeIndex).set(SpecString);
+
+ case ToString: {
+ switch (node->child1().useKind()) {
+ case StringObjectUse:
+ // This also filters that the StringObject has the primordial StringObject
+ // structure.
+ forNode(node->child1()).filter(m_graph.globalObjectFor(node->codeOrigin)->stringObjectStructure());
+ node->setCanExit(true); // We could be more precise but it's likely not worth it.
+ break;
+ case StringOrStringObjectUse:
+ node->setCanExit(true); // We could be more precise but it's likely not worth it.
+ break;
+ case CellUse:
+ case UntypedUse:
+ clobberWorld(node->codeOrigin, indexInBlock);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ forNode(node).set(m_graph.m_vm.stringStructure.get());
+ break;
+ }
+
+ case NewStringObject: {
+ ASSERT(node->structure()->classInfo() == &StringObject::s_info);
+ forNode(node).set(node->structure());
break;
+ }
case NewArray:
- node.setCanExit(true);
- forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()));
+ node->setCanExit(true);
+ forNode(node).set(m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
m_haveStructures = true;
break;
case NewArrayBuffer:
- node.setCanExit(true);
- forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()));
+ node->setCanExit(true);
+ forNode(node).set(m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
m_haveStructures = true;
break;
case NewArrayWithSize:
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecInt32);
- forNode(nodeIndex).set(SpecArray);
+ node->setCanExit(true);
+ forNode(node).set(SpecArray);
m_haveStructures = true;
break;
case NewRegexp:
- node.setCanExit(false);
- forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->regExpStructure());
+ forNode(node).set(m_graph.globalObjectFor(node->codeOrigin)->regExpStructure());
m_haveStructures = true;
break;
case ConvertThis: {
- Node& child = m_graph[node.child1()];
- AbstractValue& source = forNode(node.child1());
- AbstractValue& destination = forNode(nodeIndex);
-
- if (isObjectSpeculation(source.m_type)) {
- // This is the simple case. We already know that the source is an
- // object, so there's nothing to do. I don't think this case will
- // be hit, but then again, you never know.
- destination = source;
- node.setCanExit(false);
- m_foundConstants = true; // Tell the constant folder to turn this into Identity.
- break;
- }
-
- node.setCanExit(true);
-
- if (isOtherSpeculation(child.prediction())) {
- source.filter(SpecOther);
- destination.set(SpecObjectOther);
- break;
- }
-
- if (isObjectSpeculation(child.prediction())) {
- source.filter(SpecObjectMask);
- destination = source;
- break;
- }
+ AbstractValue& source = forNode(node->child1());
+ AbstractValue& destination = forNode(node);
destination = source;
destination.merge(SpecObjectOther);
@@ -1278,52 +1148,41 @@ bool AbstractState::execute(unsigned indexInBlock)
}
case CreateThis: {
- AbstractValue& source = forNode(node.child1());
- AbstractValue& destination = forNode(nodeIndex);
-
- node.setCanExit(!isCellSpeculation(source.m_type));
-
- source.filter(SpecFunction);
- destination.set(SpecFinalObject);
+ forNode(node).set(SpecFinalObject);
break;
}
- case InheritorIDWatchpoint:
- node.setCanExit(true);
+ case AllocationProfileWatchpoint:
+ node->setCanExit(true);
break;
case NewObject:
- node.setCanExit(false);
- forNode(nodeIndex).set(node.structure());
+ forNode(node).set(node->structure());
m_haveStructures = true;
break;
case CreateActivation:
- node.setCanExit(false);
- forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->activationStructure());
+ forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->activationStructure());
m_haveStructures = true;
break;
case CreateArguments:
- node.setCanExit(false);
- forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->argumentsStructure());
+ forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->argumentsStructure());
m_haveStructures = true;
break;
case TearOffActivation:
case TearOffArguments:
- node.setCanExit(false);
// Does nothing that is user-visible.
break;
case CheckArgumentsNotCreated:
if (isEmptySpeculation(
m_variables.operand(
- m_graph.argumentsRegisterFor(node.codeOrigin)).m_type)) {
- node.setCanExit(false);
+ m_graph.argumentsRegisterFor(node->codeOrigin)).m_type))
m_foundConstants = true;
- } else
- node.setCanExit(true);
+ else
+ node->setCanExit(true);
break;
case GetMyArgumentsLength:
@@ -1331,93 +1190,108 @@ bool AbstractState::execute(unsigned indexInBlock)
// the arguments a bit. Note that this is not sufficient to force constant folding
// of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
// We perform further optimizations on this later on.
- if (node.codeOrigin.inlineCallFrame)
- forNode(nodeIndex).set(jsNumber(node.codeOrigin.inlineCallFrame->arguments.size() - 1));
+ if (node->codeOrigin.inlineCallFrame)
+ forNode(node).set(jsNumber(node->codeOrigin.inlineCallFrame->arguments.size() - 1));
else
- forNode(nodeIndex).set(SpecInt32);
- node.setCanExit(
+ forNode(node).set(SpecInt32);
+ node->setCanExit(
!isEmptySpeculation(
m_variables.operand(
- m_graph.argumentsRegisterFor(node.codeOrigin)).m_type));
+ m_graph.argumentsRegisterFor(node->codeOrigin)).m_type));
break;
case GetMyArgumentsLengthSafe:
- node.setCanExit(false);
// This potentially clobbers all structures if the arguments object had a getter
// installed on the length property.
- clobberWorld(node.codeOrigin, indexInBlock);
+ clobberWorld(node->codeOrigin, indexInBlock);
// We currently make no guarantee about what this returns because it does not
// speculate that the length property is actually a length.
- forNode(nodeIndex).makeTop();
+ forNode(node).makeTop();
break;
case GetMyArgumentByVal:
- node.setCanExit(true);
+ node->setCanExit(true);
// We know that this executable does not escape its arguments, so we can optimize
// the arguments a bit. Note that this ends up being further optimized by the
// ArgumentsSimplificationPhase.
- forNode(node.child1()).filter(SpecInt32);
- forNode(nodeIndex).makeTop();
+ forNode(node).makeTop();
break;
case GetMyArgumentByValSafe:
- node.setCanExit(true);
+ node->setCanExit(true);
// This potentially clobbers all structures if the property we're accessing has
// a getter. We don't speculate against this.
- clobberWorld(node.codeOrigin, indexInBlock);
- // But we do speculate that the index is an integer.
- forNode(node.child1()).filter(SpecInt32);
+ clobberWorld(node->codeOrigin, indexInBlock);
// And the result is unknown.
- forNode(nodeIndex).makeTop();
+ forNode(node).makeTop();
break;
- case NewFunction:
+ case NewFunction: {
+ AbstractValue& value = forNode(node);
+ value = forNode(node->child1());
+
+ if (!(value.m_type & SpecEmpty)) {
+ m_foundConstants = true;
+ break;
+ }
+
+ value.set((value.m_type & ~SpecEmpty) | SpecFunction);
+ break;
+ }
+
case NewFunctionExpression:
case NewFunctionNoCheck:
- node.setCanExit(false);
- forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure());
+ forNode(node).set(m_codeBlock->globalObjectFor(node->codeOrigin)->functionStructure());
break;
case GetCallee:
- node.setCanExit(false);
- forNode(nodeIndex).set(SpecFunction);
+ forNode(node).set(SpecFunction);
+ break;
+
+ case SetCallee:
+ case SetMyScope:
break;
- case GetScope:
- node.setCanExit(false);
- forNode(nodeIndex).set(SpecCellOther);
+ case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
+ case GetMyScope:
+ case SkipTopScope:
+ forNode(node).set(SpecCellOther);
+ break;
+
+ case SkipScope: {
+ JSValue child = forNode(node->child1()).value();
+ if (child && trySetConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()))) {
+ m_foundConstants = true;
+ break;
+ }
+ forNode(node).set(SpecCellOther);
break;
+ }
case GetScopeRegisters:
- node.setCanExit(false);
- forNode(node.child1()).filter(SpecCell);
- forNode(nodeIndex).clear(); // The result is not a JS value.
+ forNode(node).clear(); // The result is not a JS value.
break;
case GetScopedVar:
- node.setCanExit(false);
- forNode(nodeIndex).makeTop();
+ forNode(node).makeTop();
break;
case PutScopedVar:
- node.setCanExit(false);
- clobberCapturedVars(node.codeOrigin);
+ clobberCapturedVars(node->codeOrigin);
break;
case GetById:
case GetByIdFlush:
- node.setCanExit(true);
- if (!node.prediction()) {
+ node->setCanExit(true);
+ if (!node->prediction()) {
m_isValid = false;
break;
}
- if (isCellSpeculation(m_graph[node.child1()].prediction())) {
- forNode(node.child1()).filter(SpecCell);
-
- if (Structure* structure = forNode(node.child1()).bestProvenStructure()) {
+ if (isCellSpeculation(node->child1()->prediction())) {
+ if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
GetByIdStatus status = GetByIdStatus::computeFor(
- m_graph.m_globalData, structure,
- m_graph.m_codeBlock->identifier(node.identifierNumber()));
+ m_graph.m_vm, structure,
+ m_graph.m_codeBlock->identifier(node->identifierNumber()));
if (status.isSimple()) {
// Assert things that we can't handle and that the computeFor() method
// above won't be able to return.
@@ -1425,39 +1299,48 @@ bool AbstractState::execute(unsigned indexInBlock)
ASSERT(status.chain().isEmpty());
if (status.specificValue())
- forNode(nodeIndex).set(status.specificValue());
+ forNode(node).set(status.specificValue());
else
- forNode(nodeIndex).makeTop();
- forNode(node.child1()).filter(status.structureSet());
+ forNode(node).makeTop();
+ forNode(node->child1()).filter(status.structureSet());
m_foundConstants = true;
break;
}
}
}
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
break;
case GetArrayLength:
- node.setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
- forNode(nodeIndex).set(SpecInt32);
+ node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
+ forNode(node).set(SpecInt32);
break;
+
+ case CheckExecutable: {
+ // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
+ // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
+ // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
+ // https://bugs.webkit.org/show_bug.cgi?id=106201
+ node->setCanExit(true);
+ break;
+ }
case CheckStructure:
case ForwardCheckStructure: {
// FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
- AbstractValue& value = forNode(node.child1());
+ AbstractValue& value = forNode(node->child1());
+ ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
// If this structure check is attempting to prove knowledge already held in
// the futurePossibleStructure set then the constant folding phase should
// turn this into a watchpoint instead.
- StructureSet& set = node.structureSet();
+ StructureSet& set = node->structureSet();
if (value.m_futurePossibleStructure.isSubsetOf(set)
|| value.m_currentKnownStructure.isSubsetOf(set))
m_foundConstants = true;
- node.setCanExit(
- !value.m_currentKnownStructure.isSubsetOf(set)
- || !isCellSpeculation(value.m_type));
+ if (!value.m_currentKnownStructure.isSubsetOf(set))
+ node->setCanExit(true);
value.filter(set);
m_haveStructures = true;
break;
@@ -1465,7 +1348,7 @@ bool AbstractState::execute(unsigned indexInBlock)
case StructureTransitionWatchpoint:
case ForwardStructureTransitionWatchpoint: {
- AbstractValue& value = forNode(node.child1());
+ AbstractValue& value = forNode(node->child1());
// It's only valid to issue a structure transition watchpoint if we already
// know that the watchpoint covers a superset of the structures known to
@@ -1473,229 +1356,185 @@ bool AbstractState::execute(unsigned indexInBlock)
// Currently, we only issue singleton watchpoints (that check one structure)
// and our futurePossibleStructure set can only contain zero, one, or an
// infinity of structures.
- ASSERT(value.m_futurePossibleStructure.isSubsetOf(StructureSet(node.structure())));
+ ASSERT(value.m_futurePossibleStructure.isSubsetOf(StructureSet(node->structure())));
- ASSERT(value.isClear() || isCellSpeculation(value.m_type)); // Value could be clear if we've proven must-exit due to a speculation statically known to be bad.
- value.filter(node.structure());
+ value.filter(node->structure());
m_haveStructures = true;
- node.setCanExit(true);
+ node->setCanExit(true);
break;
}
case PutStructure:
case PhantomPutStructure:
- node.setCanExit(false);
- if (!forNode(node.child1()).m_currentKnownStructure.isClear()) {
+ if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
clobberStructures(indexInBlock);
- forNode(node.child1()).set(node.structureTransitionData().newStructure);
+ forNode(node->child1()).set(node->structureTransitionData().newStructure);
m_haveStructures = true;
}
break;
case GetButterfly:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
- node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
- forNode(node.child1()).filter(SpecCell);
- forNode(nodeIndex).clear(); // The result is not a JS value.
+ forNode(node).clear(); // The result is not a JS value.
break;
case CheckArray: {
- if (node.arrayMode().alreadyChecked(m_graph, node, forNode(node.child1()))) {
+ if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- node.setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
- switch (node.arrayMode().type()) {
+ node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
+ switch (node->arrayMode().type()) {
case Array::String:
- forNode(node.child1()).filter(SpecString);
+ forNode(node->child1()).filter(SpecString);
break;
case Array::Int32:
case Array::Double:
case Array::Contiguous:
case Array::ArrayStorage:
case Array::SlowPutArrayStorage:
- forNode(node.child1()).filter(SpecCell);
break;
case Array::Arguments:
- forNode(node.child1()).filter(SpecArguments);
+ forNode(node->child1()).filter(SpecArguments);
break;
case Array::Int8Array:
- forNode(node.child1()).filter(SpecInt8Array);
+ forNode(node->child1()).filter(SpecInt8Array);
break;
case Array::Int16Array:
- forNode(node.child1()).filter(SpecInt16Array);
+ forNode(node->child1()).filter(SpecInt16Array);
break;
case Array::Int32Array:
- forNode(node.child1()).filter(SpecInt32Array);
+ forNode(node->child1()).filter(SpecInt32Array);
break;
case Array::Uint8Array:
- forNode(node.child1()).filter(SpecUint8Array);
+ forNode(node->child1()).filter(SpecUint8Array);
break;
case Array::Uint8ClampedArray:
- forNode(node.child1()).filter(SpecUint8ClampedArray);
+ forNode(node->child1()).filter(SpecUint8ClampedArray);
break;
case Array::Uint16Array:
- forNode(node.child1()).filter(SpecUint16Array);
+ forNode(node->child1()).filter(SpecUint16Array);
break;
case Array::Uint32Array:
- forNode(node.child1()).filter(SpecUint32Array);
+ forNode(node->child1()).filter(SpecUint32Array);
break;
case Array::Float32Array:
- forNode(node.child1()).filter(SpecFloat32Array);
+ forNode(node->child1()).filter(SpecFloat32Array);
break;
case Array::Float64Array:
- forNode(node.child1()).filter(SpecFloat64Array);
+ forNode(node->child1()).filter(SpecFloat64Array);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
+ forNode(node->child1()).filterArrayModes(node->arrayMode().arrayModesThatPassFiltering());
m_haveStructures = true;
break;
}
case Arrayify: {
- if (node.arrayMode().alreadyChecked(m_graph, node, forNode(node.child1()))) {
+ if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
m_foundConstants = true;
- node.setCanExit(false);
break;
}
- ASSERT(node.arrayMode().conversion() == Array::Convert);
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecCell);
- if (node.child2())
- forNode(node.child2()).filter(SpecInt32);
+ ASSERT(node->arrayMode().conversion() == Array::Convert
+ || node->arrayMode().conversion() == Array::RageConvert);
+ node->setCanExit(true);
clobberStructures(indexInBlock);
- forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
+ forNode(node->child1()).filterArrayModes(node->arrayMode().arrayModesThatPassFiltering());
m_haveStructures = true;
break;
}
case ArrayifyToStructure: {
- AbstractValue& value = forNode(node.child1());
- StructureSet set = node.structure();
+ AbstractValue& value = forNode(node->child1());
+ StructureSet set = node->structure();
if (value.m_futurePossibleStructure.isSubsetOf(set)
|| value.m_currentKnownStructure.isSubsetOf(set))
m_foundConstants = true;
- node.setCanExit(true);
+ node->setCanExit(true);
clobberStructures(indexInBlock);
value.filter(set);
m_haveStructures = true;
break;
}
case GetIndexedPropertyStorage: {
- switch (node.arrayMode().type()) {
- case Array::String:
- // Strings are weird - we may spec fail if the string was a rope. That is of course
- // stupid, and we should fix that, but for now let's at least be honest about it.
- node.setCanExit(true);
- break;
- default:
- node.setCanExit(false);
- break;
- }
- forNode(nodeIndex).clear();
+ forNode(node).clear();
break;
}
- case GetByOffset:
- if (!m_graph[node.child1()].hasStorageResult()) {
- node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
- forNode(node.child1()).filter(SpecCell);
- }
- forNode(nodeIndex).makeTop();
+ case GetByOffset: {
+ forNode(node).makeTop();
break;
+ }
case PutByOffset: {
- bool canExit = false;
- if (!m_graph[node.child1()].hasStorageResult()) {
- canExit |= !isCellSpeculation(forNode(node.child1()).m_type);
- forNode(node.child1()).filter(SpecCell);
- }
- canExit |= !isCellSpeculation(forNode(node.child2()).m_type);
- forNode(node.child2()).filter(SpecCell);
- node.setCanExit(canExit);
break;
}
case CheckFunction: {
- JSValue value = forNode(node.child1()).value();
- if (value == node.function()) {
+ JSValue value = forNode(node->child1()).value();
+ if (value == node->function()) {
m_foundConstants = true;
ASSERT(value);
- node.setCanExit(false);
break;
}
- node.setCanExit(true); // Lies! We can do better.
- if (!forNode(node.child1()).filterByValue(node.function())) {
- m_isValid = false;
- break;
- }
+ node->setCanExit(true); // Lies! We can do better.
+ forNode(node->child1()).filterByValue(node->function());
break;
}
case PutById:
case PutByIdDirect:
- node.setCanExit(true);
- if (Structure* structure = forNode(node.child1()).bestProvenStructure()) {
+ node->setCanExit(true);
+ if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
PutByIdStatus status = PutByIdStatus::computeFor(
- m_graph.m_globalData,
- m_graph.globalObjectFor(node.codeOrigin),
+ m_graph.m_vm,
+ m_graph.globalObjectFor(node->codeOrigin),
structure,
- m_graph.m_codeBlock->identifier(node.identifierNumber()),
- node.op() == PutByIdDirect);
+ m_graph.m_codeBlock->identifier(node->identifierNumber()),
+ node->op() == PutByIdDirect);
if (status.isSimpleReplace()) {
- forNode(node.child1()).filter(structure);
+ forNode(node->child1()).filter(structure);
m_foundConstants = true;
break;
}
if (status.isSimpleTransition()) {
clobberStructures(indexInBlock);
- forNode(node.child1()).set(status.newStructure());
+ forNode(node->child1()).set(status.newStructure());
m_haveStructures = true;
m_foundConstants = true;
break;
}
}
- forNode(node.child1()).filter(SpecCell);
- clobberWorld(node.codeOrigin, indexInBlock);
+ clobberWorld(node->codeOrigin, indexInBlock);
break;
case GetGlobalVar:
- node.setCanExit(false);
- forNode(nodeIndex).makeTop();
+ forNode(node).makeTop();
break;
case GlobalVarWatchpoint:
- node.setCanExit(true);
+ node->setCanExit(true);
break;
case PutGlobalVar:
case PutGlobalVarCheck:
- node.setCanExit(false);
break;
case CheckHasInstance:
- node.setCanExit(true);
- forNode(node.child1()).filter(SpecCell);
+ node->setCanExit(true);
// Sadly, we don't propagate the fact that we've done CheckHasInstance
break;
case InstanceOf:
- node.setCanExit(true);
+ node->setCanExit(true);
// Again, sadly, we don't propagate the fact that we've done InstanceOf
- if (!(m_graph[node.child1()].prediction() & ~SpecCell) && !(forNode(node.child1()).m_type & ~SpecCell))
- forNode(node.child1()).filter(SpecCell);
- forNode(node.child2()).filter(SpecCell);
- forNode(nodeIndex).set(SpecBoolean);
+ forNode(node).set(SpecBoolean);
break;
case Phi:
case Flush:
- node.setCanExit(false);
- break;
-
+ case PhantomLocal:
case Breakpoint:
- node.setCanExit(false);
break;
case Call:
@@ -1704,35 +1543,54 @@ bool AbstractState::execute(unsigned indexInBlock)
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
- node.setCanExit(true);
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ node->setCanExit(true);
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
break;
case GarbageValue:
- clobberWorld(node.codeOrigin, indexInBlock);
- forNode(nodeIndex).makeTop();
+ clobberWorld(node->codeOrigin, indexInBlock);
+ forNode(node).makeTop();
break;
case ForceOSRExit:
- node.setCanExit(true);
+ node->setCanExit(true);
m_isValid = false;
break;
+ case CheckWatchdogTimer:
+ node->setCanExit(true);
+ break;
+
case Phantom:
case InlineStart:
case Nop:
- node.setCanExit(false);
+ case CountExecution:
break;
case LastNodeType:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
return m_isValid;
}
+bool AbstractState::executeEffects(unsigned indexInBlock)
+{
+ return executeEffects(indexInBlock, m_block->at(indexInBlock));
+}
+
+bool AbstractState::execute(unsigned indexInBlock)
+{
+ Node* node = m_block->at(indexInBlock);
+ if (!startExecuting(node))
+ return true;
+
+ executeEdges(node);
+ return executeEffects(indexInBlock, node);
+}
+
inline void AbstractState::clobberWorld(const CodeOrigin& codeOrigin, unsigned indexInBlock)
{
clobberCapturedVars(codeOrigin);
@@ -1775,22 +1633,19 @@ inline void AbstractState::clobberStructures(unsigned indexInBlock)
m_didClobber = true;
}
-inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex nodeIndex)
+inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, Node* node)
{
- if (nodeIndex == NoNode)
+ if (!node)
return false;
AbstractValue source;
-
- Node& node = m_graph[nodeIndex];
- if (!node.refCount())
- return false;
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" It's live, node @%u.\n", nodeIndex);
-#endif
- if (node.variableAccessData()->isCaptured()) {
+ if (node->variableAccessData()->isCaptured()) {
+ // If it's captured then we know that whatever value was stored into the variable last is the
+ // one we care about. This is true even if the variable at tail is dead, which might happen if
+ // the last thing we did to the variable was a GetLocal and then ended up now using the
+ // GetLocal's result.
+
source = inVariable;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" Transfering ");
@@ -1798,9 +1653,14 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
dataLogF(" from last access due to captured variable.\n");
#endif
} else {
- switch (node.op()) {
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLogF(" It's live, node @%u.\n", node->index());
+#endif
+
+ switch (node->op()) {
case Phi:
case SetArgument:
+ case PhantomLocal:
case Flush:
// The block transfers the value from head to tail.
source = inVariable;
@@ -1813,7 +1673,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case GetLocal:
// The block refines the value with additional speculations.
- source = forNode(nodeIndex);
+ source = forNode(node);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" Refining to ");
source.dump(WTF::dataFile());
@@ -1824,11 +1684,11 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
case SetLocal:
// The block sets the variable, and potentially refines it, both
// before and after setting it.
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
+ if (node->variableAccessData()->shouldUseDoubleFormat()) {
// FIXME: This unnecessarily loses precision.
source.set(SpecDouble);
} else
- source = forNode(node.child1());
+ source = forNode(node->child1());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" Setting to ");
source.dump(WTF::dataFile());
@@ -1837,7 +1697,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
@@ -1886,35 +1746,34 @@ inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to)
return changed;
}
-inline bool AbstractState::mergeToSuccessors(
- Graph& graph, BasicBlock* basicBlock)
+inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBlock)
{
- Node& terminal = graph[basicBlock->last()];
+ Node* terminal = basicBlock->last();
- ASSERT(terminal.isTerminal());
+ ASSERT(terminal->isTerminal());
- switch (terminal.op()) {
+ switch (terminal->op()) {
case Jump: {
ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Merging to block #%u.\n", terminal.takenBlockIndex());
+ dataLogF(" Merging to block #%u.\n", terminal->takenBlockIndex());
#endif
- return merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get());
+ return merge(basicBlock, graph.m_blocks[terminal->takenBlockIndex()].get());
}
case Branch: {
ASSERT(basicBlock->cfaBranchDirection != InvalidBranchDirection);
bool changed = false;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Merging to block #%u.\n", terminal.takenBlockIndex());
+ dataLogF(" Merging to block #%u.\n", terminal->takenBlockIndex());
#endif
if (basicBlock->cfaBranchDirection != TakeFalse)
- changed |= merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get());
+ changed |= merge(basicBlock, graph.m_blocks[terminal->takenBlockIndex()].get());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Merging to block #%u.\n", terminal.notTakenBlockIndex());
+ dataLogF(" Merging to block #%u.\n", terminal->notTakenBlockIndex());
#endif
if (basicBlock->cfaBranchDirection != TakeTrue)
- changed |= merge(basicBlock, graph.m_blocks[terminal.notTakenBlockIndex()].get());
+ changed |= merge(basicBlock, graph.m_blocks[terminal->notTakenBlockIndex()].get());
return changed;
}
@@ -1925,17 +1784,17 @@ inline bool AbstractState::mergeToSuccessors(
return false;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
-inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, NodeIndex destinationNodeIndex, NodeIndex sourceNodeIndex)
+inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, Node* destinationNode, Node* sourceNode)
{
- if (destinationNodeIndex == NoNode)
+ if (!destinationNode)
return false;
- ASSERT_UNUSED(sourceNodeIndex, sourceNodeIndex != NoNode);
+ ASSERT_UNUSED(sourceNode, sourceNode);
// FIXME: We could do some sparse conditional propagation here!
@@ -1946,15 +1805,15 @@ void AbstractState::dump(PrintStream& out)
{
bool first = true;
for (size_t i = 0; i < m_block->size(); ++i) {
- NodeIndex index = m_block->at(i);
- AbstractValue& value = m_nodes[index];
+ Node* node = m_block->at(i);
+ AbstractValue& value = forNode(node);
if (value.isClear())
continue;
if (first)
first = false;
else
out.printf(" ");
- out.printf("@%lu:", static_cast<unsigned long>(index));
+ out.printf("@%lu:", static_cast<unsigned long>(node->index()));
value.dump(out);
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h
index 40dc50248..de1f17d1f 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -72,8 +72,8 @@ struct BasicBlock;
// AbstractState state(codeBlock, graph);
// state.beginBasicBlock(basicBlock);
// bool endReached = true;
-// for (NodeIndex idx = basicBlock.begin; idx < basicBlock.end; ++idx) {
-// if (!state.execute(idx))
+// for (unsigned i = 0; i < basicBlock->size(); ++i) {
+// if (!state.execute(i))
// break;
// }
// bool result = state.endBasicBlock(<either Merge or DontMerge>);
@@ -97,14 +97,14 @@ public:
~AbstractState();
- AbstractValue& forNode(NodeIndex nodeIndex)
+ AbstractValue& forNode(Node* node)
{
- return m_nodes[nodeIndex];
+ return node->value;
}
- AbstractValue& forNode(Edge nodeUse)
+ AbstractValue& forNode(Edge edge)
{
- return forNode(nodeUse.index());
+ return forNode(edge.node());
}
Operands<AbstractValue>& variables()
@@ -158,7 +158,53 @@ 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(unsigned);
+ //
+ // This is guaranteed to be equivalent to doing:
+ //
+ // if (state.startExecuting(index)) {
+ // state.executeEdges(index);
+ // result = state.executeEffects(index);
+ // } else
+ // result = true;
+ bool execute(unsigned indexInBlock);
+
+ // Indicate the start of execution of the node. It resets any state in the node,
+ // that is progressively built up by executeEdges() and executeEffects(). In
+ // particular, this resets canExit(), so if you want to "know" between calls of
+ // startExecuting() and executeEdges()/Effects() whether the last run of the
+ // analysis concluded that the node can exit, you should probably set that
+ // information aside prior to calling startExecuting().
+ bool startExecuting(Node*);
+ bool startExecuting(unsigned indexInBlock);
+
+ // Abstractly execute the edges of the given node. This runs filterEdgeByUse()
+ // on all edges of the node. You can skip this step, if you have already used
+ // filterEdgeByUse() (or some equivalent) on each edge.
+ void executeEdges(Node*);
+ void executeEdges(unsigned indexInBlock);
+
+ ALWAYS_INLINE void filterEdgeByUse(Node* node, Edge& edge)
+ {
+#if !ASSERT_DISABLED
+ switch (edge.useKind()) {
+ case KnownInt32Use:
+ case KnownNumberUse:
+ case KnownCellUse:
+ case KnownStringUse:
+ ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
+ break;
+ default:
+ break;
+ }
+#endif // !ASSERT_DISABLED
+
+ filterByType(node, edge, typeFilterFor(edge.useKind()));
+ }
+
+ // Abstractly execute the effects of the given node. This changes the abstract
+ // state assuming that edges have already been filtered.
+ bool executeEffects(unsigned indexInBlock);
+ bool executeEffects(unsigned indexInBlock, Node*);
// Did the last executed node clobber the world?
bool didClobber() const { return m_didClobber; }
@@ -187,62 +233,18 @@ private:
void clobberCapturedVars(const CodeOrigin&);
void clobberStructures(unsigned indexInBlock);
- bool mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex);
-
- static bool mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, NodeIndex destinationNodeIndex, NodeIndex sourceNodeIndex);
+ bool mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, Node*);
- void speculateInt32Unary(Node& node, bool forceCanExit = false)
- {
- AbstractValue& childValue = forNode(node.child1());
- node.setCanExit(forceCanExit || !isInt32Speculation(childValue.m_type));
- childValue.filter(SpecInt32);
- }
-
- void speculateNumberUnary(Node& node)
- {
- AbstractValue& childValue = forNode(node.child1());
- node.setCanExit(!isNumberSpeculation(childValue.m_type));
- childValue.filter(SpecNumber);
- }
-
- void speculateBooleanUnary(Node& node)
- {
- AbstractValue& childValue = forNode(node.child1());
- node.setCanExit(!isBooleanSpeculation(childValue.m_type));
- childValue.filter(SpecBoolean);
- }
-
- void speculateInt32Binary(Node& node, bool forceCanExit = false)
- {
- AbstractValue& childValue1 = forNode(node.child1());
- AbstractValue& childValue2 = forNode(node.child2());
- node.setCanExit(
- forceCanExit
- || !isInt32Speculation(childValue1.m_type)
- || !isInt32Speculation(childValue2.m_type));
- childValue1.filter(SpecInt32);
- childValue2.filter(SpecInt32);
- }
-
- void speculateNumberBinary(Node& node)
- {
- AbstractValue& childValue1 = forNode(node.child1());
- AbstractValue& childValue2 = forNode(node.child2());
- node.setCanExit(
- !isNumberSpeculation(childValue1.m_type)
- || !isNumberSpeculation(childValue2.m_type));
- childValue1.filter(SpecNumber);
- childValue2.filter(SpecNumber);
- }
+ static bool mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, Node* destinationNode, Node* sourceNode);
enum BooleanResult {
UnknownBooleanResult,
DefinitelyFalse,
DefinitelyTrue
};
- BooleanResult booleanResult(Node&, AbstractValue&);
+ BooleanResult booleanResult(Node*, AbstractValue&);
- bool trySetConstant(NodeIndex nodeIndex, JSValue value)
+ bool trySetConstant(Node* node, JSValue value)
{
// Make sure we don't constant fold something that will produce values that contravene
// predictions. If that happens then we know that the code will OSR exit, forcing
@@ -251,18 +253,32 @@ private:
// lot of subtle code that assumes that
// speculationFromValue(jsConstant) == jsConstant.prediction(). "Hardening" that code
// is probably less sane than just pulling back on constant folding.
- SpeculatedType oldType = m_graph[nodeIndex].prediction();
+ SpeculatedType oldType = node->prediction();
if (mergeSpeculations(speculationFromValue(value), oldType) != oldType)
return false;
- forNode(nodeIndex).set(value);
+ forNode(node).set(value);
return true;
}
+ ALWAYS_INLINE void filterByType(Node* node, Edge& edge, SpeculatedType type)
+ {
+ AbstractValue& value = forNode(edge);
+ if (value.m_type & ~type) {
+ node->setCanExit(true);
+ edge.setProofStatus(NeedsCheck);
+ } else
+ edge.setProofStatus(IsProved);
+
+ value.filter(type);
+ }
+
+ void verifyEdge(Node*, Edge);
+ void verifyEdges(Node*);
+
CodeBlock* m_codeBlock;
Graph& m_graph;
- 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 0ce01ab56..25757b54e 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -65,7 +65,7 @@ struct AbstractValue {
void makeTop()
{
- m_type = SpecTop;
+ m_type |= SpecTop; // The state may have included SpecEmpty, in which case we want this to become SpecEmptyOrTop.
m_arrayModes = ALL_ARRAY_MODES;
m_currentKnownStructure.makeTop();
m_futurePossibleStructure.makeTop();
@@ -193,6 +193,9 @@ struct AbstractValue {
bool merge(const AbstractValue& other)
{
+ if (other.isClear())
+ return false;
+
#if !ASSERT_DISABLED
AbstractValue oldMe = *this;
#endif
@@ -231,6 +234,9 @@ struct AbstractValue {
void filter(const StructureSet& other)
{
+ // FIXME: This could be optimized for the common case of m_type not
+ // having structures, array modes, or a specific value.
+ // https://bugs.webkit.org/show_bug.cgi?id=109663
m_type &= other.speculationFromStructures();
m_arrayModes &= other.arrayModesFromStructures();
m_currentKnownStructure.filter(other);
@@ -284,19 +290,11 @@ struct AbstractValue {
checkConsistency();
}
- bool filterByValue(JSValue value)
+ void filterByValue(JSValue value)
{
- if (!validate(value))
- return false;
-
- if (!!value && value.isCell())
- filter(StructureSet(value.asCell()->structure()));
- else
- filter(speculationFromValue(value));
-
- m_value = value;
-
- return true;
+ filter(speculationFromValue(value));
+ if (m_type)
+ m_value = value;
}
bool validateType(JSValue value) const
@@ -374,10 +372,10 @@ struct AbstractValue {
void dump(PrintStream& out) const
{
out.print(
- "(", SpeculationDump(m_type), ", ", arrayModesToString(m_arrayModes), ", ",
+ "(", SpeculationDump(m_type), ", ", ArrayModesDump(m_arrayModes), ", ",
m_currentKnownStructure, ", ", m_futurePossibleStructure);
if (!!m_value)
- out.print(", ", m_value.description());
+ out.print(", ", m_value);
out.print(")");
}
@@ -415,6 +413,8 @@ struct AbstractValue {
// change x's structure and we have no way of proving otherwise, but
// x's m_futurePossibleStructure will be whatever structure we had checked
// when getting property 'f'.
+
+ // NB. All fields in this struct must have trivial destructors.
// This is a proven constraint on the structures that this value can have right
// now. The structure of the current value must belong to this set. The set may
@@ -525,8 +525,17 @@ private:
m_arrayModes = 0;
else if (!(m_type & ~SpecArray))
m_arrayModes &= ALL_ARRAY_ARRAY_MODES;
- else if (!(m_type & SpecArray))
- m_arrayModes &= ALL_NON_ARRAY_ARRAY_MODES;
+
+ // NOTE: If m_type doesn't have SpecArray set, that doesn't mean that the
+ // array modes have to be a subset of ALL_NON_ARRAY_ARRAY_MODES, since
+ // in the speculated type type-system, RegExpMatchesArry and ArrayPrototype
+ // are Otherobj (since they are not *exactly* JSArray) but in the ArrayModes
+ // type system they are arrays (since they expose the magical length
+ // property and are otherwise allocated using array allocation). Hence the
+ // following would be wrong:
+ //
+ // if (!(m_type & SpecArray))
+ // m_arrayModes &= ALL_NON_ARRAY_ARRAY_MODES;
}
};
diff --git a/Source/JavaScriptCore/dfg/DFGAdjacencyList.h b/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
index 921a67a93..d3f925d4b 100644
--- a/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
+++ b/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -47,9 +47,6 @@ public:
AdjacencyList() { }
AdjacencyList(Kind kind)
-#if !ASSERT_DISABLED
- : m_kind(kind)
-#endif
{
if (kind == Variable) {
m_words[0].m_encodedWord = UINT_MAX;
@@ -57,19 +54,13 @@ public:
}
}
- AdjacencyList(Kind kind, NodeIndex child1, NodeIndex child2, NodeIndex child3)
-#if !ASSERT_DISABLED
- : m_kind(Fixed)
-#endif
+ AdjacencyList(Kind kind, Edge child1, Edge child2, Edge child3)
{
ASSERT_UNUSED(kind, kind == Fixed);
initialize(child1, child2, child3);
}
AdjacencyList(Kind kind, unsigned firstChild, unsigned numChildren)
-#if !ASSERT_DISABLED
- : m_kind(Variable)
-#endif
{
ASSERT_UNUSED(kind, kind == Variable);
setFirstChild(firstChild);
@@ -79,21 +70,18 @@ public:
const Edge& child(unsigned i) const
{
ASSERT(i < Size);
- ASSERT(m_kind == Fixed);
return m_words[i];
}
Edge& child(unsigned i)
{
ASSERT(i < Size);
- ASSERT(m_kind == Fixed);
return m_words[i];
}
void setChild(unsigned i, Edge nodeUse)
{
ASSERT(i < Size);
- ASSERT(m_kind == Fixed);
m_words[i] = nodeUse;
}
@@ -118,22 +106,18 @@ public:
child(2) = child3;
}
- void initialize(NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ void initialize(Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
{
initialize(Edge(child1), Edge(child2), Edge(child3));
}
void reset()
{
-#if !ASSERT_DISABLED
- m_kind = Fixed;
-#endif
initialize();
}
- // Call this if you wish to remove an edge and the node treats the list of children
- // as a "bag" - an unordered set where the index of the edge does not matter.
- void removeEdgeFromBag(unsigned edgeIndex)
+ // Call this if you wish to remove an edge and the node treats the list of children.
+ void removeEdge(unsigned edgeIndex)
{
for (unsigned i = edgeIndex; i < Size - 1; ++i)
setChild(i, child(i + 1));
@@ -142,31 +126,24 @@ public:
unsigned firstChild() const
{
- ASSERT(m_kind == Variable);
return m_words[0].m_encodedWord;
}
void setFirstChild(unsigned firstChild)
{
- ASSERT(m_kind == Variable);
m_words[0].m_encodedWord = firstChild;
}
unsigned numChildren() const
{
- ASSERT(m_kind == Variable);
return m_words[1].m_encodedWord;
}
void setNumChildren(unsigned numChildren)
{
- ASSERT(m_kind == Variable);
m_words[1].m_encodedWord = numChildren;
}
private:
Edge m_words[Size];
-#if !ASSERT_DISABLED
- Kind m_kind;
-#endif
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGAllocator.h b/Source/JavaScriptCore/dfg/DFGAllocator.h
new file mode 100644
index 000000000..f4d3eb58d
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGAllocator.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGAllocator_h
+#define DFGAllocator_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include <wtf/PageAllocationAligned.h>
+#include <wtf/StdLibExtras.h>
+
+namespace JSC { namespace DFG {
+
+// Custom pool allocator for exactly one type (type T). It has fast (O(1), only a few
+// instructions) allocator, and a similarly fast free(). Recycling works if either of
+// the following is true:
+// - T has a trivial destructor. In that case you don't have to ever call free() on
+// anything. You can just call freeAll() instead.
+// - You call free() on all T's that you allocated, and never use freeAll().
+
+template<typename T>
+class Allocator {
+public:
+ Allocator();
+ ~Allocator();
+
+ void* allocate(); // Use placement new to allocate, and avoid using this method.
+ void free(T*); // Call this method to delete; never use 'delete' directly.
+
+ void freeAll(); // Only call this if T has a trivial destructor.
+ void reset(); // Like freeAll(), but also returns all memory to the OS.
+
+ unsigned indexOf(const T*);
+
+ static Allocator* allocatorOf(const T*);
+
+private:
+ void* bumpAllocate();
+ void* freeListAllocate();
+ void* allocateSlow();
+
+ struct Region {
+ static size_t size() { return 64 * KB; }
+ static size_t headerSize() { return std::max(sizeof(Region), sizeof(T)); }
+ static unsigned numberOfThingsPerRegion() { return (size() - headerSize()) / sizeof(T); }
+ T* data() { return bitwise_cast<T*>(bitwise_cast<char*>(this) + headerSize()); }
+ bool isInThisRegion(const T* pointer) { return static_cast<unsigned>(pointer - data()) < numberOfThingsPerRegion(); }
+ static Region* regionFor(const T* pointer) { return bitwise_cast<Region*>(bitwise_cast<uintptr_t>(pointer) & ~(size() - 1)); }
+
+ PageAllocationAligned m_allocation;
+ Allocator* m_allocator;
+ Region* m_next;
+ };
+
+ void freeRegionsStartingAt(Allocator::Region*);
+ void startBumpingIn(Allocator::Region*);
+
+ Region* m_regionHead;
+ void** m_freeListHead;
+ T* m_bumpEnd;
+ unsigned m_bumpRemaining;
+};
+
+template<typename T>
+inline Allocator<T>::Allocator()
+ : m_regionHead(0)
+ , m_freeListHead(0)
+ , m_bumpRemaining(0)
+{
+}
+
+template<typename T>
+inline Allocator<T>::~Allocator()
+{
+ reset();
+}
+
+template<typename T>
+ALWAYS_INLINE void* Allocator<T>::allocate()
+{
+ void* result = bumpAllocate();
+ if (LIKELY(!!result))
+ return result;
+ return freeListAllocate();
+}
+
+template<typename T>
+void Allocator<T>::free(T* object)
+{
+ object->~T();
+
+ void** cell = bitwise_cast<void**>(object);
+ *cell = m_freeListHead;
+ m_freeListHead = cell;
+}
+
+template<typename T>
+void Allocator<T>::freeAll()
+{
+ if (!m_regionHead) {
+ ASSERT(!m_bumpRemaining);
+ ASSERT(!m_freeListHead);
+ return;
+ }
+
+ // Since the caller is opting out of calling the destructor for any allocated thing,
+ // we have two choices, plus a continuum between: we can either just delete all regions
+ // (i.e. call reset()), or we can make all regions available for reuse. We do something
+ // that optimizes for (a) speed of freeAll(), (b) the assumption that if the user calls
+ // freeAll() then they will probably be calling allocate() in the near future. Namely,
+ // we free all but one region, and make the remaining region a bump allocation region.
+
+ freeRegionsStartingAt(m_regionHead->m_next);
+
+ m_regionHead->m_next = 0;
+ m_freeListHead = 0;
+ startBumpingIn(m_regionHead);
+}
+
+template<typename T>
+void Allocator<T>::reset()
+{
+ freeRegionsStartingAt(m_regionHead);
+
+ m_regionHead = 0;
+ m_freeListHead = 0;
+ m_bumpRemaining = 0;
+}
+
+template<typename T>
+unsigned Allocator<T>::indexOf(const T* object)
+{
+ unsigned baseIndex = 0;
+ for (Region* region = m_regionHead; region; region = region->m_next) {
+ if (region->isInThisRegion(object))
+ return baseIndex + (object - region->data());
+ baseIndex += Region::numberOfThingsPerRegion();
+ }
+ CRASH();
+ return 0;
+}
+
+template<typename T>
+Allocator<T>* Allocator<T>::allocatorOf(const T* object)
+{
+ return Region::regionFor(object)->m_allocator;
+}
+
+template<typename T>
+ALWAYS_INLINE void* Allocator<T>::bumpAllocate()
+{
+ if (unsigned remaining = m_bumpRemaining) {
+ remaining--;
+ m_bumpRemaining = remaining;
+ return m_bumpEnd - (remaining + 1);
+ }
+ return 0;
+}
+
+template<typename T>
+void* Allocator<T>::freeListAllocate()
+{
+ void** result = m_freeListHead;
+ if (UNLIKELY(!result))
+ return allocateSlow();
+ m_freeListHead = bitwise_cast<void**>(*result);
+ return result;
+}
+
+template<typename T>
+void* Allocator<T>::allocateSlow()
+{
+ ASSERT(!m_freeListHead);
+ ASSERT(!m_bumpRemaining);
+
+ if (logCompilationChanges())
+ dataLog("Allocating another allocator region.\n");
+
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(Region::size(), Region::size(), OSAllocator::JSGCHeapPages);
+ if (!static_cast<bool>(allocation))
+ CRASH();
+ Region* region = static_cast<Region*>(allocation.base());
+ region->m_allocation = allocation;
+ region->m_allocator = this;
+ startBumpingIn(region);
+ region->m_next = m_regionHead;
+ m_regionHead = region;
+
+ void* result = bumpAllocate();
+ ASSERT(result);
+ return result;
+}
+
+template<typename T>
+void Allocator<T>::freeRegionsStartingAt(typename Allocator<T>::Region* region)
+{
+ while (region) {
+ Region* nextRegion = region->m_next;
+ region->m_allocation.deallocate();
+ region = nextRegion;
+ }
+}
+
+template<typename T>
+void Allocator<T>::startBumpingIn(typename Allocator<T>::Region* region)
+{
+ m_bumpEnd = region->data() + Region::numberOfThingsPerRegion();
+ m_bumpRemaining = Region::numberOfThingsPerRegion();
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGAllocator_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentPosition.h b/Source/JavaScriptCore/dfg/DFGArgumentPosition.h
index 05d1cb048..822b45474 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentPosition.h
+++ b/Source/JavaScriptCore/dfg/DFGArgumentPosition.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#include "DFGDoubleFormatState.h"
#include "DFGVariableAccessData.h"
+#include "DFGVariableAccessDataDump.h"
#include "SpeculatedType.h"
namespace JSC { namespace DFG {
@@ -37,6 +38,8 @@ public:
ArgumentPosition()
: m_prediction(SpecNone)
, m_doubleFormatState(EmptyDoubleFormatState)
+ , m_isProfitableToUnbox(false)
+ , m_shouldNeverUnbox(false)
{
}
@@ -45,33 +48,80 @@ public:
m_variables.append(variable);
}
- bool mergeArgumentAwareness()
+ bool mergeShouldNeverUnbox(bool shouldNeverUnbox)
+ {
+ return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | shouldNeverUnbox);
+ }
+
+ bool mergeArgumentPredictionAwareness()
{
bool changed = false;
for (unsigned i = 0; i < m_variables.size(); ++i) {
- changed |= mergeSpeculation(m_prediction, m_variables[i]->argumentAwarePrediction());
- changed |= mergeDoubleFormatState(m_doubleFormatState, m_variables[i]->doubleFormatState());
+ VariableAccessData* variable = m_variables[i]->find();
+ changed |= mergeSpeculation(m_prediction, variable->argumentAwarePrediction());
+ changed |= mergeDoubleFormatState(m_doubleFormatState, variable->doubleFormatState());
+ changed |= mergeShouldNeverUnbox(variable->shouldNeverUnbox());
}
if (!changed)
return false;
changed = false;
for (unsigned i = 0; i < m_variables.size(); ++i) {
- changed |= m_variables[i]->mergeArgumentAwarePrediction(m_prediction);
- changed |= m_variables[i]->mergeDoubleFormatState(m_doubleFormatState);
+ VariableAccessData* variable = m_variables[i]->find();
+ changed |= variable->mergeArgumentAwarePrediction(m_prediction);
+ changed |= variable->mergeDoubleFormatState(m_doubleFormatState);
+ changed |= variable->mergeShouldNeverUnbox(m_shouldNeverUnbox);
}
return changed;
}
+ bool mergeArgumentUnboxingAwareness()
+ {
+ bool changed = false;
+ for (unsigned i = 0; i < m_variables.size(); ++i) {
+ VariableAccessData* variable = m_variables[i]->find();
+ changed |= checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | variable->isProfitableToUnbox());
+ }
+ if (!changed)
+ return false;
+ changed = false;
+ for (unsigned i = 0; i < m_variables.size(); ++i) {
+ VariableAccessData* variable = m_variables[i]->find();
+ changed |= variable->mergeIsProfitableToUnbox(m_isProfitableToUnbox);
+ }
+ return changed;
+ }
+
+ bool shouldUnboxIfPossible() const { return m_isProfitableToUnbox && !m_shouldNeverUnbox; }
+
SpeculatedType prediction() const { return m_prediction; }
DoubleFormatState doubleFormatState() const { return m_doubleFormatState; }
bool shouldUseDoubleFormat() const
{
- return doubleFormatState() == UsingDoubleFormat;
+ return doubleFormatState() == UsingDoubleFormat && shouldUnboxIfPossible();
+ }
+
+ void dump(PrintStream& out, Graph* graph)
+ {
+ for (unsigned i = 0; i < m_variables.size(); ++i) {
+ VariableAccessData* variable = m_variables[i]->find();
+ int operand = variable->operand();
+
+ if (i)
+ out.print(" ");
+
+ if (operandIsArgument(operand))
+ out.print("arg", operandToArgument(operand), "(", VariableAccessDataDump(*graph, variable), ")");
+ else
+ out.print("r", operand, "(", VariableAccessDataDump(*graph, variable), ")");
+ }
+ out.print("\n");
}
private:
SpeculatedType m_prediction;
DoubleFormatState m_doubleFormatState;
+ bool m_isProfitableToUnbox;
+ bool m_shouldNeverUnbox;
Vector<VariableAccessData*, 2> m_variables;
};
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
index 35c553cf8..cbab4e8c8 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,8 @@
#include "DFGInsertionSet.h"
#include "DFGPhase.h"
#include "DFGValidate.h"
+#include "DFGVariableAccessDataDump.h"
+#include "Operations.h"
#include <wtf/HashSet.h>
#include <wtf/HashMap.h>
@@ -138,6 +140,26 @@ public:
m_argumentsAliasing.add(variableAccessData, ArgumentsAliasingData());
}
+ // Figure out which variables are live, using a conservative approximation of
+ // liveness.
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ Node* node = block->at(indexInBlock);
+ switch (node->op()) {
+ case GetLocal:
+ case Flush:
+ case PhantomLocal:
+ m_isLive.add(node->variableAccessData());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
// Figure out which variables alias the arguments and nothing else, and are
// used only for GetByVal and GetArrayLength accesses. At the same time,
// identify uses of CreateArguments that are not consistent with the arguments
@@ -147,11 +169,8 @@ public:
if (!block)
continue;
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = block->at(indexInBlock);
+ switch (node->op()) {
case CreateArguments: {
// Ignore this op. If we see a lone CreateArguments then we want to
// completely ignore it because:
@@ -171,16 +190,16 @@ public:
}
case SetLocal: {
- Node& source = m_graph[node.child1()];
- VariableAccessData* variableAccessData = node.variableAccessData();
+ Node* source = node->child1().node();
+ VariableAccessData* variableAccessData = node->variableAccessData();
int argumentsRegister =
- m_graph.uncheckedArgumentsRegisterFor(node.codeOrigin);
- if (source.op() != CreateArguments && source.op() != PhantomArguments) {
+ m_graph.uncheckedArgumentsRegisterFor(node->codeOrigin);
+ if (source->op() != CreateArguments && source->op() != PhantomArguments) {
// Make sure that the source of the SetLocal knows that if it's
// a variable that we think is aliased to the arguments, then it
// may escape at this point. In future, we could track transitive
// aliasing. But not yet.
- observeBadArgumentsUse(node.child1());
+ observeBadArgumentsUse(source);
// If this is an assignment to the arguments register, then
// pretend as if the arguments were created. We don't want to
@@ -193,14 +212,18 @@ public:
// init_lazy_reg since it treats CreateArguments as reading
// local variables. That could be fixed, but it's easier to
// work around this here.
- if (source.op() == JSConstant
- && !source.valueOfJSConstant(codeBlock()))
+ if (source->op() == JSConstant
+ && !source->valueOfJSConstant(codeBlock()))
+ break;
+
+ // If the variable is totally dead, then ignore it.
+ if (!m_isLive.contains(variableAccessData))
break;
if (argumentsRegister != InvalidVirtualRegister
&& (variableAccessData->local() == argumentsRegister
|| variableAccessData->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
- m_createsArguments.add(node.codeOrigin.inlineCallFrame);
+ m_createsArguments.add(node->codeOrigin.inlineCallFrame);
break;
}
@@ -212,19 +235,19 @@ public:
ArgumentsAliasingData& data =
m_argumentsAliasing.find(variableAccessData)->value;
data.mergeNonArgumentsAssignment();
- data.mergeCallContext(node.codeOrigin.inlineCallFrame);
+ data.mergeCallContext(node->codeOrigin.inlineCallFrame);
break;
}
if (argumentsRegister != InvalidVirtualRegister
&& (variableAccessData->local() == argumentsRegister
|| variableAccessData->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
- if (node.codeOrigin.inlineCallFrame == source.codeOrigin.inlineCallFrame)
+ if (node->codeOrigin.inlineCallFrame == source->codeOrigin.inlineCallFrame)
break;
- m_createsArguments.add(source.codeOrigin.inlineCallFrame);
+ m_createsArguments.add(source->codeOrigin.inlineCallFrame);
break;
}
if (variableAccessData->isCaptured()) {
- m_createsArguments.add(source.codeOrigin.inlineCallFrame);
+ m_createsArguments.add(source->codeOrigin.inlineCallFrame);
break;
}
ArgumentsAliasingData& data =
@@ -232,29 +255,29 @@ public:
data.mergeArgumentsAssignment();
// This ensures that the variable's uses are in the same context as
// the arguments it is aliasing.
- data.mergeCallContext(node.codeOrigin.inlineCallFrame);
- data.mergeCallContext(source.codeOrigin.inlineCallFrame);
+ data.mergeCallContext(node->codeOrigin.inlineCallFrame);
+ data.mergeCallContext(source->codeOrigin.inlineCallFrame);
break;
}
case GetLocal:
- case Phi: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ case Phi: /* FIXME: https://bugs.webkit.org/show_bug.cgi?id=108555 */ {
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->isCaptured())
break;
ArgumentsAliasingData& data =
m_argumentsAliasing.find(variableAccessData)->value;
- data.mergeCallContext(node.codeOrigin.inlineCallFrame);
+ data.mergeCallContext(node->codeOrigin.inlineCallFrame);
break;
}
case Flush: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->isCaptured())
break;
ArgumentsAliasingData& data =
m_argumentsAliasing.find(variableAccessData)->value;
- data.mergeCallContext(node.codeOrigin.inlineCallFrame);
+ data.mergeCallContext(node->codeOrigin.inlineCallFrame);
// If a variable is used in a flush then by definition it escapes.
data.escapes = true;
@@ -262,18 +285,18 @@ public:
}
case SetArgument: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->isCaptured())
break;
ArgumentsAliasingData& data =
m_argumentsAliasing.find(variableAccessData)->value;
data.mergeNonArgumentsAssignment();
- data.mergeCallContext(node.codeOrigin.inlineCallFrame);
+ data.mergeCallContext(node->codeOrigin.inlineCallFrame);
break;
}
case GetByVal: {
- if (node.arrayMode().type() != Array::Arguments) {
+ if (node->arrayMode().type() != Array::Arguments) {
observeBadArgumentsUses(node);
break;
}
@@ -281,18 +304,18 @@ public:
// That's so awful and pretty much impossible since it would
// imply that the arguments were predicted integer, but it's
// good to be defensive and thorough.
- observeBadArgumentsUse(node.child2());
- observeProperArgumentsUse(node, node.child1());
+ observeBadArgumentsUse(node->child2().node());
+ observeProperArgumentsUse(node, node->child1());
break;
}
case GetArrayLength: {
- if (node.arrayMode().type() != Array::Arguments) {
+ if (node->arrayMode().type() != Array::Arguments) {
observeBadArgumentsUses(node);
break;
}
- observeProperArgumentsUse(node, node.child1());
+ observeProperArgumentsUse(node, node->child1());
break;
}
@@ -333,16 +356,13 @@ public:
if (!block)
continue;
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate())
- continue;
- if (node.op() != SetLocal)
+ Node* node = block->at(indexInBlock);
+ if (node->op() != SetLocal)
continue;
- Node& source = m_graph[node.child1()];
- if (source.op() != CreateArguments)
+ Node* source = node->child1().node();
+ if (source->op() != CreateArguments)
continue;
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->isCaptured()) {
// The captured case would have already been taken care of in the
// previous pass.
@@ -354,7 +374,7 @@ public:
if (data.isValid())
continue;
- m_createsArguments.add(source.codeOrigin.inlineCallFrame);
+ m_createsArguments.add(source->codeOrigin.inlineCallFrame);
}
}
@@ -364,7 +384,7 @@ public:
VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
if (!variableAccessData->isRoot())
continue;
- dataLogF(" r%d(%s): ", variableAccessData->local(), m_graph.nameOfVariableAccessData(variableAccessData));
+ dataLog(" r", variableAccessData->local(), "(", VariableAccessDataDump(m_graph, variableAccessData), "): ");
if (variableAccessData->isCaptured())
dataLogF("Captured");
else {
@@ -405,31 +425,27 @@ public:
}
#endif
- InsertionSet<NodeIndex> insertionSet;
+ InsertionSet insertionSet(m_graph);
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
- for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate())
- continue;
-
- switch (node.op()) {
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); indexInBlock++) {
+ Node* node = block->at(indexInBlock);
+ switch (node->op()) {
case SetLocal: {
- Node& source = m_graph[node.child1()];
- if (source.op() != CreateArguments)
+ Node* source = node->child1().node();
+ if (source->op() != CreateArguments)
break;
- if (m_createsArguments.contains(source.codeOrigin.inlineCallFrame))
+ if (m_createsArguments.contains(source->codeOrigin.inlineCallFrame))
break;
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
- if (m_graph.argumentsRegisterFor(node.codeOrigin) == variableAccessData->local()
- || unmodifiedArgumentsRegister(m_graph.argumentsRegisterFor(node.codeOrigin)) == variableAccessData->local())
+ if (m_graph.argumentsRegisterFor(node->codeOrigin) == variableAccessData->local()
+ || unmodifiedArgumentsRegister(m_graph.argumentsRegisterFor(node->codeOrigin)) == variableAccessData->local())
break;
ASSERT(!variableAccessData->isCaptured());
@@ -442,7 +458,46 @@ public:
// we replace all uses of this variable with GetMyArgumentsLength and
// GetMyArgumentByVal.
ASSERT(m_argumentsAliasing.find(variableAccessData)->value.isValid());
- changed |= variableAccessData->mergeIsArgumentsAlias(true);
+ if (variableAccessData->mergeIsArgumentsAlias(true)) {
+ changed = true;
+
+ // Make sure that the variable knows, that it may now hold non-cell values.
+ variableAccessData->predict(SpecEmpty);
+ }
+
+ // Make sure that the SetLocal doesn't check that the input is a Cell.
+ if (node->child1().useKind() != UntypedUse) {
+ node->child1().setUseKind(UntypedUse);
+ changed = true;
+ }
+ break;
+ }
+
+ case PhantomLocal: {
+ VariableAccessData* variableAccessData = node->variableAccessData();
+
+ if (variableAccessData->isCaptured()
+ || !m_argumentsAliasing.find(variableAccessData)->value.isValid()
+ || m_createsArguments.contains(node->codeOrigin.inlineCallFrame))
+ break;
+
+ // Turn PhantomLocals into just GetLocals. This will preserve the threading
+ // of the local through to this point, but will allow it to die, causing
+ // only OSR to know about it.
+
+ node->setOpAndDefaultFlags(GetLocal);
+ break;
+ }
+
+ case Flush: {
+ VariableAccessData* variableAccessData = node->variableAccessData();
+
+ if (variableAccessData->isCaptured()
+ || !m_argumentsAliasing.find(variableAccessData)->value.isValid()
+ || m_createsArguments.contains(node->codeOrigin.inlineCallFrame))
+ break;
+
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -467,16 +522,15 @@ public:
case ForwardStructureTransitionWatchpoint:
case CheckArray: {
// We can just get rid of this node, if it references a phantom argument.
- if (!isOKToOptimize(m_graph[node.child1()]))
+ if (!isOKToOptimize(node->child1().node()))
break;
- m_graph.deref(node.child1());
- node.setOpAndDefaultFlags(Phantom);
- node.children.setChild1(Edge());
+ node->convertToPhantom();
+ node->children.setChild1(Edge());
break;
}
case GetByVal: {
- if (node.arrayMode().type() != Array::Arguments)
+ if (node->arrayMode().type() != Array::Arguments)
break;
// This can be simplified to GetMyArgumentByVal if we know that
@@ -486,28 +540,26 @@ public:
// 2) Its first child is CreateArguments and its InlineCallFrame*
// is not marked as creating arguments.
- if (!isOKToOptimize(m_graph[node.child1()]))
+ if (!isOKToOptimize(node->child1().node()))
break;
- m_graph.deref(node.child1());
- node.children.child1() = node.children.child2();
- node.children.child2() = Edge();
- node.setOpAndDefaultFlags(GetMyArgumentByVal);
+ node->children.child1() = node->children.child2();
+ node->children.child2() = Edge();
+ node->setOpAndDefaultFlags(GetMyArgumentByVal);
changed = true;
--indexInBlock; // Force reconsideration of this op now that it's a GetMyArgumentByVal.
break;
}
case GetArrayLength: {
- if (node.arrayMode().type() != Array::Arguments)
+ if (node->arrayMode().type() != Array::Arguments)
break;
- if (!isOKToOptimize(m_graph[node.child1()]))
+ if (!isOKToOptimize(node->child1().node()))
break;
- m_graph.deref(node.child1());
- node.children.child1() = Edge();
- node.setOpAndDefaultFlags(GetMyArgumentsLength);
+ node->children.child1() = Edge();
+ node->setOpAndDefaultFlags(GetMyArgumentsLength);
changed = true;
--indexInBlock; // Force reconsideration of this op noew that it's a GetMyArgumentsLength.
break;
@@ -515,54 +567,51 @@ public:
case GetMyArgumentsLength:
case GetMyArgumentsLengthSafe: {
- if (m_createsArguments.contains(node.codeOrigin.inlineCallFrame)) {
- ASSERT(node.op() == GetMyArgumentsLengthSafe);
+ if (m_createsArguments.contains(node->codeOrigin.inlineCallFrame)) {
+ ASSERT(node->op() == GetMyArgumentsLengthSafe);
break;
}
- if (node.op() == GetMyArgumentsLengthSafe) {
- node.setOp(GetMyArgumentsLength);
+ if (node->op() == GetMyArgumentsLengthSafe) {
+ node->setOp(GetMyArgumentsLength);
changed = true;
}
- CodeOrigin codeOrigin = node.codeOrigin;
+ CodeOrigin codeOrigin = node->codeOrigin;
if (!codeOrigin.inlineCallFrame)
break;
// We know exactly what this will return. But only after we have checked
// that nobody has escaped our arguments.
- Node check(CheckArgumentsNotCreated, codeOrigin);
- check.ref();
- NodeIndex checkIndex = m_graph.size();
- m_graph.append(check);
- insertionSet.append(indexInBlock, checkIndex);
+ insertionSet.insertNode(
+ indexInBlock, SpecNone, CheckArgumentsNotCreated, codeOrigin);
m_graph.convertToConstant(
- nodeIndex, jsNumber(codeOrigin.inlineCallFrame->arguments.size() - 1));
+ node, jsNumber(codeOrigin.inlineCallFrame->arguments.size() - 1));
changed = true;
break;
}
case GetMyArgumentByVal:
case GetMyArgumentByValSafe: {
- if (m_createsArguments.contains(node.codeOrigin.inlineCallFrame)) {
- ASSERT(node.op() == GetMyArgumentByValSafe);
+ if (m_createsArguments.contains(node->codeOrigin.inlineCallFrame)) {
+ ASSERT(node->op() == GetMyArgumentByValSafe);
break;
}
- if (node.op() == GetMyArgumentByValSafe) {
- node.setOp(GetMyArgumentByVal);
+ if (node->op() == GetMyArgumentByValSafe) {
+ node->setOp(GetMyArgumentByVal);
changed = true;
}
- if (!node.codeOrigin.inlineCallFrame)
+ if (!node->codeOrigin.inlineCallFrame)
break;
- if (!m_graph[node.child1()].hasConstant())
+ if (!node->child1()->hasConstant())
break;
- JSValue value = m_graph[node.child1()].valueOfJSConstant(codeBlock());
+ JSValue value = node->child1()->valueOfJSConstant(codeBlock());
if (!value.isInt32())
break;
int32_t index = value.asInt32();
if (index < 0
|| static_cast<size_t>(index + 1) >=
- node.codeOrigin.inlineCallFrame->arguments.size())
+ node->codeOrigin.inlineCallFrame->arguments.size())
break;
// We know which argument this is accessing. But only after we have checked
@@ -574,37 +623,32 @@ public:
// has run - therefore it makes little sense to link the GetLocal operation
// into the VariableAccessData and Phi graphs.
- Node check(CheckArgumentsNotCreated, node.codeOrigin);
- check.ref();
-
- Node phantom(Phantom, node.codeOrigin);
- phantom.ref();
- phantom.children = node.children;
+ CodeOrigin codeOrigin = node->codeOrigin;
+ AdjacencyList children = node->children;
- node.convertToGetLocalUnlinked(
+ node->convertToGetLocalUnlinked(
static_cast<VirtualRegister>(
- node.codeOrigin.inlineCallFrame->stackOffset +
- m_graph.baselineCodeBlockFor(node.codeOrigin)->argumentIndexAfterCapture(index)));
+ node->codeOrigin.inlineCallFrame->stackOffset +
+ m_graph.baselineCodeBlockFor(node->codeOrigin)->argumentIndexAfterCapture(index)));
- NodeIndex checkNodeIndex = m_graph.size();
- m_graph.append(check);
- insertionSet.append(indexInBlock, checkNodeIndex);
- NodeIndex phantomNodeIndex = m_graph.size();
- m_graph.append(phantom);
- insertionSet.append(indexInBlock, phantomNodeIndex);
+ insertionSet.insertNode(
+ indexInBlock, SpecNone, CheckArgumentsNotCreated,
+ codeOrigin);
+ insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, codeOrigin,
+ children);
changed = true;
break;
}
case TearOffArguments: {
- if (m_createsArguments.contains(node.codeOrigin.inlineCallFrame))
+ if (m_createsArguments.contains(node->codeOrigin.inlineCallFrame))
continue;
- node.setOpAndDefaultFlags(Nop);
+ node->setOpAndDefaultFlags(Nop);
m_graph.clearAndDerefChild1(node);
m_graph.clearAndDerefChild2(node);
- node.setRefCount(0);
break;
}
@@ -612,7 +656,7 @@ public:
break;
}
}
- insertionSet.execute(*block);
+ insertionSet.execute(block);
}
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
@@ -620,35 +664,29 @@ public:
if (!block)
continue;
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node* nodePtr = &m_graph[nodeIndex];
- if (nodePtr->op() != CreateArguments)
+ Node* node = block->at(indexInBlock);
+ if (node->op() != CreateArguments)
continue;
// If this is a CreateArguments for an InlineCallFrame* that does
// not create arguments, then replace it with a PhantomArguments.
// PhantomArguments is a non-executing node that just indicates
// that the node should be reified as an arguments object on OSR
// exit.
- if (m_createsArguments.contains(nodePtr->codeOrigin.inlineCallFrame))
+ if (m_createsArguments.contains(node->codeOrigin.inlineCallFrame))
continue;
- if (nodePtr->shouldGenerate()) {
- Node phantom(Phantom, nodePtr->codeOrigin);
- phantom.children = nodePtr->children;
- phantom.ref();
- NodeIndex phantomNodeIndex = m_graph.size();
- m_graph.append(phantom);
- insertionSet.append(indexInBlock, phantomNodeIndex);
- nodePtr = &m_graph[nodeIndex];
- }
- nodePtr->setOpAndDefaultFlags(PhantomArguments);
- nodePtr->children.reset();
+ insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, node->codeOrigin, node->children);
+ node->setOpAndDefaultFlags(PhantomArguments);
+ node->children.reset();
changed = true;
}
- insertionSet.execute(*block);
+ insertionSet.execute(block);
}
- if (changed)
- m_graph.collectGarbage();
+ if (changed) {
+ m_graph.dethread();
+ m_graph.m_form = LoadStore;
+ }
return changed;
}
@@ -660,29 +698,29 @@ private:
HashMap<VariableAccessData*, ArgumentsAliasingData,
DefaultHash<VariableAccessData*>::Hash,
NullableHashTraits<VariableAccessData*> > m_argumentsAliasing;
+ HashSet<VariableAccessData*> m_isLive;
- void observeBadArgumentsUse(Edge edge)
+ void observeBadArgumentsUse(Node* node)
{
- if (!edge)
+ if (!node)
return;
- Node& child = m_graph[edge];
- switch (child.op()) {
+ switch (node->op()) {
case CreateArguments: {
- m_createsArguments.add(child.codeOrigin.inlineCallFrame);
+ m_createsArguments.add(node->codeOrigin.inlineCallFrame);
break;
}
case GetLocal: {
- int argumentsRegister = m_graph.uncheckedArgumentsRegisterFor(child.codeOrigin);
+ int argumentsRegister = m_graph.uncheckedArgumentsRegisterFor(node->codeOrigin);
if (argumentsRegister != InvalidVirtualRegister
- && (child.local() == argumentsRegister
- || child.local() == unmodifiedArgumentsRegister(argumentsRegister))) {
- m_createsArguments.add(child.codeOrigin.inlineCallFrame);
+ && (node->local() == argumentsRegister
+ || node->local() == unmodifiedArgumentsRegister(argumentsRegister))) {
+ m_createsArguments.add(node->codeOrigin.inlineCallFrame);
break;
}
- VariableAccessData* variableAccessData = child.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->isCaptured())
break;
@@ -696,16 +734,15 @@ private:
}
}
- void observeBadArgumentsUses(Node& node)
+ void observeBadArgumentsUses(Node* node)
{
for (unsigned i = m_graph.numChildren(node); i--;)
- observeBadArgumentsUse(m_graph.child(node, i));
+ observeBadArgumentsUse(m_graph.child(node, i).node());
}
- void observeProperArgumentsUse(Node& node, Edge edge)
+ void observeProperArgumentsUse(Node* node, Edge edge)
{
- Node& child = m_graph[edge];
- if (child.op() != GetLocal) {
+ if (edge->op() != GetLocal) {
// When can this happen? At least two cases that I can think
// of:
//
@@ -717,18 +754,18 @@ private:
//
// 2) If we're accessing arguments we got from the heap!
- if (child.op() == CreateArguments
- && node.codeOrigin.inlineCallFrame
- != child.codeOrigin.inlineCallFrame)
- m_createsArguments.add(child.codeOrigin.inlineCallFrame);
+ if (edge->op() == CreateArguments
+ && node->codeOrigin.inlineCallFrame
+ != edge->codeOrigin.inlineCallFrame)
+ m_createsArguments.add(edge->codeOrigin.inlineCallFrame);
return;
}
- VariableAccessData* variableAccessData = child.variableAccessData();
- if (child.local() == m_graph.uncheckedArgumentsRegisterFor(child.codeOrigin)
- && node.codeOrigin.inlineCallFrame != child.codeOrigin.inlineCallFrame) {
- m_createsArguments.add(child.codeOrigin.inlineCallFrame);
+ VariableAccessData* variableAccessData = edge->variableAccessData();
+ if (edge->local() == m_graph.uncheckedArgumentsRegisterFor(edge->codeOrigin)
+ && node->codeOrigin.inlineCallFrame != edge->codeOrigin.inlineCallFrame) {
+ m_createsArguments.add(edge->codeOrigin.inlineCallFrame);
return;
}
@@ -736,18 +773,18 @@ private:
return;
ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value;
- data.mergeCallContext(node.codeOrigin.inlineCallFrame);
+ data.mergeCallContext(node->codeOrigin.inlineCallFrame);
}
- bool isOKToOptimize(Node& source)
+ bool isOKToOptimize(Node* source)
{
- if (m_createsArguments.contains(source.codeOrigin.inlineCallFrame))
+ if (m_createsArguments.contains(source->codeOrigin.inlineCallFrame))
return false;
- switch (source.op()) {
+ switch (source->op()) {
case GetLocal: {
- VariableAccessData* variableAccessData = source.variableAccessData();
- int argumentsRegister = m_graph.uncheckedArgumentsRegisterFor(source.codeOrigin);
+ VariableAccessData* variableAccessData = source->variableAccessData();
+ int argumentsRegister = m_graph.uncheckedArgumentsRegisterFor(source->codeOrigin);
if (argumentsRegister == InvalidVirtualRegister)
break;
if (argumentsRegister == variableAccessData->local())
@@ -775,38 +812,35 @@ private:
return false;
}
- void removeArgumentsReferencingPhantomChild(Node& node, unsigned edgeIndex)
+ void removeArgumentsReferencingPhantomChild(Node* node, unsigned edgeIndex)
{
- Edge edge = node.children.child(edgeIndex);
+ Edge edge = node->children.child(edgeIndex);
if (!edge)
return;
- Node& child = m_graph[edge];
- switch (child.op()) {
+ switch (edge->op()) {
case Phi: // Arises if we had CSE on a GetLocal of the arguments register.
case GetLocal: // Arises if we had CSE on an arguments access to a variable aliased to the arguments.
case SetLocal: { // Arises if we had CSE on a GetLocal of the arguments register.
- VariableAccessData* variableAccessData = child.variableAccessData();
+ VariableAccessData* variableAccessData = edge->variableAccessData();
bool isDeadArgumentsRegister =
variableAccessData->local() ==
- m_graph.uncheckedArgumentsRegisterFor(child.codeOrigin)
- && !m_createsArguments.contains(child.codeOrigin.inlineCallFrame);
+ m_graph.uncheckedArgumentsRegisterFor(edge->codeOrigin)
+ && !m_createsArguments.contains(edge->codeOrigin.inlineCallFrame);
bool isAliasedArgumentsRegister =
!variableAccessData->isCaptured()
&& m_argumentsAliasing.find(variableAccessData)->value.isValid()
- && !m_createsArguments.contains(child.codeOrigin.inlineCallFrame);
+ && !m_createsArguments.contains(edge->codeOrigin.inlineCallFrame);
if (!isDeadArgumentsRegister && !isAliasedArgumentsRegister)
break;
- m_graph.deref(edge);
- node.children.removeEdgeFromBag(edgeIndex);
+ node->children.removeEdge(edgeIndex);
break;
}
case CreateArguments: { // Arises if we CSE two GetLocals to the arguments register and then CSE the second use of the GetLocal to the first.
- if (m_createsArguments.contains(child.codeOrigin.inlineCallFrame))
+ if (m_createsArguments.contains(edge->codeOrigin.inlineCallFrame))
break;
- m_graph.deref(edge);
- node.children.removeEdgeFromBag(edgeIndex);
+ node->children.removeEdge(edgeIndex);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
index 3bfb6a43e..ede2ffc2b 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
@@ -30,6 +30,7 @@
#include "DFGAbstractValue.h"
#include "DFGGraph.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
@@ -111,9 +112,11 @@ ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, b
else
type = Array::Undecided;
- if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage)))
+ if (hasSeenArray(observed) && hasSeenNonArray(observed))
+ arrayClass = Array::PossiblyArray;
+ else if (hasSeenArray(observed))
arrayClass = Array::Array;
- else if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage)))
+ else if (hasSeenNonArray(observed))
arrayClass = Array::NonArray;
else
arrayClass = Array::PossiblyArray;
@@ -122,7 +125,7 @@ ArrayMode ArrayMode::fromObserved(ArrayProfile* profile, Array::Action action, b
}
}
-ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, SpeculatedType value) const
+ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, SpeculatedType value, NodeFlags flags) const
{
if (!base || !index) {
// It can be that we had a legitimate arrayMode but no incoming predictions. That'll
@@ -132,9 +135,19 @@ ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, Speculate
return ArrayMode(Array::ForceExit);
}
- if (!isInt32Speculation(index) || !isCellSpeculation(base))
+ if (!isInt32Speculation(index))
return ArrayMode(Array::Generic);
+ // Note: our profiling currently doesn't give us good information in case we have
+ // an unlikely control flow path that sets the base to a non-cell value. Value
+ // profiling and prediction propagation will probably tell us that the value is
+ // either a cell or not, but that doesn't tell us which is more likely: that this
+ // is an array access on a cell (what we want and can optimize) or that the user is
+ // doing a crazy by-val access on a primitive (we can't easily optimize this and
+ // don't want to). So, for now, we assume that if the base is not a cell according
+ // to value profiling, but the array profile tells us something else, then we
+ // should just trust the array profile.
+
switch (type()) {
case Array::Unprofiled:
return ArrayMode(Array::ForceExit);
@@ -156,11 +169,20 @@ ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, Speculate
return withTypeAndConversion(Array::Contiguous, Array::Convert);
case Array::Double:
+ if (flags & NodeUsedAsInt)
+ return withTypeAndConversion(Array::Contiguous, Array::RageConvert);
if (!value || isNumberSpeculation(value))
return *this;
return withTypeAndConversion(Array::Contiguous, Array::Convert);
+ case Array::Contiguous:
+ if (doesConversion() && (flags & NodeUsedAsInt))
+ return withConversion(Array::RageConvert);
+ return *this;
+
case Array::SelectUsingPredictions:
+ base &= ~SpecOther;
+
if (isStringSpeculation(base))
return ArrayMode(Array::String);
@@ -223,19 +245,19 @@ Structure* ArrayMode::originalArrayStructure(Graph& graph, const CodeOrigin& cod
}
}
-Structure* ArrayMode::originalArrayStructure(Graph& graph, Node& node) const
+Structure* ArrayMode::originalArrayStructure(Graph& graph, Node* node) const
{
- return originalArrayStructure(graph, node.codeOrigin);
+ return originalArrayStructure(graph, node->codeOrigin);
}
-bool ArrayMode::alreadyChecked(Graph& graph, Node& node, AbstractValue& value, IndexingType shape) const
+bool ArrayMode::alreadyChecked(Graph& graph, Node* node, AbstractValue& value, IndexingType shape) const
{
switch (arrayClass()) {
case Array::OriginalArray:
return value.m_currentKnownStructure.hasSingleton()
&& (value.m_currentKnownStructure.singleton()->indexingType() & IndexingShapeMask) == shape
&& (value.m_currentKnownStructure.singleton()->indexingType() & IsArray)
- && graph.globalObjectFor(node.codeOrigin)->isOriginalArrayStructure(value.m_currentKnownStructure.singleton());
+ && graph.globalObjectFor(node->codeOrigin)->isOriginalArrayStructure(value.m_currentKnownStructure.singleton());
case Array::Array:
if (arrayModesAlreadyChecked(value.m_arrayModes, asArrayModes(shape | IsArray)))
@@ -252,7 +274,7 @@ bool ArrayMode::alreadyChecked(Graph& graph, Node& node, AbstractValue& value, I
}
}
-bool ArrayMode::alreadyChecked(Graph& graph, Node& node, AbstractValue& value) const
+bool ArrayMode::alreadyChecked(Graph& graph, Node* node, AbstractValue& value) const
{
switch (type()) {
case Array::Generic:
@@ -429,19 +451,43 @@ const char* arrayConversionToString(Array::Conversion conversion)
return "AsIs";
case Array::Convert:
return "Convert";
+ case Array::RageConvert:
+ return "RageConvert";
default:
return "Unknown!";
}
}
-const char* ArrayMode::toString() const
+void ArrayMode::dump(PrintStream& out) const
{
- static char buffer[256];
- snprintf(buffer, sizeof(buffer), "%s%s%s%s", arrayTypeToString(type()), arrayClassToString(arrayClass()), arraySpeculationToString(speculation()), arrayConversionToString(conversion()));
- return buffer;
+ out.print(type(), arrayClass(), speculation(), conversion());
}
} } // namespace JSC::DFG
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::DFG::Array::Type type)
+{
+ out.print(JSC::DFG::arrayTypeToString(type));
+}
+
+void printInternal(PrintStream& out, JSC::DFG::Array::Class arrayClass)
+{
+ out.print(JSC::DFG::arrayClassToString(arrayClass));
+}
+
+void printInternal(PrintStream& out, JSC::DFG::Array::Speculation speculation)
+{
+ out.print(JSC::DFG::arraySpeculationToString(speculation));
+}
+
+void printInternal(PrintStream& out, JSC::DFG::Array::Conversion conversion)
+{
+ out.print(JSC::DFG::arrayConversionToString(conversion));
+}
+
+} // namespace WTF
+
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.h b/Source/JavaScriptCore/dfg/DFGArrayMode.h
index 0799868d6..c6d966d60 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.h
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.h
@@ -31,6 +31,7 @@
#if ENABLE(DFG_JIT)
#include "ArrayProfile.h"
+#include "DFGNodeFlags.h"
#include "SpeculatedType.h"
namespace JSC {
@@ -93,7 +94,8 @@ enum Speculation {
};
enum Conversion {
AsIs,
- Convert
+ Convert,
+ RageConvert
};
} // namespace Array
@@ -183,16 +185,21 @@ public:
return ArrayMode(type, arrayClass(), speculation(), conversion());
}
+ ArrayMode withConversion(Array::Conversion conversion) const
+ {
+ return ArrayMode(type(), arrayClass(), speculation(), conversion);
+ }
+
ArrayMode withTypeAndConversion(Array::Type type, Array::Conversion conversion) const
{
return ArrayMode(type, arrayClass(), speculation(), conversion);
}
- ArrayMode refine(SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone) const;
+ ArrayMode refine(SpeculatedType base, SpeculatedType index, SpeculatedType value = SpecNone, NodeFlags = 0) const;
- bool alreadyChecked(Graph&, Node&, AbstractValue&) const;
+ bool alreadyChecked(Graph&, Node*, AbstractValue&) const;
- const char* toString() const;
+ void dump(PrintStream&) const;
bool usesButterfly() const
{
@@ -336,12 +343,17 @@ public:
// Returns 0 if this is not OriginalArray.
Structure* originalArrayStructure(Graph&, const CodeOrigin&) const;
- Structure* originalArrayStructure(Graph&, Node&) const;
+ Structure* originalArrayStructure(Graph&, Node*) const;
bool benefitsFromStructureCheck() const
{
switch (type()) {
case Array::SelectUsingPredictions:
+ // It might benefit from structure checks! If it ends up not benefiting, we can just
+ // remove it. The FixupPhase does this: if it finds a CheckStructure just before an
+ // array op and it had turned that array op into either generic or conversion mode,
+ // it will remove the CheckStructure.
+ return true;
case Array::Unprofiled:
case Array::ForceExit:
case Array::Generic:
@@ -353,7 +365,7 @@ public:
bool doesConversion() const
{
- return conversion() == Array::Convert;
+ return conversion() != Array::AsIs;
}
ArrayModes arrayModesThatPassFiltering() const
@@ -376,6 +388,11 @@ public:
}
}
+ bool getIndexedPropertyStorageMayTriggerGC() const
+ {
+ return type() == Array::String;
+ }
+
bool operator==(const ArrayMode& other) const
{
return type() == other.type()
@@ -410,7 +427,7 @@ private:
}
}
- bool alreadyChecked(Graph&, Node&, AbstractValue&, IndexingType shape) const;
+ bool alreadyChecked(Graph&, Node*, AbstractValue&, IndexingType shape) const;
union {
struct {
@@ -435,6 +452,16 @@ static inline bool lengthNeedsStorage(const ArrayMode& arrayMode)
} } // namespace JSC::DFG
+namespace WTF {
+
+class PrintStream;
+void printInternal(PrintStream&, JSC::DFG::Array::Type);
+void printInternal(PrintStream&, JSC::DFG::Array::Class);
+void printInternal(PrintStream&, JSC::DFG::Array::Speculation);
+void printInternal(PrintStream&, JSC::DFG::Array::Conversion);
+
+} // namespace WTF
+
#endif // ENABLE(DFG_JIT)
#endif // DFGArrayMode_h
diff --git a/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h b/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h
new file mode 100644
index 000000000..7647ed445
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGArrayifySlowPathGenerator_h
+#define DFGArrayifySlowPathGenerator_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGArrayMode.h"
+#include "DFGCommon.h"
+#include "DFGOSRExitJumpPlaceholder.h"
+#include "DFGOperations.h"
+#include "DFGSlowPathGenerator.h"
+#include "DFGSpeculativeJIT.h"
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+class ArrayifySlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> {
+public:
+ ArrayifySlowPathGenerator(
+ const MacroAssembler::JumpList& from, SpeculativeJIT* jit, Node* node, GPRReg baseGPR,
+ GPRReg propertyGPR, GPRReg tempGPR, GPRReg structureGPR)
+ : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit)
+ , m_op(node->op())
+ , m_arrayMode(node->arrayMode())
+ , m_structure(node->op() == ArrayifyToStructure ? node->structure() : 0)
+ , m_baseGPR(baseGPR)
+ , m_propertyGPR(propertyGPR)
+ , m_tempGPR(tempGPR)
+ , m_structureGPR(structureGPR)
+ {
+ ASSERT(m_op == Arrayify || m_op == ArrayifyToStructure);
+
+ jit->silentSpillAllRegistersImpl(false, m_plans, InvalidGPRReg);
+
+ if (m_propertyGPR != InvalidGPRReg) {
+ switch (m_arrayMode.type()) {
+ case Array::Int32:
+ case Array::Double:
+ case Array::Contiguous:
+ m_badPropertyJump = jit->backwardSpeculationCheck(Uncountable, JSValueRegs(), 0);
+ break;
+ default:
+ break;
+ }
+ }
+ m_badIndexingTypeJump = jit->backwardSpeculationCheck(BadIndexingType, JSValueSource::unboxedCell(m_baseGPR), 0);
+ }
+
+protected:
+ void generateInternal(SpeculativeJIT* jit)
+ {
+ linkFrom(jit);
+
+ ASSERT(m_op == Arrayify || m_op == ArrayifyToStructure);
+
+ if (m_propertyGPR != InvalidGPRReg) {
+ switch (m_arrayMode.type()) {
+ case Array::Int32:
+ case Array::Double:
+ case Array::Contiguous:
+ m_badPropertyJump.fill(jit, jit->m_jit.branch32(
+ MacroAssembler::AboveOrEqual, m_propertyGPR,
+ MacroAssembler::TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (unsigned i = 0; i < m_plans.size(); ++i)
+ jit->silentSpill(m_plans[i]);
+ switch (m_arrayMode.type()) {
+ case Array::Int32:
+ jit->callOperation(operationEnsureInt32, m_tempGPR, m_baseGPR);
+ break;
+ case Array::Double:
+ jit->callOperation(operationEnsureDouble, m_tempGPR, m_baseGPR);
+ break;
+ case Array::Contiguous:
+ if (m_arrayMode.conversion() == Array::RageConvert)
+ jit->callOperation(operationRageEnsureContiguous, m_tempGPR, m_baseGPR);
+ else
+ jit->callOperation(operationEnsureContiguous, m_tempGPR, m_baseGPR);
+ break;
+ case Array::ArrayStorage:
+ case Array::SlowPutArrayStorage:
+ jit->callOperation(operationEnsureArrayStorage, m_tempGPR, m_baseGPR);
+ break;
+ default:
+ CRASH();
+ break;
+ }
+ for (unsigned i = m_plans.size(); i--;)
+ jit->silentFill(m_plans[i], GPRInfo::regT0);
+
+ if (m_op == ArrayifyToStructure) {
+ ASSERT(m_structure);
+ m_badIndexingTypeJump.fill(
+ jit, jit->m_jit.branchWeakPtr(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(m_baseGPR, JSCell::structureOffset()),
+ m_structure));
+ } else {
+ // Alas, we need to reload the structure because silent spilling does not save
+ // temporaries. Nor would it be useful for it to do so. Either way we're talking
+ // about a load.
+ jit->m_jit.loadPtr(
+ MacroAssembler::Address(m_baseGPR, JSCell::structureOffset()), m_structureGPR);
+
+ // Finally, check that we have the kind of array storage that we wanted to get.
+ // Note that this is a backwards speculation check, which will result in the
+ // bytecode operation corresponding to this arrayification being reexecuted.
+ // That's fine, since arrayification is not user-visible.
+ jit->m_jit.load8(
+ MacroAssembler::Address(m_structureGPR, Structure::indexingTypeOffset()), m_structureGPR);
+ m_badIndexingTypeJump.fill(
+ jit, jit->jumpSlowForUnwantedArrayMode(m_structureGPR, m_arrayMode));
+ }
+
+ jumpTo(jit);
+ }
+
+private:
+ NodeType m_op;
+ ArrayMode m_arrayMode;
+ Structure* m_structure;
+ GPRReg m_baseGPR;
+ GPRReg m_propertyGPR;
+ GPRReg m_tempGPR;
+ GPRReg m_structureGPR;
+ OSRExitJumpPlaceholder m_badPropertyJump;
+ OSRExitJumpPlaceholder m_badIndexingTypeJump;
+ Vector<SilentRegisterSavePlan, 2> m_plans;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGArrayifySlowPathGenerator_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
index c060179a8..48dd216f1 100644
--- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
+++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,17 +34,17 @@
#include "DFGFPRInfo.h"
#include "DFGGPRInfo.h"
#include "DFGNode.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "MacroAssembler.h"
namespace JSC { namespace DFG {
-typedef void (*V_DFGDebugOperation_EP)(ExecState*, void*);
+typedef void (*V_DFGDebugOperation_EPP)(ExecState*, void*, void*);
class AssemblyHelpers : public MacroAssembler {
public:
- AssemblyHelpers(JSGlobalData* globalData, CodeBlock* codeBlock)
- : m_globalData(globalData)
+ AssemblyHelpers(VM* vm, CodeBlock* codeBlock)
+ : m_vm(vm)
, m_codeBlock(codeBlock)
, m_baselineCodeBlock(codeBlock ? codeBlock->baselineVersion() : 0)
{
@@ -56,7 +56,7 @@ public:
}
CodeBlock* codeBlock() { return m_codeBlock; }
- JSGlobalData* globalData() { return m_globalData; }
+ VM* vm() { return m_vm; }
AssemblerType_T& assembler() { return m_assembler; }
#if CPU(X86_64) || CPU(X86)
@@ -110,6 +110,23 @@ public:
}
#endif
+#if CPU(SH4)
+ ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
+ {
+ m_assembler.stspr(reg);
+ }
+
+ ALWAYS_INLINE void restoreReturnAddressBeforeReturn(RegisterID reg)
+ {
+ m_assembler.ldspr(reg);
+ }
+
+ ALWAYS_INLINE void restoreReturnAddressBeforeReturn(Address address)
+ {
+ loadPtrLinkReg(address);
+ }
+#endif
+
void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to)
{
loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
@@ -187,10 +204,10 @@ public:
}
// Add a debug call. This call has no effect on JIT code execution state.
- void debugCall(V_DFGDebugOperation_EP function, void* argument)
+ void debugCall(V_DFGDebugOperation_EPP function, void* argument)
{
size_t scratchSize = sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters);
- ScratchBuffer* scratchBuffer = m_globalData->scratchBufferForSize(scratchSize);
+ ScratchBuffer* scratchBuffer = m_vm->scratchBufferForSize(scratchSize);
EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer());
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
@@ -210,13 +227,15 @@ public:
move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::regT0);
storePtr(TrustedImmPtr(scratchSize), GPRInfo::regT0);
-#if CPU(X86_64) || CPU(ARM) || CPU(MIPS)
+#if CPU(X86_64) || CPU(ARM) || CPU(MIPS) || CPU(SH4)
+ move(TrustedImmPtr(buffer), GPRInfo::argumentGPR2);
move(TrustedImmPtr(argument), GPRInfo::argumentGPR1);
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- GPRReg scratch = selectScratchGPR(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1);
+ GPRReg scratch = selectScratchGPR(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2);
#elif CPU(X86)
poke(GPRInfo::callFrameRegister, 0);
poke(TrustedImmPtr(argument), 1);
+ poke(TrustedImmPtr(buffer), 2);
GPRReg scratch = GPRInfo::regT0;
#else
#error "DFG JIT not supported on this platform."
@@ -290,9 +309,9 @@ public:
Jump emitExceptionCheck(ExceptionCheckKind kind = NormalExceptionCheck)
{
#if USE(JSVALUE64)
- return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(&globalData()->exception));
+ return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(&vm()->exception));
#elif USE(JSVALUE32_64)
- return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(&globalData()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
+ return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(&vm()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
#endif
}
@@ -317,17 +336,11 @@ public:
return codeBlock()->globalObjectFor(codeOrigin);
}
- JSObject* globalThisObjectFor(CodeOrigin codeOrigin)
- {
- JSGlobalObject* object = globalObjectFor(codeOrigin);
- return object->methodTable()->toThisObject(object, 0);
- }
-
bool strictModeFor(CodeOrigin codeOrigin)
{
if (!codeOrigin.inlineCallFrame)
return codeBlock()->isStrictMode();
- return codeOrigin.inlineCallFrame->callee->jsExecutable()->isStrictMode();
+ return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->isStrictMode();
}
ExecutableBase* executableFor(const CodeOrigin& codeOrigin);
@@ -385,7 +398,7 @@ public:
Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*);
protected:
- JSGlobalData* m_globalData;
+ VM* m_vm;
CodeBlock* m_codeBlock;
CodeBlock* m_baselineCodeBlock;
diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
new file mode 100644
index 000000000..2f06646aa
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGBackwardsPropagationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+class BackwardsPropagationPhase : public Phase {
+public:
+ BackwardsPropagationPhase(Graph& graph)
+ : Phase(graph, "backwards propagation")
+ {
+ }
+
+ bool run()
+ {
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+
+ // Prevent a tower of overflowing additions from creating a value that is out of the
+ // safe 2^48 range.
+ m_allowNestedOverflowingAdditions = block->size() < (1 << 16);
+
+ for (unsigned indexInBlock = block->size(); indexInBlock--;)
+ propagate(block->at(indexInBlock));
+ }
+
+ return true;
+ }
+
+private:
+ bool isNotNegZero(Node* node)
+ {
+ if (!m_graph.isNumberConstant(node))
+ return false;
+ double value = m_graph.valueOfNumberConstant(node);
+ return (value || 1.0 / value > 0.0);
+ }
+
+ bool isNotPosZero(Node* node)
+ {
+ if (!m_graph.isNumberConstant(node))
+ return false;
+ double value = m_graph.valueOfNumberConstant(node);
+ return (value || 1.0 / value < 0.0);
+ }
+
+ // Tests if the absolute value is strictly less than the power of two.
+ template<int power>
+ bool isWithinPowerOfTwoForConstant(Node* node)
+ {
+ JSValue immediateValue = node->valueOfJSConstant(codeBlock());
+ if (!immediateValue.isNumber())
+ return false;
+ double immediate = immediateValue.asNumber();
+ return immediate > -(static_cast<int64_t>(1) << power) && immediate < (static_cast<int64_t>(1) << power);
+ }
+
+ template<int power>
+ bool isWithinPowerOfTwoNonRecursive(Node* node)
+ {
+ if (node->op() != JSConstant)
+ return false;
+ return isWithinPowerOfTwoForConstant<power>(node);
+ }
+
+ template<int power>
+ bool isWithinPowerOfTwo(Node* node)
+ {
+ switch (node->op()) {
+ case JSConstant: {
+ return isWithinPowerOfTwoForConstant<power>(node);
+ }
+
+ case BitAnd: {
+ if (power > 31)
+ return true;
+
+ return isWithinPowerOfTwoNonRecursive<power>(node->child1().node())
+ || isWithinPowerOfTwoNonRecursive<power>(node->child2().node());
+ }
+
+ case BitOr:
+ case BitXor:
+ case BitLShift:
+ case ValueToInt32: {
+ return power > 31;
+ }
+
+ case BitRShift:
+ case BitURShift: {
+ if (power > 31)
+ return true;
+
+ Node* shiftAmount = node->child2().node();
+ if (shiftAmount->op() != JSConstant)
+ return false;
+ JSValue immediateValue = shiftAmount->valueOfJSConstant(codeBlock());
+ if (!immediateValue.isInt32())
+ return false;
+ return immediateValue.asInt32() > 32 - power;
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ template<int power>
+ bool isWithinPowerOfTwo(Edge edge)
+ {
+ return isWithinPowerOfTwo<power>(edge.node());
+ }
+
+ bool mergeDefaultFlags(Node* node)
+ {
+ bool changed = false;
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild();
+ childIdx < node->firstChild() + node->numChildren();
+ childIdx++) {
+ if (!!m_graph.m_varArgChildren[childIdx])
+ changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
+ }
+ } else {
+ if (!node->child1())
+ return changed;
+ changed |= node->child1()->mergeFlags(NodeUsedAsValue);
+ if (!node->child2())
+ return changed;
+ changed |= node->child2()->mergeFlags(NodeUsedAsValue);
+ if (!node->child3())
+ return changed;
+ changed |= node->child3()->mergeFlags(NodeUsedAsValue);
+ }
+ return changed;
+ }
+
+ void propagate(Node* node)
+ {
+ NodeFlags flags = node->flags() & NodeBackPropMask;
+
+ switch (node->op()) {
+ case GetLocal: {
+ VariableAccessData* variableAccessData = node->variableAccessData();
+ variableAccessData->mergeFlags(flags);
+ break;
+ }
+
+ case SetLocal: {
+ VariableAccessData* variableAccessData = node->variableAccessData();
+ if (!variableAccessData->isLoadedFrom())
+ break;
+ node->child1()->mergeFlags(NodeUsedAsValue);
+ break;
+ }
+
+ case BitAnd:
+ case BitOr:
+ case BitXor:
+ case BitRShift:
+ case BitLShift:
+ case BitURShift:
+ case ArithIMul: {
+ flags |= NodeUsedAsInt;
+ flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case ValueToInt32: {
+ flags |= NodeUsedAsInt;
+ flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
+ node->child1()->mergeFlags(flags);
+ break;
+ }
+
+ case StringCharCodeAt: {
+ node->child1()->mergeFlags(NodeUsedAsValue);
+ node->child2()->mergeFlags(NodeUsedAsValue | NodeUsedAsInt);
+ break;
+ }
+
+ case Identity:
+ case UInt32ToNumber: {
+ node->child1()->mergeFlags(flags);
+ break;
+ }
+
+ case ValueAdd: {
+ if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
+ flags &= ~NodeNeedsNegZero;
+ if (node->child1()->hasNumberResult() || node->child2()->hasNumberResult())
+ flags &= ~NodeUsedAsOther;
+ if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
+ flags |= NodeUsedAsNumber;
+ if (!m_allowNestedOverflowingAdditions)
+ flags |= NodeUsedAsNumber;
+
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case ArithAdd: {
+ if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
+ flags &= ~NodeNeedsNegZero;
+ if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
+ flags |= NodeUsedAsNumber;
+ if (!m_allowNestedOverflowingAdditions)
+ flags |= NodeUsedAsNumber;
+
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case ArithSub: {
+ if (isNotNegZero(node->child1().node()) || isNotPosZero(node->child2().node()))
+ flags &= ~NodeNeedsNegZero;
+ if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
+ flags |= NodeUsedAsNumber;
+ if (!m_allowNestedOverflowingAdditions)
+ flags |= NodeUsedAsNumber;
+
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case ArithNegate: {
+ flags &= ~NodeUsedAsOther;
+
+ node->child1()->mergeFlags(flags);
+ break;
+ }
+
+ case ArithMul: {
+ // As soon as a multiply happens, we can easily end up in the part
+ // of the double domain where the point at which you do truncation
+ // can change the outcome. So, ArithMul always forces its inputs to
+ // check for overflow. Additionally, it will have to check for overflow
+ // itself unless we can prove that there is no way for the values
+ // produced to cause double rounding.
+
+ if (!isWithinPowerOfTwo<22>(node->child1().node())
+ && !isWithinPowerOfTwo<22>(node->child2().node()))
+ flags |= NodeUsedAsNumber;
+
+ node->mergeFlags(flags);
+
+ flags |= NodeUsedAsNumber | NodeNeedsNegZero;
+ flags &= ~NodeUsedAsOther;
+
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case ArithDiv: {
+ flags |= NodeUsedAsNumber | NodeNeedsNegZero;
+ flags &= ~NodeUsedAsOther;
+
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case ArithMod: {
+ flags |= NodeUsedAsNumber | NodeNeedsNegZero;
+ flags &= ~NodeUsedAsOther;
+
+ node->child1()->mergeFlags(flags);
+ node->child2()->mergeFlags(flags);
+ break;
+ }
+
+ case GetByVal: {
+ node->child1()->mergeFlags(NodeUsedAsValue);
+ node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
+ break;
+ }
+
+ case GetMyArgumentByValSafe: {
+ node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
+ break;
+ }
+
+ case NewArrayWithSize: {
+ node->child1()->mergeFlags(NodeUsedAsValue | NodeUsedAsInt);
+ break;
+ }
+
+ case StringCharAt: {
+ node->child1()->mergeFlags(NodeUsedAsValue);
+ node->child2()->mergeFlags(NodeUsedAsValue | NodeUsedAsInt);
+ break;
+ }
+
+ case ToString: {
+ node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther);
+ break;
+ }
+
+ case ToPrimitive: {
+ node->child1()->mergeFlags(flags);
+ break;
+ }
+
+ case PutByVal: {
+ m_graph.varArgChild(node, 0)->mergeFlags(NodeUsedAsValue);
+ m_graph.varArgChild(node, 1)->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
+ m_graph.varArgChild(node, 2)->mergeFlags(NodeUsedAsValue);
+ break;
+ }
+
+ default:
+ mergeDefaultFlags(node);
+ break;
+ }
+ }
+
+ bool m_allowNestedOverflowingAdditions;
+};
+
+bool performBackwardsPropagation(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Backwards Propagation Phase");
+ return runPhase<BackwardsPropagationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h
new file mode 100644
index 000000000..438684657
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGBackwardsPropagationPhase_h
+#define DFGBackwardsPropagationPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Infer basic information about how nodes are used by doing a block-local
+// backwards flow analysis.
+
+bool performBackwardsPropagation(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBackwardsPropagationPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
index 6f348f2e1..bae9d5258 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,15 +31,18 @@
#include "DFGAbstractValue.h"
#include "DFGBranchDirection.h"
#include "DFGNode.h"
+#include "DFGVariadicFunction.h"
#include "Operands.h"
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
+class Graph;
+
typedef Vector <BlockIndex, 2> PredecessorList;
-struct BasicBlock : Vector<NodeIndex, 8> {
+struct BasicBlock : Vector<Node*, 8> {
BasicBlock(unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals)
: bytecodeBegin(bytecodeBegin)
, isOSRTarget(false)
@@ -72,7 +75,7 @@ struct BasicBlock : Vector<NodeIndex, 8> {
}
size_t numNodes() const { return phis.size() + size(); }
- NodeIndex nodeIndex(size_t i) const
+ Node* node(size_t i) const
{
if (i < phis.size())
return phis[i];
@@ -80,24 +83,29 @@ struct BasicBlock : Vector<NodeIndex, 8> {
}
bool isPhiIndex(size_t i) const { return i < phis.size(); }
- bool isInPhis(NodeIndex nodeIndex) const
+ bool isInPhis(Node* node) const
{
for (size_t i = 0; i < phis.size(); ++i) {
- if (phis[i] == nodeIndex)
+ if (phis[i] == node)
return true;
}
return false;
}
- bool isInBlock(NodeIndex index) const
+ bool isInBlock(Node* myNode) const
{
for (size_t i = 0; i < numNodes(); ++i) {
- if (nodeIndex(i) == index)
+ if (node(i) == myNode)
return true;
}
return false;
}
-
+
+#define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
+ templatePre typeParams templatePost Node* appendNode(Graph&, SpeculatedType valueParamsComma valueParams);
+ DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
+#undef DFG_DEFINE_APPEND_NODE
+
// This value is used internally for block linking and OSR entry. It is mostly meaningless
// for other purposes due to inlining.
unsigned bytecodeBegin;
@@ -113,11 +121,11 @@ struct BasicBlock : Vector<NodeIndex, 8> {
#endif
bool isReachable;
- Vector<NodeIndex> phis;
+ Vector<Node*> phis;
PredecessorList m_predecessors;
- Operands<NodeIndex, NodeIndexTraits> variablesAtHead;
- Operands<NodeIndex, NodeIndexTraits> variablesAtTail;
+ Operands<Node*, NodePointerTraits> variablesAtHead;
+ Operands<Node*, NodePointerTraits> variablesAtTail;
Operands<AbstractValue> valuesAtHead;
Operands<AbstractValue> valuesAtTail;
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h b/Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h
new file mode 100644
index 000000000..06eb39322
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlockInlines.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGBasicBlockInlines_h
+#define DFGBasicBlockInlines_h
+
+#include "DFGBasicBlock.h"
+#include "DFGGraph.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+#define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
+ templatePre typeParams templatePost inline Node* BasicBlock::appendNode(Graph& graph, SpeculatedType type valueParamsComma valueParams) \
+ { \
+ Node* result = graph.addNode(type valueParamsComma valueArgs); \
+ append(result); \
+ return result; \
+ }
+ DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
+#undef DFG_DEFINE_APPEND_NODE
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGBasicBlockInlines_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeCache.h b/Source/JavaScriptCore/dfg/DFGByteCodeCache.h
deleted file mode 100644
index e1837b041..000000000
--- a/Source/JavaScriptCore/dfg/DFGByteCodeCache.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DFGByteCodeCache_h
-#define DFGByteCodeCache_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(DFG_JIT)
-
-#include "CodeBlock.h"
-#include "Executable.h"
-#include "JSFunction.h"
-#include <wtf/HashMap.h>
-
-namespace JSC { namespace DFG {
-
-class CodeBlockKey {
-public:
- CodeBlockKey()
- : m_executable(0)
- , m_kind(CodeForCall) // CodeForCall = empty value
- {
- }
-
- CodeBlockKey(WTF::HashTableDeletedValueType)
- : m_executable(0)
- , m_kind(CodeForConstruct) // CodeForConstruct = deleted value
- {
- }
-
- CodeBlockKey(FunctionExecutable* executable, CodeSpecializationKind kind)
- : m_executable(executable)
- , m_kind(kind)
- {
- }
-
- bool operator==(const CodeBlockKey& other) const
- {
- return m_executable == other.m_executable
- && m_kind == other.m_kind;
- }
-
- unsigned hash() const
- {
- return WTF::PtrHash<FunctionExecutable*>::hash(m_executable) ^ static_cast<unsigned>(m_kind);
- }
-
- FunctionExecutable* executable() const { return m_executable; }
- CodeSpecializationKind kind() const { return m_kind; }
-
- bool isHashTableDeletedValue() const
- {
- return !m_executable && m_kind == CodeForConstruct;
- }
-
-private:
- FunctionExecutable* m_executable;
- CodeSpecializationKind m_kind;
-};
-
-struct CodeBlockKeyHash {
- static unsigned hash(const CodeBlockKey& key) { return key.hash(); }
- static bool equal(const CodeBlockKey& a, const CodeBlockKey& b) { return a == b; }
-
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-} } // namespace JSC::DFG
-
-namespace WTF {
-
-template<typename T> struct DefaultHash;
-template<> struct DefaultHash<JSC::DFG::CodeBlockKey> {
- typedef JSC::DFG::CodeBlockKeyHash Hash;
-};
-
-template<typename T> struct HashTraits;
-template<> struct HashTraits<JSC::DFG::CodeBlockKey> : SimpleClassHashTraits<JSC::DFG::CodeBlockKey> { };
-
-} // namespace WTF
-
-namespace JSC { namespace DFG {
-
-struct ByteCodeCacheValue {
- FunctionCodeBlock* codeBlock;
- bool owned;
- bool oldValueOfShouldDiscardBytecode;
-
- // All uses of this struct initialize everything manually. But gcc isn't
- // smart enough to see that, so this constructor is just here to make the
- // compiler happy.
- ByteCodeCacheValue()
- : codeBlock(0)
- , owned(false)
- , oldValueOfShouldDiscardBytecode(false)
- {
- }
-};
-
-template<bool (*filterFunction)(CodeBlock*, CodeSpecializationKind)>
-class ByteCodeCache {
-public:
- typedef HashMap<CodeBlockKey, ByteCodeCacheValue> Map;
-
- ByteCodeCache() { }
-
- ~ByteCodeCache()
- {
- Map::iterator begin = m_map.begin();
- Map::iterator end = m_map.end();
- for (Map::iterator iter = begin; iter != end; ++iter) {
- if (!iter->value.codeBlock)
- continue;
- if (iter->value.owned) {
- delete iter->value.codeBlock;
- continue;
- }
- }
- }
-
- CodeBlock* get(const CodeBlockKey& key, JSScope* scope)
- {
- Map::iterator iter = m_map.find(key);
- if (iter != m_map.end())
- return iter->value.codeBlock;
-
- ByteCodeCacheValue value;
-
- // First see if there is already a parsed code block that still has some
- // bytecode in it.
- value.codeBlock = key.executable()->codeBlockWithBytecodeFor(key.kind());
- if (value.codeBlock) {
- value.owned = false;
- } else {
- // Nope, so try to parse one.
- JSObject* exception;
- value.owned = true;
- value.codeBlock = key.executable()->produceCodeBlockFor(scope, key.kind(), exception).leakPtr();
- }
-
- // Check if there is any reason to reject this from our cache. If so, then
- // poison it.
- if (!!value.codeBlock && !filterFunction(value.codeBlock, key.kind())) {
- if (value.owned)
- delete value.codeBlock;
- value.codeBlock = 0;
- }
-
- m_map.add(key, value);
-
- return value.codeBlock;
- }
-
-private:
- Map m_map;
-};
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGByteCodeCache_h
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 3facd63bb..a76d5f250 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,12 +31,16 @@
#include "ArrayConstructor.h"
#include "CallLinkStatus.h"
#include "CodeBlock.h"
+#include "CodeBlockWithJITType.h"
#include "DFGArrayMode.h"
-#include "DFGByteCodeCache.h"
#include "DFGCapabilities.h"
#include "GetByIdStatus.h"
+#include "Operations.h"
+#include "PreciseJumpTargets.h"
#include "PutByIdStatus.h"
#include "ResolveGlobalStatus.h"
+#include "StringConstructor.h"
+#include <wtf/CommaPrinter.h>
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
@@ -117,9 +121,8 @@ namespace JSC { namespace DFG {
// This class is used to compile the dataflow graph from a CodeBlock.
class ByteCodeParser {
public:
- ByteCodeParser(ExecState* exec, Graph& graph)
- : m_exec(exec)
- , m_globalData(&graph.m_globalData)
+ ByteCodeParser(Graph& graph)
+ : m_vm(&graph.m_vm)
, m_codeBlock(graph.m_codeBlock)
, m_profiledBlock(graph.m_profiledBlock)
, m_graph(graph)
@@ -136,7 +139,6 @@ public:
, m_preservedVars(m_codeBlock->m_numVars)
, m_parameterSlots(0)
, m_numPassedVarArgs(0)
- , m_globalResolveNumber(0)
, m_inlineStackTop(0)
, m_haveBuiltOperandMaps(false)
, m_emptyJSValueIndex(UINT_MAX)
@@ -152,6 +154,8 @@ public:
bool parse();
private:
+ struct InlineStackEntry;
+
// Just parse from m_currentIndex to the end of the current CodeBlock.
void parseCodeBlock();
@@ -160,24 +164,27 @@ private:
// Handle calls. This resolves issues surrounding inlining and intrinsics.
void handleCall(Interpreter*, Instruction* currentInstruction, NodeType op, CodeSpecializationKind);
- void emitFunctionCheck(JSFunction* expectedFunction, NodeIndex callTarget, int registerOffset, CodeSpecializationKind);
+ void emitFunctionChecks(const CallLinkStatus&, Node* callTarget, int registerOffset, CodeSpecializationKind);
+ void emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind);
// Handle inlining. Return true if it succeeded, false if we need to plant a call.
- bool handleInlining(bool usesResult, int callTarget, NodeIndex callTargetNodeIndex, int resultOperand, bool certainAboutExpectedFunction, JSFunction*, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind);
+ bool handleInlining(bool usesResult, Node* callTargetNode, int resultOperand, const CallLinkStatus&, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind);
// Handle setting the result of an intrinsic.
- void setIntrinsicResult(bool usesResult, int resultOperand, NodeIndex);
+ void setIntrinsicResult(bool usesResult, int resultOperand, Node*);
// Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
bool handleConstantInternalFunction(bool usesResult, int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
- NodeIndex handleGetByOffset(SpeculatedType, NodeIndex base, unsigned identifierNumber, PropertyOffset);
+ Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset);
void handleGetByOffset(
- int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
+ int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber,
PropertyOffset);
void handleGetById(
- int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
+ int destinationOperand, SpeculatedType, Node* base, unsigned identifierNumber,
const GetByIdStatus&);
+ Node* getScope(bool skipTop, unsigned skipCount);
+
// Convert a set of ResolveOperations into graph nodes
- bool parseResolveOperations(SpeculatedType, unsigned identifierNumber, unsigned operations, unsigned putToBaseOperation, NodeIndex* base, NodeIndex* value);
+ bool parseResolveOperations(SpeculatedType, unsigned identifierNumber, ResolveOperations*, PutToBaseOperation*, Node** base, Node** value);
// Prepare to parse a block.
void prepareToParseBlock();
@@ -186,17 +193,6 @@ private:
// Link block successors.
void linkBlock(BasicBlock*, Vector<BlockIndex>& possibleTargets);
void linkBlocks(Vector<UnlinkedBlock>& unlinkedBlocks, Vector<BlockIndex>& possibleTargets);
- // Link GetLocal & SetLocal nodes, to ensure live values are generated.
- enum PhiStackType {
- LocalPhiStack,
- ArgumentPhiStack
- };
- template<PhiStackType stackType>
- void processPhiStack();
-
- void fixVariableAccessPredictions();
- // Add spill locations to nodes.
- void allocateVirtualRegisters();
VariableAccessData* newVariableAccessData(int operand, bool isCaptured)
{
@@ -207,7 +203,7 @@ private:
}
// Get/Set the operands/result of a bytecode instruction.
- NodeIndex getDirect(int operand)
+ Node* getDirect(int operand)
{
// Is this a constant?
if (operand >= FirstConstantRegisterIndex) {
@@ -216,8 +212,7 @@ private:
return getJSConstant(constant);
}
- if (operand == JSStack::Callee)
- return getCallee();
+ ASSERT(operand != JSStack::Callee);
// Is this an argument?
if (operandIsArgument(operand))
@@ -226,12 +221,19 @@ private:
// Must be a local.
return getLocal((unsigned)operand);
}
- NodeIndex get(int operand)
+ Node* get(int operand)
{
+ if (operand == JSStack::Callee) {
+ if (inlineCallFrame() && inlineCallFrame()->callee)
+ return cellConstant(inlineCallFrame()->callee.get());
+
+ return getCallee();
+ }
+
return getDirect(m_inlineStackTop->remapOperand(operand));
}
enum SetMode { NormalSet, SetOnEntry };
- void setDirect(int operand, NodeIndex value, SetMode setMode = NormalSet)
+ void setDirect(int operand, Node* value, SetMode setMode = NormalSet)
{
// Is this an argument?
if (operandIsArgument(operand)) {
@@ -242,12 +244,12 @@ private:
// Must be a local.
setLocal((unsigned)operand, value, setMode);
}
- void set(int operand, NodeIndex value, SetMode setMode = NormalSet)
+ void set(int operand, Node* value, SetMode setMode = NormalSet)
{
setDirect(m_inlineStackTop->remapOperand(operand), value, setMode);
}
- void setPair(int operand1, NodeIndex value1, int operand2, NodeIndex value2)
+ void setPair(int operand1, Node* value1, int operand2, Node* value2)
{
// First emit dead SetLocals for the benefit of OSR.
set(operand1, value1);
@@ -258,89 +260,60 @@ private:
set(operand2, value2);
}
- NodeIndex injectLazyOperandSpeculation(NodeIndex nodeIndex)
+ Node* injectLazyOperandSpeculation(Node* node)
{
- Node& node = m_graph[nodeIndex];
- ASSERT(node.op() == GetLocal);
- ASSERT(node.codeOrigin.bytecodeIndex == m_currentIndex);
+ ASSERT(node->op() == GetLocal);
+ ASSERT(node->codeOrigin.bytecodeIndex == m_currentIndex);
SpeculatedType prediction =
m_inlineStackTop->m_lazyOperands.prediction(
- LazyOperandValueProfileKey(m_currentIndex, node.local()));
+ LazyOperandValueProfileKey(m_currentIndex, node->local()));
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("Lazy operand [@", nodeIndex, ", bc#", m_currentIndex, ", r", node.local(), "] prediction: ", SpeculationDump(prediction), "\n");
+ dataLog("Lazy operand [@", node->index(), ", bc#", m_currentIndex, ", r", node->local(), "] prediction: ", SpeculationDump(prediction), "\n");
#endif
- node.variableAccessData()->predict(prediction);
- return nodeIndex;
+ node->variableAccessData()->predict(prediction);
+ return node;
}
// Used in implementing get/set, above, where the operand is a local variable.
- NodeIndex getLocal(unsigned operand)
- {
- NodeIndex nodeIndex = m_currentBlock->variablesAtTail.local(operand);
- bool isCaptured = m_codeBlock->isCaptured(operand, m_inlineStackTop->m_inlineCallFrame);
-
- if (nodeIndex != NoNode) {
- Node* nodePtr = &m_graph[nodeIndex];
- if (nodePtr->op() == Flush) {
- // 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.
- nodeIndex = nodePtr->child1().index();
- Node& flushChild = m_graph[nodeIndex];
- if (flushChild.op() == Phi) {
- VariableAccessData* variableAccessData = flushChild.variableAccessData();
- variableAccessData->mergeIsCaptured(isCaptured);
- nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variableAccessData), nodeIndex));
- m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
- return nodeIndex;
+ Node* getLocal(unsigned operand)
+ {
+ Node* node = m_currentBlock->variablesAtTail.local(operand);
+ bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
+
+ // This has two goals: 1) link together variable access datas, and 2)
+ // try to avoid creating redundant GetLocals. (1) is required for
+ // correctness - no other phase will ensure that block-local variable
+ // access data unification is done correctly. (2) is purely opportunistic
+ // and is meant as an compile-time optimization only.
+
+ VariableAccessData* variable;
+
+ if (node) {
+ variable = node->variableAccessData();
+ variable->mergeIsCaptured(isCaptured);
+
+ if (!isCaptured) {
+ switch (node->op()) {
+ case GetLocal:
+ return node;
+ case SetLocal:
+ return node->child1().node();
+ default:
+ break;
}
- nodePtr = &flushChild;
}
-
- ASSERT(&m_graph[nodeIndex] == nodePtr);
- ASSERT(nodePtr->op() != Flush);
-
- nodePtr->variableAccessData()->mergeIsCaptured(isCaptured);
-
- if (isCaptured) {
- // 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();
-
- NodeIndex newGetLocal = injectLazyOperandSpeculation(
- addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
- m_currentBlock->variablesAtTail.local(operand) = newGetLocal;
- return newGetLocal;
- }
-
- if (nodePtr->op() == GetLocal)
- return nodeIndex;
- ASSERT(nodePtr->op() == SetLocal);
- return nodePtr->child1().index();
+ } else {
+ m_preservedVars.set(operand);
+ variable = newVariableAccessData(operand, isCaptured);
}
-
- // Check for reads of temporaries from prior blocks,
- // expand m_preservedVars to cover these.
- m_preservedVars.set(operand);
- VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
-
- NodeIndex phi = addToGraph(Phi, OpInfo(variableAccessData));
- m_localPhiStack.append(PhiStackEntry(m_currentBlock, phi, operand));
- nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variableAccessData), phi));
- m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
-
- m_currentBlock->variablesAtHead.setLocalFirstTime(operand, nodeIndex);
-
- return nodeIndex;
+ node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
+ m_currentBlock->variablesAtTail.local(operand) = node;
+ return node;
}
- void setLocal(unsigned operand, NodeIndex value, SetMode setMode = NormalSet)
+ void setLocal(unsigned operand, Node* value, SetMode setMode = NormalSet)
{
- bool isCaptured = m_codeBlock->isCaptured(operand, m_inlineStackTop->m_inlineCallFrame);
+ bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
if (setMode == NormalSet) {
ArgumentPosition* argumentPosition = findArgumentPositionForLocal(operand);
@@ -351,92 +324,61 @@ private:
VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
variableAccessData->mergeStructureCheckHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
- NodeIndex nodeIndex = addToGraph(SetLocal, OpInfo(variableAccessData), value);
- m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
+ Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
+ m_currentBlock->variablesAtTail.local(operand) = node;
}
// Used in implementing get/set, above, where the operand is an argument.
- NodeIndex getArgument(unsigned operand)
+ Node* getArgument(unsigned operand)
{
unsigned argument = operandToArgument(operand);
ASSERT(argument < m_numArguments);
- NodeIndex nodeIndex = m_currentBlock->variablesAtTail.argument(argument);
+ Node* node = m_currentBlock->variablesAtTail.argument(argument);
bool isCaptured = m_codeBlock->isCaptured(operand);
- if (nodeIndex != NoNode) {
- Node* nodePtr = &m_graph[nodeIndex];
- if (nodePtr->op() == Flush) {
- // 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.
- nodeIndex = nodePtr->child1().index();
- Node& flushChild = m_graph[nodeIndex];
- if (flushChild.op() == Phi) {
- VariableAccessData* variableAccessData = flushChild.variableAccessData();
- variableAccessData->mergeIsCaptured(isCaptured);
- nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variableAccessData), nodeIndex));
- m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
- return nodeIndex;
- }
- nodePtr = &flushChild;
- }
-
- ASSERT(&m_graph[nodeIndex] == nodePtr);
- ASSERT(nodePtr->op() != Flush);
-
- nodePtr->variableAccessData()->mergeIsCaptured(isCaptured);
-
- if (nodePtr->op() == SetArgument) {
- // We're getting an argument in the first basic block; link
- // the GetLocal to the SetArgument.
- ASSERT(nodePtr->local() == static_cast<VirtualRegister>(operand));
- VariableAccessData* variable = nodePtr->variableAccessData();
- nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable), nodeIndex));
- m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
- return nodeIndex;
- }
+ VariableAccessData* variable;
+
+ if (node) {
+ variable = node->variableAccessData();
+ variable->mergeIsCaptured(isCaptured);
- if (isCaptured) {
- if (nodePtr->op() == GetLocal)
- nodeIndex = nodePtr->child1().index();
- return injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
+ switch (node->op()) {
+ case GetLocal:
+ return node;
+ case SetLocal:
+ return node->child1().node();
+ default:
+ break;
}
-
- if (nodePtr->op() == GetLocal)
- return nodeIndex;
-
- ASSERT(nodePtr->op() == SetLocal);
- return nodePtr->child1().index();
- }
-
- VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
-
- NodeIndex phi = addToGraph(Phi, OpInfo(variableAccessData));
- m_argumentPhiStack.append(PhiStackEntry(m_currentBlock, phi, argument));
- nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variableAccessData), phi));
- m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
+ } else
+ variable = newVariableAccessData(operand, isCaptured);
- m_currentBlock->variablesAtHead.setArgumentFirstTime(argument, nodeIndex);
-
- return nodeIndex;
+ node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
+ m_currentBlock->variablesAtTail.argument(argument) = node;
+ return node;
}
- void setArgument(int operand, NodeIndex value, SetMode setMode = NormalSet)
+ void setArgument(int operand, Node* value, SetMode setMode = NormalSet)
{
unsigned argument = operandToArgument(operand);
ASSERT(argument < m_numArguments);
bool isCaptured = m_codeBlock->isCaptured(operand);
- // Always flush arguments, except for 'this'.
- if (argument && setMode == NormalSet)
- flushDirect(operand);
-
VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+
+ // Always flush arguments, except for 'this'. If 'this' is created by us,
+ // then make sure that it's never unboxed.
+ if (argument) {
+ if (setMode == NormalSet)
+ flushDirect(operand);
+ } else if (m_codeBlock->specializationKind() == CodeForConstruct)
+ variableAccessData->mergeShouldNeverUnbox(true);
+
variableAccessData->mergeStructureCheckHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
- NodeIndex nodeIndex = addToGraph(SetLocal, OpInfo(variableAccessData), value);
- m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
+ Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
+ m_currentBlock->variablesAtTail.argument(argument) = node;
}
ArgumentPosition* findArgumentPositionForArgument(int argument)
@@ -484,113 +426,88 @@ private:
void flushDirect(int operand, ArgumentPosition* argumentPosition)
{
- // FIXME: This should check if the same operand had already been flushed to
- // some other local variable.
-
- bool isCaptured = m_codeBlock->isCaptured(operand, m_inlineStackTop->m_inlineCallFrame);
+ bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
ASSERT(operand < FirstConstantRegisterIndex);
- NodeIndex nodeIndex;
- int index;
- if (operandIsArgument(operand)) {
- index = operandToArgument(operand);
- nodeIndex = m_currentBlock->variablesAtTail.argument(index);
- } else {
- index = operand;
- nodeIndex = m_currentBlock->variablesAtTail.local(index);
+ if (!operandIsArgument(operand))
m_preservedVars.set(operand);
- }
- if (nodeIndex != NoNode) {
- Node& node = m_graph[nodeIndex];
- switch (node.op()) {
- case Flush:
- nodeIndex = node.child1().index();
- break;
- case GetLocal:
- nodeIndex = node.child1().index();
- break;
- default:
- break;
- }
-
- ASSERT(m_graph[nodeIndex].op() != Flush
- && m_graph[nodeIndex].op() != GetLocal);
-
- // 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.
- VariableAccessData* variableAccessData = node.variableAccessData();
- variableAccessData->mergeIsCaptured(isCaptured);
- addToGraph(Flush, OpInfo(variableAccessData), nodeIndex);
- if (argumentPosition)
- argumentPosition->addVariable(variableAccessData);
- return;
- }
+ Node* node = m_currentBlock->variablesAtTail.operand(operand);
- VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
- NodeIndex phi = addToGraph(Phi, OpInfo(variableAccessData));
- nodeIndex = addToGraph(Flush, OpInfo(variableAccessData), phi);
- if (operandIsArgument(operand)) {
- m_argumentPhiStack.append(PhiStackEntry(m_currentBlock, phi, index));
- m_currentBlock->variablesAtTail.argument(index) = nodeIndex;
- m_currentBlock->variablesAtHead.setArgumentFirstTime(index, nodeIndex);
- } else {
- m_localPhiStack.append(PhiStackEntry(m_currentBlock, phi, index));
- m_currentBlock->variablesAtTail.local(index) = nodeIndex;
- m_currentBlock->variablesAtHead.setLocalFirstTime(index, nodeIndex);
- }
+ VariableAccessData* variable;
+
+ if (node) {
+ variable = node->variableAccessData();
+ variable->mergeIsCaptured(isCaptured);
+ } else
+ variable = newVariableAccessData(operand, isCaptured);
+
+ node = addToGraph(Flush, OpInfo(variable));
+ m_currentBlock->variablesAtTail.operand(operand) = node;
if (argumentPosition)
- argumentPosition->addVariable(variableAccessData);
+ argumentPosition->addVariable(variable);
}
-
- void flushArgumentsAndCapturedVariables()
+
+ void flush(InlineStackEntry* inlineStackEntry)
{
int numArguments;
- if (m_inlineStackTop->m_inlineCallFrame)
- numArguments = m_inlineStackTop->m_inlineCallFrame->arguments.size();
+ if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame)
+ numArguments = inlineCallFrame->arguments.size();
else
- numArguments = m_inlineStackTop->m_codeBlock->numParameters();
+ numArguments = inlineStackEntry->m_codeBlock->numParameters();
for (unsigned argument = numArguments; argument-- > 1;)
- flush(argumentToOperand(argument));
- for (int local = 0; local < m_inlineStackTop->m_codeBlock->m_numVars; ++local) {
- if (!m_inlineStackTop->m_codeBlock->isCaptured(local))
+ flushDirect(inlineStackEntry->remapOperand(argumentToOperand(argument)));
+ for (int local = 0; local < inlineStackEntry->m_codeBlock->m_numVars; ++local) {
+ if (!inlineStackEntry->m_codeBlock->isCaptured(local))
continue;
- flush(local);
+ flushDirect(inlineStackEntry->remapOperand(local));
}
}
+ void flushAllArgumentsAndCapturedVariablesInInlineStack()
+ {
+ for (InlineStackEntry* inlineStackEntry = m_inlineStackTop; inlineStackEntry; inlineStackEntry = inlineStackEntry->m_caller)
+ flush(inlineStackEntry);
+ }
+
+ void flushArgumentsAndCapturedVariables()
+ {
+ flush(m_inlineStackTop);
+ }
+
// Get an operand, and perform a ToInt32/ToNumber conversion on it.
- NodeIndex getToInt32(int operand)
+ Node* getToInt32(int operand)
{
return toInt32(get(operand));
}
// Perform an ES5 ToInt32 operation - returns a node of type NodeResultInt32.
- NodeIndex toInt32(NodeIndex index)
+ Node* toInt32(Node* node)
{
- Node& node = m_graph[index];
+ if (node->hasInt32Result())
+ return node;
- if (node.hasInt32Result())
- return index;
-
- if (node.op() == UInt32ToNumber)
- return node.child1().index();
+ if (node->op() == UInt32ToNumber)
+ return node->child1().node();
// Check for numeric constants boxed as JSValues.
- if (node.op() == JSConstant) {
- JSValue v = valueOfJSConstant(index);
+ if (canFold(node)) {
+ JSValue v = valueOfJSConstant(node);
if (v.isInt32())
- return getJSConstant(node.constantNumber());
+ return getJSConstant(node->constantNumber());
if (v.isNumber())
return getJSConstantForValue(JSValue(JSC::toInt32(v.asNumber())));
}
- return addToGraph(ValueToInt32, index);
+ return addToGraph(ValueToInt32, node);
}
- NodeIndex getJSConstantForValue(JSValue constantValue)
+ // NOTE: Only use this to construct constants that arise from non-speculative
+ // constant folding. I.e. creating constants using this if we had constant
+ // field inference would be a bad idea, since the bytecode parser's folding
+ // doesn't handle liveness preservation.
+ Node* getJSConstantForValue(JSValue constantValue)
{
unsigned constantIndex = m_codeBlock->addOrFindConstant(constantValue);
if (constantIndex >= m_constants.size())
@@ -601,55 +518,55 @@ private:
return getJSConstant(constantIndex);
}
- NodeIndex getJSConstant(unsigned constant)
+ Node* getJSConstant(unsigned constant)
{
- NodeIndex index = m_constants[constant].asJSValue;
- if (index != NoNode)
- return index;
+ Node* node = m_constants[constant].asJSValue;
+ if (node)
+ return node;
- NodeIndex resultIndex = addToGraph(JSConstant, OpInfo(constant));
- m_constants[constant].asJSValue = resultIndex;
- return resultIndex;
+ Node* result = addToGraph(JSConstant, OpInfo(constant));
+ m_constants[constant].asJSValue = result;
+ return result;
}
- NodeIndex getCallee()
+ Node* getCallee()
{
return addToGraph(GetCallee);
}
// Helper functions to get/set the this value.
- NodeIndex getThis()
+ Node* getThis()
{
return get(m_inlineStackTop->m_codeBlock->thisRegister());
}
- void setThis(NodeIndex value)
+ void setThis(Node* value)
{
set(m_inlineStackTop->m_codeBlock->thisRegister(), value);
}
// Convenience methods for checking nodes for constants.
- bool isJSConstant(NodeIndex index)
+ bool isJSConstant(Node* node)
{
- return m_graph[index].op() == JSConstant;
+ return node->op() == JSConstant;
}
- bool isInt32Constant(NodeIndex nodeIndex)
+ bool isInt32Constant(Node* node)
{
- return isJSConstant(nodeIndex) && valueOfJSConstant(nodeIndex).isInt32();
+ return isJSConstant(node) && valueOfJSConstant(node).isInt32();
}
// Convenience methods for getting constant values.
- JSValue valueOfJSConstant(NodeIndex index)
+ JSValue valueOfJSConstant(Node* node)
{
- ASSERT(isJSConstant(index));
- return m_codeBlock->getConstant(FirstConstantRegisterIndex + m_graph[index].constantNumber());
+ ASSERT(isJSConstant(node));
+ return m_codeBlock->getConstant(FirstConstantRegisterIndex + node->constantNumber());
}
- int32_t valueOfInt32Constant(NodeIndex nodeIndex)
+ int32_t valueOfInt32Constant(Node* node)
{
- ASSERT(isInt32Constant(nodeIndex));
- return valueOfJSConstant(nodeIndex).asInt32();
+ ASSERT(isInt32Constant(node));
+ return valueOfJSConstant(node).asInt32();
}
// This method returns a JSConstant with the value 'undefined'.
- NodeIndex constantUndefined()
+ Node* constantUndefined()
{
// Has m_constantUndefined been set up yet?
if (m_constantUndefined == UINT_MAX) {
@@ -674,7 +591,7 @@ private:
}
// This method returns a JSConstant with the value 'null'.
- NodeIndex constantNull()
+ Node* constantNull()
{
// Has m_constantNull been set up yet?
if (m_constantNull == UINT_MAX) {
@@ -699,7 +616,7 @@ private:
}
// This method returns a DoubleConstant with the value 1.
- NodeIndex one()
+ Node* one()
{
// Has m_constant1 been set up yet?
if (m_constant1 == UINT_MAX) {
@@ -725,7 +642,7 @@ private:
}
// This method returns a DoubleConstant with the value NaN.
- NodeIndex constantNaN()
+ Node* constantNaN()
{
JSValue nan = jsNaN();
@@ -748,92 +665,98 @@ private:
// m_constantNaN must refer to an entry in the CodeBlock's constant pool that has the value nan.
ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).isDouble());
- ASSERT(isnan(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).asDouble()));
+ ASSERT(std::isnan(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constantNaN).asDouble()));
return getJSConstant(m_constantNaN);
}
- NodeIndex cellConstant(JSCell* cell)
+ Node* cellConstant(JSCell* cell)
{
- HashMap<JSCell*, NodeIndex>::AddResult result = m_cellConstantNodes.add(cell, NoNode);
+ HashMap<JSCell*, Node*>::AddResult result = m_cellConstantNodes.add(cell, 0);
if (result.isNewEntry)
result.iterator->value = addToGraph(WeakJSConstant, OpInfo(cell));
return result.iterator->value;
}
+ InlineCallFrame* inlineCallFrame()
+ {
+ return m_inlineStackTop->m_inlineCallFrame;
+ }
+
CodeOrigin currentCodeOrigin()
{
- return CodeOrigin(m_currentIndex, m_inlineStackTop->m_inlineCallFrame, m_currentProfilingIndex - m_currentIndex);
+ return CodeOrigin(m_currentIndex, inlineCallFrame(), m_currentProfilingIndex - m_currentIndex);
+ }
+
+ bool canFold(Node* node)
+ {
+ return node->isStronglyProvedConstantIn(inlineCallFrame());
}
- // These methods create a node and add it to the graph. If nodes of this type are
- // 'mustGenerate' then the node will implicitly be ref'ed to ensure generation.
- NodeIndex addToGraph(NodeType op, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ // Our codegen for constant strict equality performs a bitwise comparison,
+ // so we can only select values that have a consistent bitwise identity.
+ bool isConstantForCompareStrictEq(Node* node)
{
- NodeIndex resultIndex = (NodeIndex)m_graph.size();
- m_graph.append(Node(op, currentCodeOrigin(), child1, child2, child3));
+ if (!node->isConstant())
+ return false;
+ JSValue value = valueOfJSConstant(node);
+ return value.isBoolean() || value.isUndefinedOrNull();
+ }
+
+ Node* addToGraph(NodeType op, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
+ {
+ Node* result = m_graph.addNode(
+ SpecNone, op, currentCodeOrigin(), Edge(child1), Edge(child2), Edge(child3));
ASSERT(op != Phi);
- m_currentBlock->append(resultIndex);
-
- if (defaultFlags(op) & NodeMustGenerate)
- m_graph.ref(resultIndex);
- return resultIndex;
+ m_currentBlock->append(result);
+ return result;
}
- NodeIndex addToGraph(NodeType op, OpInfo info, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ Node* addToGraph(NodeType op, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
{
- 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 (defaultFlags(op) & NodeMustGenerate)
- m_graph.ref(resultIndex);
- return resultIndex;
+ Node* result = m_graph.addNode(
+ SpecNone, op, currentCodeOrigin(), child1, child2, child3);
+ ASSERT(op != Phi);
+ m_currentBlock->append(result);
+ return result;
}
- NodeIndex addToGraph(NodeType op, OpInfo info1, OpInfo info2, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
+ Node* addToGraph(NodeType op, OpInfo info, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
{
- NodeIndex resultIndex = (NodeIndex)m_graph.size();
- m_graph.append(Node(op, currentCodeOrigin(), info1, info2, child1, child2, child3));
+ Node* result = m_graph.addNode(
+ SpecNone, op, currentCodeOrigin(), info, Edge(child1), Edge(child2), Edge(child3));
ASSERT(op != Phi);
- m_currentBlock->append(resultIndex);
-
- if (defaultFlags(op) & NodeMustGenerate)
- m_graph.ref(resultIndex);
- return resultIndex;
+ m_currentBlock->append(result);
+ return result;
+ }
+ Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
+ {
+ Node* result = m_graph.addNode(
+ SpecNone, op, currentCodeOrigin(), info1, info2,
+ Edge(child1), Edge(child2), Edge(child3));
+ ASSERT(op != Phi);
+ m_currentBlock->append(result);
+ return result;
}
- NodeIndex addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
+ Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
{
- 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));
+ Node* result = m_graph.addNode(
+ SpecNone, Node::VarArg, op, currentCodeOrigin(), info1, info2,
+ m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs);
ASSERT(op != Phi);
- m_currentBlock->append(resultIndex);
+ m_currentBlock->append(result);
m_numPassedVarArgs = 0;
- 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;
+ return result;
}
- void addVarArgChild(NodeIndex child)
+ void addVarArgChild(Node* child)
{
m_graph.m_varArgChildren.append(Edge(child));
m_numPassedVarArgs++;
}
- NodeIndex addCall(Interpreter* interpreter, Instruction* currentInstruction, NodeType op)
+ Node* addCall(Interpreter* interpreter, Instruction* currentInstruction, NodeType op)
{
Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
@@ -853,48 +776,41 @@ private:
for (int i = 0 + dummyThisArgument; i < argCount; ++i)
addVarArgChild(get(registerOffset + argumentToOperand(i)));
- NodeIndex call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
+ Node* call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
set(putInstruction[1].u.operand, call);
return call;
}
- NodeIndex addStructureTransitionCheck(JSCell* object, Structure* structure)
+ Node* addStructureTransitionCheck(JSCell* object, Structure* structure)
{
// Add a weak JS constant for the object regardless, since the code should
// be jettisoned if the object ever dies.
- NodeIndex objectIndex = cellConstant(object);
+ Node* objectNode = cellConstant(object);
if (object->structure() == structure && structure->transitionWatchpointSetIsStillValid()) {
- addToGraph(StructureTransitionWatchpoint, OpInfo(structure), objectIndex);
- return objectIndex;
+ addToGraph(StructureTransitionWatchpoint, OpInfo(structure), objectNode);
+ return objectNode;
}
- addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectIndex);
+ addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), objectNode);
- return objectIndex;
+ return objectNode;
}
- NodeIndex addStructureTransitionCheck(JSCell* object)
+ Node* addStructureTransitionCheck(JSCell* object)
{
return addStructureTransitionCheck(object, object->structure());
}
- SpeculatedType getPredictionWithoutOSRExit(NodeIndex nodeIndex, unsigned bytecodeIndex)
+ SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
{
- UNUSED_PARAM(nodeIndex);
-
- SpeculatedType prediction = m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(bytecodeIndex);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("Dynamic [@", nodeIndex, ", bc#", bytecodeIndex, "] prediction: ", SpeculationDump(prediction), "\n");
-#endif
-
- return prediction;
+ return m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(bytecodeIndex);
}
- SpeculatedType getPrediction(NodeIndex nodeIndex, unsigned bytecodeIndex)
+ SpeculatedType getPrediction(unsigned bytecodeIndex)
{
- SpeculatedType prediction = getPredictionWithoutOSRExit(nodeIndex, bytecodeIndex);
+ SpeculatedType prediction = getPredictionWithoutOSRExit(bytecodeIndex);
if (prediction == SpecNone) {
// We have no information about what values this node generates. Give up
@@ -907,12 +823,12 @@ private:
SpeculatedType getPredictionWithoutOSRExit()
{
- return getPredictionWithoutOSRExit(m_graph.size(), m_currentProfilingIndex);
+ return getPredictionWithoutOSRExit(m_currentProfilingIndex);
}
SpeculatedType getPrediction()
{
- return getPrediction(m_graph.size(), m_currentProfilingIndex);
+ return getPrediction(m_currentProfilingIndex);
}
ArrayMode getArrayMode(ArrayProfile* profile, Array::Action action)
@@ -926,7 +842,7 @@ private:
return getArrayMode(profile, Array::Read);
}
- ArrayMode getArrayModeAndEmitChecks(ArrayProfile* profile, Array::Action action, NodeIndex base)
+ ArrayMode getArrayModeAndEmitChecks(ArrayProfile* profile, Array::Action action, Node* base)
{
profile->computeUpdatedPrediction(m_inlineStackTop->m_codeBlock);
@@ -937,23 +853,23 @@ private:
#endif
bool makeSafe =
- m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
- || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds);
+ m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)
+ || profile->outOfBounds();
ArrayMode result = ArrayMode::fromObserved(profile, action, makeSafe);
- if (profile->hasDefiniteStructure() && result.benefitsFromStructureCheck())
+ if (profile->hasDefiniteStructure()
+ && result.benefitsFromStructureCheck()
+ && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache))
addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base);
return result;
}
- NodeIndex makeSafe(NodeIndex nodeIndex)
+ Node* makeSafe(Node* node)
{
- Node& node = m_graph[nodeIndex];
-
bool likelyToTakeSlowCase;
- if (!isX86() && node.op() == ArithMod)
+ if (!isX86() && node->op() == ArithMod)
likelyToTakeSlowCase = false;
else
likelyToTakeSlowCase = m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex);
@@ -961,45 +877,45 @@ private:
if (!likelyToTakeSlowCase
&& !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)
&& !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
- return nodeIndex;
+ return node;
- switch (m_graph[nodeIndex].op()) {
+ switch (node->op()) {
case UInt32ToNumber:
case ArithAdd:
case ArithSub:
case ArithNegate:
case ValueAdd:
case ArithMod: // for ArithMod "MayOverflow" means we tried to divide by zero, or we saw double.
- m_graph[nodeIndex].mergeFlags(NodeMayOverflow);
+ node->mergeFlags(NodeMayOverflow);
break;
case ArithMul:
if (m_inlineStackTop->m_profiledBlock->likelyToTakeDeepestSlowCase(m_currentIndex)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) {
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Making ArithMul @%u take deepest slow case.\n", nodeIndex);
+ dataLogF("Making ArithMul @%u take deepest slow case.\n", node->index());
#endif
- m_graph[nodeIndex].mergeFlags(NodeMayOverflow | NodeMayNegZero);
+ node->mergeFlags(NodeMayOverflow | NodeMayNegZero);
} else if (m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) {
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Making ArithMul @%u take faster slow case.\n", nodeIndex);
+ dataLogF("Making ArithMul @%u take faster slow case.\n", node->index());
#endif
- m_graph[nodeIndex].mergeFlags(NodeMayNegZero);
+ node->mergeFlags(NodeMayNegZero);
}
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- return nodeIndex;
+ return node;
}
- NodeIndex makeDivSafe(NodeIndex nodeIndex)
+ Node* makeDivSafe(Node* node)
{
- ASSERT(m_graph[nodeIndex].op() == ArithDiv);
+ ASSERT(node->op() == ArithDiv);
// The main slow case counter for op_div in the old JIT counts only when
// the operands are not numbers. We don't care about that since we already
@@ -1010,40 +926,17 @@ private:
if (!m_inlineStackTop->m_profiledBlock->couldTakeSpecialFastCase(m_currentIndex)
&& !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)
&& !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
- return nodeIndex;
+ return node;
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("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));
+ dataLogF("Making %s @%u safe at bc#%u because special fast-case counter is at %u and exit profiles say %d, %d\n", Graph::opName(node->op()), node->index(), 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
// distinguish between negative zero and overflow in its exit profiles.
- m_graph[nodeIndex].mergeFlags(NodeMayOverflow | NodeMayNegZero);
+ node->mergeFlags(NodeMayOverflow | NodeMayNegZero);
- return nodeIndex;
- }
-
- bool willNeedFlush(StructureStubInfo& stubInfo)
- {
- PolymorphicAccessStructureList* list;
- int listSize;
- switch (stubInfo.accessType) {
- case access_get_by_id_self_list:
- list = stubInfo.u.getByIdSelfList.structureList;
- listSize = stubInfo.u.getByIdSelfList.listSize;
- break;
- case access_get_by_id_proto_list:
- list = stubInfo.u.getByIdProtoList.structureList;
- listSize = stubInfo.u.getByIdProtoList.listSize;
- break;
- default:
- return false;
- }
- for (int i = 0; i < listSize; ++i) {
- if (!list->list[i].isDirect)
- return true;
- }
- return false;
+ return node;
}
bool structureChainIsStillValid(bool direct, Structure* previousStructure, StructureChain* chain)
@@ -1064,8 +957,7 @@ private:
void buildOperandMapsIfNecessary();
- ExecState* m_exec;
- JSGlobalData* m_globalData;
+ VM* m_vm;
CodeBlock* m_codeBlock;
CodeBlock* m_profiledBlock;
Graph& m_graph;
@@ -1087,21 +979,21 @@ private:
unsigned m_constantNaN;
unsigned m_constant1;
HashMap<JSCell*, unsigned> m_cellConstants;
- HashMap<JSCell*, NodeIndex> m_cellConstantNodes;
+ HashMap<JSCell*, Node*> m_cellConstantNodes;
// A constant in the constant pool may be represented by more than one
// node in the graph, depending on the context in which it is being used.
struct ConstantRecord {
ConstantRecord()
- : asInt32(NoNode)
- , asNumeric(NoNode)
- , asJSValue(NoNode)
+ : asInt32(0)
+ , asNumeric(0)
+ , asJSValue(0)
{
}
- NodeIndex asInt32;
- NodeIndex asNumeric;
- NodeIndex asJSValue;
+ Node* asInt32;
+ Node* asNumeric;
+ Node* asJSValue;
};
// Track the index of the node whose result is the current value for every
@@ -1123,24 +1015,7 @@ private:
unsigned m_parameterSlots;
// The number of var args passed to the next var arg node.
unsigned m_numPassedVarArgs;
- // The index in the global resolve info.
- unsigned m_globalResolveNumber;
-
- struct PhiStackEntry {
- PhiStackEntry(BasicBlock* block, NodeIndex phi, unsigned varNo)
- : m_block(block)
- , m_phi(phi)
- , m_varNo(varNo)
- {
- }
- BasicBlock* m_block;
- NodeIndex m_phi;
- unsigned m_varNo;
- };
- Vector<PhiStackEntry, 16> m_argumentPhiStack;
- Vector<PhiStackEntry, 16> m_localPhiStack;
-
HashMap<ConstantBufferKey, unsigned> m_constantBufferCache;
struct InlineStackEntry {
@@ -1149,7 +1024,6 @@ private:
CodeBlock* m_codeBlock;
CodeBlock* m_profiledBlock;
InlineCallFrame* m_inlineCallFrame;
- VirtualRegister m_calleeVR; // absolute virtual register, not relative to call frame
ScriptExecutable* executable() { return m_codeBlock->ownerExecutable(); }
@@ -1162,8 +1036,6 @@ private:
Vector<unsigned> m_identifierRemap;
Vector<unsigned> m_constantRemap;
Vector<unsigned> m_constantBufferRemap;
- Vector<unsigned> m_resolveOperationRemap;
- Vector<unsigned> m_putToBaseOperationRemap;
// Blocks introduced by this code block, which need successor linking.
// May include up to one basic block that includes the continuation after
@@ -1213,8 +1085,7 @@ private:
CodeBlock*,
CodeBlock* profiledBlock,
BlockIndex callsiteBlockHead,
- VirtualRegister calleeVR,
- JSFunction* callee,
+ JSFunction* callee, // Null if this is a closure call.
VirtualRegister returnValueVR,
VirtualRegister inlineCallFrameStart,
int argumentCountIncludingThis,
@@ -1236,8 +1107,7 @@ private:
return result;
}
- if (operand == JSStack::Callee)
- return m_calleeVR;
+ ASSERT(operand != JSStack::Callee);
return operand + m_inlineCallFrame->stackOffset;
}
@@ -1256,9 +1126,6 @@ private:
// 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;
-
Instruction* m_currentInstruction;
};
@@ -1275,138 +1142,125 @@ void ByteCodeParser::handleCall(Interpreter* interpreter, Instruction* currentIn
{
ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
- NodeIndex callTarget = get(currentInstruction[1].u.operand);
- enum {
- ConstantFunction,
- ConstantInternalFunction,
- LinkedFunction,
- UnknownFunction
- } callType;
-
- CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
- m_inlineStackTop->m_profiledBlock, m_currentIndex);
+ Node* callTarget = get(currentInstruction[1].u.operand);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("For call at @%lu bc#%u: ", m_graph.size(), m_currentIndex);
- if (callLinkStatus.isSet()) {
- if (callLinkStatus.couldTakeSlowPath())
- dataLogF("could take slow path, ");
- dataLogF("target = %p\n", callLinkStatus.callTarget());
- } else
- dataLogF("not set.\n");
-#endif
+ CallLinkStatus callLinkStatus;
+
+ if (m_graph.isConstant(callTarget))
+ callLinkStatus = CallLinkStatus(m_graph.valueOfJSConstant(callTarget)).setIsProved(true);
+ else {
+ callLinkStatus = CallLinkStatus::computeFor(m_inlineStackTop->m_profiledBlock, m_currentIndex);
+ callLinkStatus.setHasBadFunctionExitSite(m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadFunction));
+ callLinkStatus.setHasBadCacheExitSite(m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
+ callLinkStatus.setHasBadExecutableExitSite(m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadExecutable));
+ }
- if (m_graph.isFunctionConstant(callTarget)) {
- callType = ConstantFunction;
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Call at [@%lu, bc#%u] has a function constant: %p, exec %p.\n",
- m_graph.size(), m_currentIndex,
- m_graph.valueOfFunctionConstant(callTarget),
- m_graph.valueOfFunctionConstant(callTarget)->executable());
-#endif
- } else if (m_graph.isInternalFunctionConstant(callTarget)) {
- callType = ConstantInternalFunction;
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Call at [@%lu, bc#%u] has an internal function constant: %p.\n",
- m_graph.size(), m_currentIndex,
- m_graph.valueOfInternalFunctionConstant(callTarget));
-#endif
- } else if (callLinkStatus.isSet() && !callLinkStatus.couldTakeSlowPath()
- && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
- callType = LinkedFunction;
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Call at [@%lu, bc#%u] is linked to: %p, exec %p.\n",
- m_graph.size(), m_currentIndex, callLinkStatus.callTarget(),
- callLinkStatus.callTarget()->executable());
-#endif
- } else {
- callType = UnknownFunction;
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Call at [@%lu, bc#%u] is has an unknown or ambiguous target.\n",
- m_graph.size(), m_currentIndex);
+ dataLog("For call at bc#", m_currentIndex, ": ", callLinkStatus, "\n");
#endif
+
+ if (!callLinkStatus.canOptimize()) {
+ // Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
+ // that we cannot optimize them.
+
+ addCall(interpreter, currentInstruction, op);
+ return;
}
- if (callType != UnknownFunction) {
- int argumentCountIncludingThis = currentInstruction[2].u.operand;
- int registerOffset = currentInstruction[3].u.operand;
-
- // Do we have a result?
- bool usesResult = false;
- int resultOperand = 0; // make compiler happy
- unsigned nextOffset = m_currentIndex + OPCODE_LENGTH(op_call);
- Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
- SpeculatedType prediction = SpecNone;
- if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) {
- resultOperand = putInstruction[1].u.operand;
- usesResult = true;
- m_currentProfilingIndex = nextOffset;
- prediction = getPrediction();
- nextOffset += OPCODE_LENGTH(op_call_put_result);
- }
-
- if (callType == ConstantInternalFunction) {
- if (handleConstantInternalFunction(usesResult, resultOperand, m_graph.valueOfInternalFunctionConstant(callTarget), registerOffset, argumentCountIncludingThis, prediction, kind))
- return;
-
- // Can only handle this using the generic call handler.
- addCall(interpreter, currentInstruction, op);
+
+ int argumentCountIncludingThis = currentInstruction[2].u.operand;
+ int registerOffset = currentInstruction[3].u.operand;
+
+ // Do we have a result?
+ bool usesResult = false;
+ int resultOperand = 0; // make compiler happy
+ unsigned nextOffset = m_currentIndex + OPCODE_LENGTH(op_call);
+ Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
+ SpeculatedType prediction = SpecNone;
+ if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result) {
+ resultOperand = putInstruction[1].u.operand;
+ usesResult = true;
+ m_currentProfilingIndex = nextOffset;
+ prediction = getPrediction();
+ nextOffset += OPCODE_LENGTH(op_call_put_result);
+ }
+
+ if (InternalFunction* function = callLinkStatus.internalFunction()) {
+ if (handleConstantInternalFunction(usesResult, resultOperand, function, registerOffset, argumentCountIncludingThis, prediction, kind)) {
+ // This phantoming has to be *after* the code for the intrinsic, to signify that
+ // the inputs must be kept alive whatever exits the intrinsic may do.
+ addToGraph(Phantom, callTarget);
+ emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, kind);
return;
}
- JSFunction* expectedFunction;
- Intrinsic intrinsic;
- bool certainAboutExpectedFunction;
- if (callType == ConstantFunction) {
- expectedFunction = m_graph.valueOfFunctionConstant(callTarget);
- intrinsic = expectedFunction->executable()->intrinsicFor(kind);
- certainAboutExpectedFunction = true;
- } else {
- ASSERT(callType == LinkedFunction);
- expectedFunction = callLinkStatus.callTarget();
- intrinsic = expectedFunction->executable()->intrinsicFor(kind);
- certainAboutExpectedFunction = false;
- }
-
- if (intrinsic != NoIntrinsic) {
- if (!certainAboutExpectedFunction)
- emitFunctionCheck(expectedFunction, callTarget, registerOffset, kind);
+ // Can only handle this using the generic call handler.
+ addCall(interpreter, currentInstruction, op);
+ return;
+ }
+
+ Intrinsic intrinsic = callLinkStatus.intrinsicFor(kind);
+ if (intrinsic != NoIntrinsic) {
+ emitFunctionChecks(callLinkStatus, callTarget, registerOffset, kind);
- if (handleIntrinsic(usesResult, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) {
- if (!certainAboutExpectedFunction) {
- // Need to keep the call target alive for OSR. We could easily optimize this out if we wanted
- // to, since at this point we know that the call target is a constant. It's just that OSR isn't
- // smart enough to figure that out, since it doesn't understand CheckFunction.
- addToGraph(Phantom, callTarget);
- }
-
- return;
- }
- } else if (handleInlining(usesResult, currentInstruction[1].u.operand, callTarget, resultOperand, certainAboutExpectedFunction, expectedFunction, registerOffset, argumentCountIncludingThis, nextOffset, kind))
+ if (handleIntrinsic(usesResult, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction)) {
+ // This phantoming has to be *after* the code for the intrinsic, to signify that
+ // the inputs must be kept alive whatever exits the intrinsic may do.
+ addToGraph(Phantom, callTarget);
+ emitArgumentPhantoms(registerOffset, argumentCountIncludingThis, kind);
+ if (m_graph.m_compilation)
+ m_graph.m_compilation->noticeInlinedCall();
return;
+ }
+ } else if (handleInlining(usesResult, callTarget, resultOperand, callLinkStatus, registerOffset, argumentCountIncludingThis, nextOffset, kind)) {
+ if (m_graph.m_compilation)
+ m_graph.m_compilation->noticeInlinedCall();
+ return;
}
addCall(interpreter, currentInstruction, op);
}
-void ByteCodeParser::emitFunctionCheck(JSFunction* expectedFunction, NodeIndex callTarget, int registerOffset, CodeSpecializationKind kind)
+void ByteCodeParser::emitFunctionChecks(const CallLinkStatus& callLinkStatus, Node* callTarget, int registerOffset, CodeSpecializationKind kind)
{
- NodeIndex thisArgument;
+ Node* thisArgument;
if (kind == CodeForCall)
thisArgument = get(registerOffset + argumentToOperand(0));
else
- thisArgument = NoNode;
- addToGraph(CheckFunction, OpInfo(expectedFunction), callTarget, thisArgument);
+ thisArgument = 0;
+
+ if (callLinkStatus.isProved()) {
+ addToGraph(Phantom, callTarget, thisArgument);
+ return;
+ }
+
+ ASSERT(callLinkStatus.canOptimize());
+
+ if (JSFunction* function = callLinkStatus.function())
+ addToGraph(CheckFunction, OpInfo(function), callTarget, thisArgument);
+ else {
+ ASSERT(callLinkStatus.structure());
+ ASSERT(callLinkStatus.executable());
+
+ addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(callLinkStatus.structure())), callTarget);
+ addToGraph(CheckExecutable, OpInfo(callLinkStatus.executable()), callTarget, thisArgument);
+ }
}
-bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex callTargetNodeIndex, int resultOperand, bool certainAboutExpectedFunction, JSFunction* expectedFunction, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind kind)
+void ByteCodeParser::emitArgumentPhantoms(int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind kind)
+{
+ for (int i = kind == CodeForCall ? 0 : 1; i < argumentCountIncludingThis; ++i)
+ addToGraph(Phantom, get(registerOffset + argumentToOperand(i)));
+}
+
+bool ByteCodeParser::handleInlining(bool usesResult, Node* callTargetNode, int resultOperand, const CallLinkStatus& callLinkStatus, int registerOffset, int argumentCountIncludingThis, unsigned nextOffset, CodeSpecializationKind kind)
{
// First, the really simple checks: do we have an actual JS function?
- if (!expectedFunction)
+ if (!callLinkStatus.executable())
return false;
- if (expectedFunction->isHostFunction())
+ if (callLinkStatus.executable()->isHostFunction())
return false;
- FunctionExecutable* executable = expectedFunction->jsExecutable();
+ FunctionExecutable* executable = jsCast<FunctionExecutable*>(callLinkStatus.executable());
// Does the number of arguments we're passing match the arity of the target? We currently
// inline only if the number of arguments passed is greater than or equal to the number
@@ -1426,26 +1280,18 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
return false; // Recursion detected.
}
- // Does the code block's size match the heuristics/requirements for being
- // an inline candidate?
- CodeBlock* profiledBlock = executable->profiledCodeBlockFor(kind);
- if (!profiledBlock)
- return false;
-
- if (!mightInlineFunctionFor(profiledBlock, kind))
- return false;
-
- // If we get here then it looks like we should definitely inline this code. Proceed
- // with parsing the code to get bytecode, so that we can then parse the bytecode.
- // Note that if LLInt is enabled, the bytecode will always be available. Also note
- // that if LLInt is enabled, we may inline a code block that has never been JITted
- // before!
- CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
+ // Do we have a code block, and does the code block's size match the heuristics/requirements for
+ // being an inline candidate? We might not have a code block if code was thrown away or if we
+ // simply hadn't actually made this call yet. We could still theoretically attempt to inline it
+ // if we had a static proof of what was being called; this might happen for example if you call a
+ // global function, where watchpointing gives us static information. Overall, it's a rare case
+ // because we expect that any hot callees would have already been compiled.
+ CodeBlock* codeBlock = executable->baselineCodeBlockFor(kind);
if (!codeBlock)
return false;
+ if (!canInlineFunctionFor(codeBlock, kind, callLinkStatus.isClosureCall()))
+ return false;
- ASSERT(canInlineFunctionFor(codeBlock, kind));
-
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLogF("Inlining executable %p.\n", executable);
#endif
@@ -1453,8 +1299,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
// Now we know without a doubt that we are committed to inlining. So begin the process
// by checking the callee (if necessary) and making sure that arguments and the callee
// are flushed.
- if (!certainAboutExpectedFunction)
- emitFunctionCheck(expectedFunction, callTargetNodeIndex, registerOffset, kind);
+ emitFunctionChecks(callLinkStatus, callTargetNode, registerOffset, kind);
// FIXME: Don't flush constants!
@@ -1475,9 +1320,8 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
size_t argumentPositionStart = m_graph.m_argumentPositions.size();
InlineStackEntry inlineStackEntry(
- this, codeBlock, profiledBlock, m_graph.m_blocks.size() - 1,
- (VirtualRegister)m_inlineStackTop->remapOperand(callTarget), expectedFunction,
- (VirtualRegister)m_inlineStackTop->remapOperand(
+ this, codeBlock, codeBlock, m_graph.m_blocks.size() - 1,
+ callLinkStatus.function(), (VirtualRegister)m_inlineStackTop->remapOperand(
usesResult ? resultOperand : InvalidVirtualRegister),
(VirtualRegister)inlineCallFrameStart, argumentCountIncludingThis, kind);
@@ -1488,6 +1332,10 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
m_currentProfilingIndex = 0;
addToGraph(InlineStart, OpInfo(argumentPositionStart));
+ if (callLinkStatus.isClosureCall()) {
+ addToGraph(SetCallee, callTargetNode);
+ addToGraph(SetMyScope, addToGraph(GetScope, callTargetNode));
+ }
parseCodeBlock();
@@ -1522,11 +1370,11 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
} else
ASSERT(inlineStackEntry.m_unlinkedBlocks.isEmpty());
+ BasicBlock* lastBlock = m_graph.m_blocks.last().get();
// If there was a return, but no early returns, then we're done. We allow parsing of
// the caller to continue in whatever basic block we're in right now.
if (!inlineStackEntry.m_didEarlyReturn && inlineStackEntry.m_didReturn) {
- BasicBlock* lastBlock = m_graph.m_blocks.last().get();
- ASSERT(lastBlock->isEmpty() || !m_graph.last().isTerminal());
+ ASSERT(lastBlock->isEmpty() || !lastBlock->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.
@@ -1550,7 +1398,7 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
}
// If we get to this point then all blocks must end in some sort of terminals.
- ASSERT(m_graph.last().isTerminal());
+ ASSERT(lastBlock->last()->isTerminal());
// Link the early returns to the basic block we're about to create.
for (size_t i = 0; i < inlineStackEntry.m_unlinkedBlocks.size(); ++i) {
@@ -1558,10 +1406,10 @@ 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->last()];
- ASSERT(node.op() == Jump);
- ASSERT(node.takenBlockIndex() == NoBlock);
- node.setTakenBlockIndex(m_graph.m_blocks.size());
+ Node* node = block->last();
+ ASSERT(node->op() == Jump);
+ ASSERT(node->takenBlockIndex() == NoBlock);
+ node->setTakenBlockIndex(m_graph.m_blocks.size());
inlineStackEntry.m_unlinkedBlocks[i].m_needsEarlyReturnLinking = false;
#if !ASSERT_DISABLED
block->isLinked = true;
@@ -1571,7 +1419,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_numArguments, m_numLocals));
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("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));
+ dataLogF("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(inlineCallFrame()));
#endif
m_currentBlock = block.get();
ASSERT(m_inlineStackTop->m_caller->m_blockLinkingTargets.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_caller->m_blockLinkingTargets.last()]->bytecodeBegin < nextOffset);
@@ -1588,11 +1436,11 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
return true;
}
-void ByteCodeParser::setIntrinsicResult(bool usesResult, int resultOperand, NodeIndex nodeIndex)
+void ByteCodeParser::setIntrinsicResult(bool usesResult, int resultOperand, Node* node)
{
if (!usesResult)
return;
- set(resultOperand, nodeIndex);
+ set(resultOperand, node);
}
bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType op, int registerOffset, int argumentCountIncludingThis)
@@ -1603,9 +1451,8 @@ bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType o
}
if (argumentCountIncludingThis == 2) { // Math.min(x)
- // FIXME: what we'd really like is a ValueToNumber, except we don't support that right now. Oh well.
- NodeIndex result = get(registerOffset + argumentToOperand(1));
- addToGraph(CheckNumber, result);
+ Node* result = get(registerOffset + argumentToOperand(1));
+ addToGraph(Phantom, Edge(result, NumberUse));
setIntrinsicResult(usesResult, resultOperand, result);
return true;
}
@@ -1633,10 +1480,10 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
if (!MacroAssembler::supportsFloatingPointAbs())
return false;
- NodeIndex nodeIndex = addToGraph(ArithAbs, get(registerOffset + argumentToOperand(1)));
+ Node* node = addToGraph(ArithAbs, get(registerOffset + argumentToOperand(1)));
if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
- m_graph[nodeIndex].mergeFlags(NodeMayOverflow);
- setIntrinsicResult(usesResult, resultOperand, nodeIndex);
+ node->mergeFlags(NodeMayOverflow);
+ setIntrinsicResult(usesResult, resultOperand, node);
return true;
}
@@ -1672,7 +1519,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
case Array::Double:
case Array::Contiguous:
case Array::ArrayStorage: {
- NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
+ Node* arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
if (usesResult)
set(resultOperand, arrayPush);
@@ -1696,7 +1543,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
case Array::Double:
case Array::Contiguous:
case Array::ArrayStorage: {
- NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0)));
+ Node* arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0)));
if (usesResult)
set(resultOperand, arrayPop);
return true;
@@ -1713,7 +1560,7 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
int thisOperand = registerOffset + argumentToOperand(0);
int indexOperand = registerOffset + argumentToOperand(1);
- NodeIndex charCode = addToGraph(StringCharCodeAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), getToInt32(indexOperand));
+ Node* charCode = addToGraph(StringCharCodeAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), getToInt32(indexOperand));
if (usesResult)
set(resultOperand, charCode);
@@ -1726,18 +1573,30 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
int thisOperand = registerOffset + argumentToOperand(0);
int indexOperand = registerOffset + argumentToOperand(1);
- NodeIndex charCode = addToGraph(StringCharAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), getToInt32(indexOperand));
+ Node* charCode = addToGraph(StringCharAt, OpInfo(ArrayMode(Array::String).asWord()), get(thisOperand), getToInt32(indexOperand));
if (usesResult)
set(resultOperand, charCode);
return true;
}
+ case FromCharCodeIntrinsic: {
+ if (argumentCountIncludingThis != 2)
+ return false;
+
+ int indexOperand = registerOffset + argumentToOperand(1);
+ Node* charCode = addToGraph(StringFromCharCode, getToInt32(indexOperand));
+
+ if (usesResult)
+ set(resultOperand, charCode);
+
+ return true;
+ }
case RegExpExecIntrinsic: {
if (argumentCountIncludingThis != 2)
return false;
- NodeIndex regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
+ Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
if (usesResult)
set(resultOperand, regExpExec);
@@ -1748,12 +1607,23 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
if (argumentCountIncludingThis != 2)
return false;
- NodeIndex regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
+ Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
if (usesResult)
set(resultOperand, regExpExec);
return true;
}
+
+ case IMulIntrinsic: {
+ if (argumentCountIncludingThis != 3)
+ return false;
+ int leftOperand = registerOffset + argumentToOperand(1);
+ int rightOperand = registerOffset + argumentToOperand(2);
+ Node* left = getToInt32(leftOperand);
+ Node* right = getToInt32(rightOperand);
+ setIntrinsicResult(usesResult, resultOperand, addToGraph(ArithIMul, left, right));
+ return true;
+ }
default:
return false;
@@ -1772,7 +1642,6 @@ bool ByteCodeParser::handleConstantInternalFunction(
// is good enough.
UNUSED_PARAM(prediction); // Remove this once we do more things.
- UNUSED_PARAM(kind); // Remove this once we do more things.
if (function->classInfo() == &ArrayConstructor::s_info) {
if (argumentCountIncludingThis == 2) {
@@ -1788,14 +1657,27 @@ bool ByteCodeParser::handleConstantInternalFunction(
usesResult, resultOperand,
addToGraph(Node::VarArg, NewArray, OpInfo(ArrayWithUndecided), OpInfo(0)));
return true;
+ } else if (function->classInfo() == &StringConstructor::s_info) {
+ Node* result;
+
+ if (argumentCountIncludingThis <= 1)
+ result = cellConstant(m_vm->smallStrings.emptyString());
+ else
+ result = addToGraph(ToString, get(registerOffset + argumentToOperand(1)));
+
+ if (kind == CodeForConstruct)
+ result = addToGraph(NewStringObject, OpInfo(function->globalObject()->stringObjectStructure()), result);
+
+ setIntrinsicResult(usesResult, resultOperand, result);
+ return true;
}
return false;
}
-NodeIndex ByteCodeParser::handleGetByOffset(SpeculatedType prediction, NodeIndex base, unsigned identifierNumber, PropertyOffset offset)
+Node* ByteCodeParser::handleGetByOffset(SpeculatedType prediction, Node* base, unsigned identifierNumber, PropertyOffset offset)
{
- NodeIndex propertyStorage;
+ Node* propertyStorage;
if (isInlineOffset(offset))
propertyStorage = base;
else
@@ -1804,7 +1686,7 @@ NodeIndex ByteCodeParser::handleGetByOffset(SpeculatedType prediction, NodeIndex
// an OSR standpoint) if GetByOffset also referenced the object we were loading
// from, and if we could load eliminate a GetByOffset even if the butterfly
// had changed. That would be a great success.
- NodeIndex getByOffset = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), propertyStorage);
+ Node* getByOffset = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), propertyStorage);
StorageAccessData storageAccessData;
storageAccessData.offset = indexRelativeToBase(offset);
@@ -1815,18 +1697,19 @@ NodeIndex ByteCodeParser::handleGetByOffset(SpeculatedType prediction, NodeIndex
}
void ByteCodeParser::handleGetByOffset(
- int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
+ int destinationOperand, SpeculatedType prediction, Node* base, unsigned identifierNumber,
PropertyOffset offset)
{
set(destinationOperand, handleGetByOffset(prediction, base, identifierNumber, offset));
}
void ByteCodeParser::handleGetById(
- int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
+ int destinationOperand, SpeculatedType prediction, Node* base, unsigned identifierNumber,
const GetByIdStatus& getByIdStatus)
{
if (!getByIdStatus.isSimple()
- || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache)) {
set(destinationOperand,
addToGraph(
getByIdStatus.makesCalls() ? GetByIdFlush : GetById,
@@ -1840,8 +1723,10 @@ void ByteCodeParser::handleGetById(
// execution if it doesn't have a prediction, so we do it manually.
if (prediction == SpecNone)
addToGraph(ForceOSRExit);
+ else if (m_graph.m_compilation)
+ m_graph.m_compilation->noticeInlinedGetById();
- NodeIndex originalBaseForBaselineJIT = base;
+ Node* originalBaseForBaselineJIT = base;
addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(getByIdStatus.structureSet())), base);
@@ -1882,19 +1767,36 @@ void ByteCodeParser::prepareToParseBlock()
m_cellConstantNodes.clear();
}
-bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned identifier, unsigned operations, unsigned putToBaseOperation, NodeIndex* base, NodeIndex* value)
+Node* ByteCodeParser::getScope(bool skipTop, unsigned skipCount)
+{
+ Node* localBase;
+ if (inlineCallFrame() && !inlineCallFrame()->isClosureCall()) {
+ ASSERT(inlineCallFrame()->callee);
+ localBase = cellConstant(inlineCallFrame()->callee->scope());
+ } else
+ localBase = addToGraph(GetMyScope);
+ if (skipTop) {
+ ASSERT(!inlineCallFrame());
+ localBase = addToGraph(SkipTopScope, localBase);
+ }
+ for (unsigned n = skipCount; n--;)
+ localBase = addToGraph(SkipScope, localBase);
+ return localBase;
+}
+
+bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned identifier, ResolveOperations* resolveOperations, PutToBaseOperation* putToBaseOperation, Node** base, Node** value)
{
- ResolveOperations* resolveOperations = m_codeBlock->resolveOperations(operations);
if (resolveOperations->isEmpty()) {
addToGraph(ForceOSRExit);
return false;
}
JSGlobalObject* globalObject = m_inlineStackTop->m_codeBlock->globalObject();
int skipCount = 0;
+ bool skipTop = false;
bool skippedScopes = false;
bool setBase = false;
ResolveOperation* pc = resolveOperations->data();
- NodeIndex localBase = 0;
+ Node* localBase = 0;
bool resolvingBase = true;
while (resolvingBase) {
switch (pc->m_operation) {
@@ -1918,7 +1820,7 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned
break;
case ResolveOperation::SetBaseToScope:
- localBase = addToGraph(GetScope, OpInfo(skipCount));
+ localBase = getScope(skipTop, skipCount);
*base = localBase;
setBase = true;
@@ -1929,21 +1831,18 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned
++pc;
break;
case ResolveOperation::ReturnScopeAsBase:
- *base = addToGraph(GetScope, OpInfo(skipCount));
+ *base = getScope(skipTop, skipCount);
ASSERT(!value);
return true;
case ResolveOperation::SkipTopScopeNode:
- if (m_inlineStackTop->m_inlineCallFrame)
- return false;
- skipCount = 1;
+ ASSERT(!inlineCallFrame());
+ skipTop = true;
skippedScopes = true;
++pc;
break;
case ResolveOperation::SkipScopes:
- if (m_inlineStackTop->m_inlineCallFrame)
- return false;
skipCount += pc->m_scopesToSkip;
skippedScopes = true;
++pc;
@@ -1960,7 +1859,7 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned
}
}
if (skippedScopes)
- localBase = addToGraph(GetScope, OpInfo(skipCount));
+ localBase = getScope(skipTop, skipCount);
if (base && !setBase)
*base = localBase;
@@ -1973,7 +1872,7 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned
if (status.isSimple()) {
ASSERT(status.structure());
- NodeIndex globalObjectNode = addStructureTransitionCheck(globalObject, status.structure());
+ Node* globalObjectNode = addStructureTransitionCheck(globalObject, status.structure());
if (status.specificValue()) {
ASSERT(status.specificValue().isCell());
@@ -1983,20 +1882,21 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned
return true;
}
- NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction));
+ Node* resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction));
m_graph.m_resolveGlobalData.append(ResolveGlobalData());
ResolveGlobalData& data = m_graph.m_resolveGlobalData.last();
data.identifierNumber = identifier;
- data.resolveOperationsIndex = operations;
- data.putToBaseOperationIndex = putToBaseOperation;
+ data.resolveOperations = resolveOperations;
+ data.putToBaseOperation = putToBaseOperation;
data.resolvePropertyIndex = resolveValueOperation - resolveOperations->data();
*value = resolve;
return true;
}
case ResolveOperation::GetAndReturnGlobalVar: {
- *value = addToGraph(GetGlobalVar,
- OpInfo(globalObject->assertRegisterIsInThisObject(pc->m_registerAddress)),
- OpInfo(prediction));
+ *value = addToGraph(
+ GetGlobalVar,
+ OpInfo(globalObject->assertRegisterIsInThisObject(pc->m_registerAddress)),
+ OpInfo(prediction));
return true;
}
case ResolveOperation::GetAndReturnGlobalVarWatchable: {
@@ -2035,7 +1935,7 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned
return true;
}
case ResolveOperation::GetAndReturnScopedVar: {
- NodeIndex getScopeRegisters = addToGraph(GetScopeRegisters, localBase);
+ Node* getScopeRegisters = addToGraph(GetScopeRegisters, localBase);
*value = addToGraph(GetScopedVar, OpInfo(resolveValueOperation->m_offset), OpInfo(prediction), getScopeRegisters);
return true;
}
@@ -2050,23 +1950,23 @@ bool ByteCodeParser::parseBlock(unsigned limit)
{
bool shouldContinueParsing = true;
- Interpreter* interpreter = m_globalData->interpreter;
+ Interpreter* interpreter = m_vm->interpreter;
Instruction* instructionsBegin = m_inlineStackTop->m_codeBlock->instructions().begin();
unsigned blockBegin = m_currentIndex;
// If we are the first basic block, introduce markers for arguments. This allows
// us to track if a use of an argument may use the actual argument passed, as
// opposed to using a value we set explicitly.
- if (m_currentBlock == m_graph.m_blocks[0].get() && !m_inlineStackTop->m_inlineCallFrame) {
+ if (m_currentBlock == m_graph.m_blocks[0].get() && !inlineCallFrame()) {
m_graph.m_arguments.resize(m_numArguments);
for (unsigned argument = 0; argument < m_numArguments; ++argument) {
VariableAccessData* variable = newVariableAccessData(
argumentToOperand(argument), m_codeBlock->isCaptured(argumentToOperand(argument)));
variable->mergeStructureCheckHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
- NodeIndex setArgument = addToGraph(SetArgument, OpInfo(variable));
+
+ Node* setArgument = addToGraph(SetArgument, OpInfo(variable));
m_graph.m_arguments[argument] = setArgument;
- m_currentBlock->variablesAtHead.setArgumentFirstTime(argument, setArgument);
m_currentBlock->variablesAtTail.setArgumentFirstTime(argument, setArgument);
}
}
@@ -2097,6 +1997,12 @@ bool ByteCodeParser::parseBlock(unsigned limit)
Instruction* currentInstruction = instructionsBegin + m_currentIndex;
m_currentInstruction = currentInstruction; // Some methods want to use this, and we'd rather not thread it through calls.
OpcodeID opcodeID = interpreter->getOpcodeID(currentInstruction->u.opcode);
+
+ if (m_graph.m_compilation && opcodeID != op_call_put_result) {
+ addToGraph(CountExecution, OpInfo(m_graph.m_compilation->executionCounterFor(
+ Profiler::OriginStack(*m_vm->m_perBytecodeProfiler, m_codeBlock, currentCodeOrigin()))));
+ }
+
switch (opcodeID) {
// === Function entry opcodes ===
@@ -2108,13 +2014,13 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_enter);
case op_convert_this: {
- NodeIndex op1 = getThis();
- if (m_graph[op1].op() != ConvertThis) {
+ Node* op1 = getThis();
+ if (op1->op() != ConvertThis) {
ValueProfile* profile =
m_inlineStackTop->m_profiledBlock->valueProfileForBytecodeOffset(m_currentProfilingIndex);
profile->computeUpdatedPrediction();
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("[@%lu bc#%u]: profile %p: ", m_graph.size(), m_currentProfilingIndex, profile);
+ dataLogF("[bc#%u]: profile %p: ", m_currentProfilingIndex, profile);
profile->dump(WTF::dataFile());
dataLogF("\n");
#endif
@@ -2135,27 +2041,33 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_create_this: {
int calleeOperand = currentInstruction[2].u.operand;
- NodeIndex callee = get(calleeOperand);
+ Node* callee = get(calleeOperand);
bool alreadyEmitted = false;
- if (m_graph[callee].op() == WeakJSConstant) {
- JSCell* cell = m_graph[callee].weakConstant();
+ if (callee->op() == WeakJSConstant) {
+ JSCell* cell = callee->weakConstant();
ASSERT(cell->inherits(&JSFunction::s_info));
JSFunction* function = jsCast<JSFunction*>(cell);
- Structure* inheritorID = function->tryGetKnownInheritorID();
- if (inheritorID) {
- addToGraph(InheritorIDWatchpoint, OpInfo(function));
- set(currentInstruction[1].u.operand, addToGraph(NewObject, OpInfo(inheritorID)));
+ ObjectAllocationProfile* allocationProfile = function->tryGetAllocationProfile();
+ if (allocationProfile) {
+ addToGraph(AllocationProfileWatchpoint, OpInfo(function));
+ // The callee is still live up to this point.
+ addToGraph(Phantom, callee);
+ set(currentInstruction[1].u.operand,
+ addToGraph(NewObject, OpInfo(allocationProfile->structure())));
alreadyEmitted = true;
}
}
if (!alreadyEmitted)
- set(currentInstruction[1].u.operand, addToGraph(CreateThis, callee));
+ set(currentInstruction[1].u.operand,
+ addToGraph(CreateThis, OpInfo(currentInstruction[3].u.operand), callee));
NEXT_OPCODE(op_create_this);
}
-
+
case op_new_object: {
- set(currentInstruction[1].u.operand, addToGraph(NewObject, OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->emptyObjectStructure())));
+ set(currentInstruction[1].u.operand,
+ addToGraph(NewObject,
+ OpInfo(currentInstruction[3].u.objectAllocationProfile->structure())));
NEXT_OPCODE(op_new_object);
}
@@ -2212,7 +2124,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
set(currentInstruction[1].u.operand, get(JSStack::Callee));
else {
ASSERT(profile->m_singletonValue.asCell()->inherits(&JSFunction::s_info));
- NodeIndex actualCallee = get(JSStack::Callee);
+ Node* actualCallee = get(JSStack::Callee);
addToGraph(CheckFunction, OpInfo(profile->m_singletonValue.asCell()), actualCallee);
set(currentInstruction[1].u.operand, addToGraph(WeakJSConstant, OpInfo(profile->m_singletonValue.asCell())));
}
@@ -2222,30 +2134,30 @@ bool ByteCodeParser::parseBlock(unsigned limit)
// === Bitwise operations ===
case op_bitand: {
- NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
- NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ Node* op1 = getToInt32(currentInstruction[2].u.operand);
+ Node* op2 = getToInt32(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2));
NEXT_OPCODE(op_bitand);
}
case op_bitor: {
- NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
- NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ Node* op1 = getToInt32(currentInstruction[2].u.operand);
+ Node* op2 = getToInt32(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2));
NEXT_OPCODE(op_bitor);
}
case op_bitxor: {
- NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
- NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
+ Node* op1 = getToInt32(currentInstruction[2].u.operand);
+ Node* op2 = getToInt32(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2));
NEXT_OPCODE(op_bitxor);
}
case op_rshift: {
- NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
- NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
- NodeIndex result;
+ Node* op1 = getToInt32(currentInstruction[2].u.operand);
+ Node* op2 = getToInt32(currentInstruction[3].u.operand);
+ Node* result;
// Optimize out shifts by zero.
if (isInt32Constant(op2) && !(valueOfInt32Constant(op2) & 0x1f))
result = op1;
@@ -2256,9 +2168,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_lshift: {
- NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
- NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
- NodeIndex result;
+ Node* op1 = getToInt32(currentInstruction[2].u.operand);
+ Node* op2 = getToInt32(currentInstruction[3].u.operand);
+ Node* result;
// Optimize out shifts by zero.
if (isInt32Constant(op2) && !(valueOfInt32Constant(op2) & 0x1f))
result = op1;
@@ -2269,9 +2181,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_urshift: {
- NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
- NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
- NodeIndex result;
+ Node* op1 = getToInt32(currentInstruction[2].u.operand);
+ Node* op2 = getToInt32(currentInstruction[3].u.operand);
+ Node* result;
// The result of a zero-extending right shift is treated as an unsigned value.
// This means that if the top bit is set, the result is not in the int32 range,
// and as such must be stored as a double. If the shift amount is a constant,
@@ -2297,43 +2209,26 @@ bool ByteCodeParser::parseBlock(unsigned limit)
// === Increment/Decrement opcodes ===
- case op_pre_inc: {
+ case op_inc: {
unsigned srcDst = currentInstruction[1].u.operand;
- NodeIndex op = get(srcDst);
+ Node* op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
- NEXT_OPCODE(op_pre_inc);
+ NEXT_OPCODE(op_inc);
}
- case op_post_inc: {
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
- ASSERT(result != srcDst); // Required for assumptions we make during OSR.
- NodeIndex op = get(srcDst);
- setPair(result, op, srcDst, makeSafe(addToGraph(ArithAdd, op, one())));
- NEXT_OPCODE(op_post_inc);
- }
-
- case op_pre_dec: {
+ case op_dec: {
unsigned srcDst = currentInstruction[1].u.operand;
- NodeIndex op = get(srcDst);
+ Node* op = get(srcDst);
set(srcDst, makeSafe(addToGraph(ArithSub, op, one())));
- NEXT_OPCODE(op_pre_dec);
- }
-
- case op_post_dec: {
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
- NodeIndex op = get(srcDst);
- setPair(result, op, srcDst, makeSafe(addToGraph(ArithSub, op, one())));
- NEXT_OPCODE(op_post_dec);
+ NEXT_OPCODE(op_dec);
}
// === Arithmetic operations ===
case op_add: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
- if (m_graph[op1].hasNumberResult() && m_graph[op2].hasNumberResult())
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (op1->hasNumberResult() && op2->hasNumberResult())
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, op1, op2)));
else
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ValueAdd, op1, op2)));
@@ -2341,36 +2236,36 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_sub: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, op1, op2)));
NEXT_OPCODE(op_sub);
}
case op_negate: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
+ Node* 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);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
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);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
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);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, makeDivSafe(addToGraph(ArithDiv, op1, op2)));
NEXT_OPCODE(op_div);
}
@@ -2383,7 +2278,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_debug);
#endif
case op_mov: {
- NodeIndex op = get(currentInstruction[2].u.operand);
+ Node* op = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, op);
NEXT_OPCODE(op_mov);
}
@@ -2393,56 +2288,56 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_check_has_instance);
case op_instanceof: {
- NodeIndex value = get(currentInstruction[2].u.operand);
- NodeIndex prototype = get(currentInstruction[3].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
+ Node* prototype = get(currentInstruction[3].u.operand);
set(currentInstruction[1].u.operand, addToGraph(InstanceOf, value, prototype));
NEXT_OPCODE(op_instanceof);
}
case op_is_undefined: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(IsUndefined, value));
NEXT_OPCODE(op_is_undefined);
}
case op_is_boolean: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(IsBoolean, value));
NEXT_OPCODE(op_is_boolean);
}
case op_is_number: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(IsNumber, value));
NEXT_OPCODE(op_is_number);
}
case op_is_string: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(IsString, value));
NEXT_OPCODE(op_is_string);
}
case op_is_object: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(IsObject, value));
NEXT_OPCODE(op_is_object);
}
case op_is_function: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(IsFunction, value));
NEXT_OPCODE(op_is_function);
}
case op_not: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(LogicalNot, value));
NEXT_OPCODE(op_not);
}
case op_to_primitive: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
set(currentInstruction[1].u.operand, addToGraph(ToPrimitive, value));
NEXT_OPCODE(op_to_primitive);
}
@@ -2450,77 +2345,182 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_strcat: {
int startOperand = currentInstruction[2].u.operand;
int numOperands = currentInstruction[3].u.operand;
- for (int operandIdx = startOperand; operandIdx < startOperand + numOperands; ++operandIdx)
- addVarArgChild(get(operandIdx));
- set(currentInstruction[1].u.operand, addToGraph(Node::VarArg, StrCat, OpInfo(0), OpInfo(0)));
+#if CPU(X86)
+ // X86 doesn't have enough registers to compile MakeRope with three arguments.
+ // Rather than try to be clever, we just make MakeRope dumber on this processor.
+ const unsigned maxRopeArguments = 2;
+#else
+ const unsigned maxRopeArguments = 3;
+#endif
+ OwnArrayPtr<Node*> toStringNodes = adoptArrayPtr(new Node*[numOperands]);
+ for (int i = 0; i < numOperands; i++)
+ toStringNodes[i] = addToGraph(ToString, get(startOperand + i));
+
+ for (int i = 0; i < numOperands; i++)
+ addToGraph(Phantom, toStringNodes[i]);
+
+ Node* operands[AdjacencyList::Size];
+ unsigned indexInOperands = 0;
+ for (unsigned i = 0; i < AdjacencyList::Size; ++i)
+ operands[i] = 0;
+ for (int operandIdx = 0; operandIdx < numOperands; ++operandIdx) {
+ if (indexInOperands == maxRopeArguments) {
+ operands[0] = addToGraph(MakeRope, operands[0], operands[1], operands[2]);
+ for (unsigned i = 1; i < AdjacencyList::Size; ++i)
+ operands[i] = 0;
+ indexInOperands = 1;
+ }
+
+ ASSERT(indexInOperands < AdjacencyList::Size);
+ ASSERT(indexInOperands < maxRopeArguments);
+ operands[indexInOperands++] = toStringNodes[operandIdx];
+ }
+ set(currentInstruction[1].u.operand,
+ addToGraph(MakeRope, operands[0], operands[1], operands[2]));
NEXT_OPCODE(op_strcat);
}
case op_less: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ if (a.isNumber() && b.isNumber()) {
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(a.asNumber() < b.asNumber())));
+ NEXT_OPCODE(op_less);
+ }
+ }
set(currentInstruction[1].u.operand, addToGraph(CompareLess, op1, op2));
NEXT_OPCODE(op_less);
}
case op_lesseq: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ if (a.isNumber() && b.isNumber()) {
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(a.asNumber() <= b.asNumber())));
+ NEXT_OPCODE(op_lesseq);
+ }
+ }
set(currentInstruction[1].u.operand, addToGraph(CompareLessEq, op1, op2));
NEXT_OPCODE(op_lesseq);
}
case op_greater: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ if (a.isNumber() && b.isNumber()) {
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(a.asNumber() > b.asNumber())));
+ NEXT_OPCODE(op_greater);
+ }
+ }
set(currentInstruction[1].u.operand, addToGraph(CompareGreater, op1, op2));
NEXT_OPCODE(op_greater);
}
case op_greatereq: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ if (a.isNumber() && b.isNumber()) {
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(a.asNumber() >= b.asNumber())));
+ NEXT_OPCODE(op_greatereq);
+ }
+ }
set(currentInstruction[1].u.operand, addToGraph(CompareGreaterEq, op1, op2));
NEXT_OPCODE(op_greatereq);
}
case op_eq: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(JSValue::equal(m_codeBlock->globalObject()->globalExec(), a, b))));
+ NEXT_OPCODE(op_eq);
+ }
set(currentInstruction[1].u.operand, addToGraph(CompareEq, op1, op2));
NEXT_OPCODE(op_eq);
}
case op_eq_null: {
- NodeIndex value = get(currentInstruction[2].u.operand);
- set(currentInstruction[1].u.operand, addToGraph(CompareEq, value, constantNull()));
+ Node* value = get(currentInstruction[2].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(CompareEqConstant, value, constantNull()));
NEXT_OPCODE(op_eq_null);
}
case op_stricteq: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
- set(currentInstruction[1].u.operand, addToGraph(CompareStrictEq, op1, op2));
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(JSValue::strictEqual(m_codeBlock->globalObject()->globalExec(), a, b))));
+ NEXT_OPCODE(op_stricteq);
+ }
+ if (isConstantForCompareStrictEq(op1))
+ set(currentInstruction[1].u.operand, addToGraph(CompareStrictEqConstant, op2, op1));
+ else if (isConstantForCompareStrictEq(op2))
+ set(currentInstruction[1].u.operand, addToGraph(CompareStrictEqConstant, op1, op2));
+ else
+ set(currentInstruction[1].u.operand, addToGraph(CompareStrictEq, op1, op2));
NEXT_OPCODE(op_stricteq);
}
case op_neq: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(!JSValue::equal(m_codeBlock->globalObject()->globalExec(), a, b))));
+ NEXT_OPCODE(op_neq);
+ }
set(currentInstruction[1].u.operand, addToGraph(LogicalNot, addToGraph(CompareEq, op1, op2)));
NEXT_OPCODE(op_neq);
}
case op_neq_null: {
- NodeIndex value = get(currentInstruction[2].u.operand);
- set(currentInstruction[1].u.operand, addToGraph(LogicalNot, addToGraph(CompareEq, value, constantNull())));
+ Node* value = get(currentInstruction[2].u.operand);
+ set(currentInstruction[1].u.operand, addToGraph(LogicalNot, addToGraph(CompareEqConstant, value, constantNull())));
NEXT_OPCODE(op_neq_null);
}
case op_nstricteq: {
- NodeIndex op1 = get(currentInstruction[2].u.operand);
- NodeIndex op2 = get(currentInstruction[3].u.operand);
- set(currentInstruction[1].u.operand, addToGraph(LogicalNot, addToGraph(CompareStrictEq, op1, op2)));
+ Node* op1 = get(currentInstruction[2].u.operand);
+ Node* op2 = get(currentInstruction[3].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue a = valueOfJSConstant(op1);
+ JSValue b = valueOfJSConstant(op2);
+ set(currentInstruction[1].u.operand,
+ getJSConstantForValue(jsBoolean(!JSValue::strictEqual(m_codeBlock->globalObject()->globalExec(), a, b))));
+ NEXT_OPCODE(op_nstricteq);
+ }
+ Node* invertedResult;
+ if (isConstantForCompareStrictEq(op1))
+ invertedResult = addToGraph(CompareStrictEqConstant, op2, op1);
+ else if (isConstantForCompareStrictEq(op2))
+ invertedResult = addToGraph(CompareStrictEqConstant, op1, op2);
+ else
+ invertedResult = addToGraph(CompareStrictEq, op1, op2);
+ set(currentInstruction[1].u.operand, addToGraph(LogicalNot, invertedResult));
NEXT_OPCODE(op_nstricteq);
}
@@ -2529,27 +2529,27 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_get_by_val: {
SpeculatedType prediction = getPrediction();
- NodeIndex base = get(currentInstruction[2].u.operand);
+ Node* base = get(currentInstruction[2].u.operand);
ArrayMode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Read, base);
- NodeIndex property = get(currentInstruction[3].u.operand);
- NodeIndex getByVal = addToGraph(GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction), base, property);
+ Node* property = get(currentInstruction[3].u.operand);
+ Node* getByVal = addToGraph(GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction), base, property);
set(currentInstruction[1].u.operand, getByVal);
NEXT_OPCODE(op_get_by_val);
}
case op_put_by_val: {
- NodeIndex base = get(currentInstruction[1].u.operand);
+ Node* base = get(currentInstruction[1].u.operand);
ArrayMode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Write, base);
- NodeIndex property = get(currentInstruction[2].u.operand);
- NodeIndex value = get(currentInstruction[3].u.operand);
+ Node* property = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[3].u.operand);
addVarArgChild(base);
addVarArgChild(property);
addVarArgChild(value);
- addVarArgChild(NoNode); // Leave room for property storage.
+ addVarArgChild(0); // Leave room for property storage.
addToGraph(Node::VarArg, PutByVal, OpInfo(arrayMode.asWord()), OpInfo(0));
NEXT_OPCODE(op_put_by_val);
@@ -2560,7 +2560,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_get_array_length: {
SpeculatedType prediction = getPrediction();
- NodeIndex base = get(currentInstruction[2].u.operand);
+ Node* base = get(currentInstruction[2].u.operand);
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
Identifier identifier = m_codeBlock->identifier(identifierNumber);
@@ -2578,8 +2578,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_put_by_id_transition_normal:
case op_put_by_id_transition_direct_out_of_line:
case op_put_by_id_transition_normal_out_of_line: {
- NodeIndex value = get(currentInstruction[3].u.operand);
- NodeIndex base = get(currentInstruction[1].u.operand);
+ Node* value = get(currentInstruction[3].u.operand);
+ Node* base = get(currentInstruction[1].u.operand);
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
bool direct = currentInstruction[8].u.operand;
@@ -2587,14 +2587,19 @@ bool ByteCodeParser::parseBlock(unsigned limit)
m_inlineStackTop->m_profiledBlock,
m_currentIndex,
m_codeBlock->identifier(identifierNumber));
- if (!putByIdStatus.isSet())
+ bool canCountAsInlined = true;
+ if (!putByIdStatus.isSet()) {
addToGraph(ForceOSRExit);
+ canCountAsInlined = false;
+ }
- bool hasExitSite = m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache);
+ bool hasExitSite =
+ m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache);
if (!hasExitSite && putByIdStatus.isSimpleReplace()) {
addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(putByIdStatus.oldStructure())), base);
- NodeIndex propertyStorage;
+ Node* propertyStorage;
if (isInlineOffset(putByIdStatus.offset()))
propertyStorage = base;
else
@@ -2629,7 +2634,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
ASSERT(putByIdStatus.oldStructure()->transitionWatchpointSetHasBeenInvalidated());
- NodeIndex propertyStorage;
+ Node* propertyStorage;
StructureTransitionData* transitionData =
m_graph.addStructureTransitionData(
StructureTransitionData(
@@ -2676,7 +2681,11 @@ bool ByteCodeParser::parseBlock(unsigned limit)
addToGraph(PutByIdDirect, OpInfo(identifierNumber), base, value);
else
addToGraph(PutById, OpInfo(identifierNumber), base, value);
+ canCountAsInlined = false;
}
+
+ if (canCountAsInlined && m_graph.m_compilation)
+ m_graph.m_compilation->noticeInlinedPutById();
NEXT_OPCODE(op_put_by_id);
}
@@ -2686,7 +2695,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_init_global_const: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
addToGraph(
PutGlobalVar,
OpInfo(m_inlineStackTop->m_codeBlock->globalObject()->assertRegisterIsInThisObject(currentInstruction[1].u.registerPointer)),
@@ -2695,7 +2704,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_init_global_const_check: {
- NodeIndex value = get(currentInstruction[2].u.operand);
+ Node* value = get(currentInstruction[2].u.operand);
CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
JSGlobalObject* globalObject = codeBlock->globalObject();
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[4].u.operand];
@@ -2725,167 +2734,271 @@ bool ByteCodeParser::parseBlock(unsigned limit)
LAST_OPCODE(op_jmp);
}
- case op_loop: {
- unsigned relativeOffset = currentInstruction[1].u.operand;
- addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
- LAST_OPCODE(op_loop);
- }
-
case op_jtrue: {
unsigned relativeOffset = currentInstruction[2].u.operand;
- NodeIndex condition = get(currentInstruction[1].u.operand);
+ Node* condition = get(currentInstruction[1].u.operand);
+ if (canFold(condition)) {
+ TriState state = valueOfJSConstant(condition).pureToBoolean();
+ if (state == TrueTriState) {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jtrue);
+ } else if (state == FalseTriState) {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jtrue);
+ }
+ }
addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jtrue)), condition);
LAST_OPCODE(op_jtrue);
}
case op_jfalse: {
unsigned relativeOffset = currentInstruction[2].u.operand;
- NodeIndex condition = get(currentInstruction[1].u.operand);
+ Node* condition = get(currentInstruction[1].u.operand);
+ if (canFold(condition)) {
+ TriState state = valueOfJSConstant(condition).pureToBoolean();
+ if (state == FalseTriState) {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jfalse);
+ } else if (state == TrueTriState) {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jfalse);
+ }
+ }
addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jfalse)), OpInfo(m_currentIndex + relativeOffset), condition);
LAST_OPCODE(op_jfalse);
}
- case op_loop_if_true: {
- unsigned relativeOffset = currentInstruction[2].u.operand;
- NodeIndex condition = get(currentInstruction[1].u.operand);
- addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_true)), condition);
- LAST_OPCODE(op_loop_if_true);
- }
-
- case op_loop_if_false: {
- unsigned relativeOffset = currentInstruction[2].u.operand;
- NodeIndex condition = get(currentInstruction[1].u.operand);
- addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_false)), OpInfo(m_currentIndex + relativeOffset), condition);
- LAST_OPCODE(op_loop_if_false);
- }
-
case op_jeq_null: {
unsigned relativeOffset = currentInstruction[2].u.operand;
- NodeIndex value = get(currentInstruction[1].u.operand);
- NodeIndex condition = addToGraph(CompareEq, value, constantNull());
+ Node* value = get(currentInstruction[1].u.operand);
+ Node* condition = addToGraph(CompareEqConstant, value, constantNull());
addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jeq_null)), condition);
LAST_OPCODE(op_jeq_null);
}
case op_jneq_null: {
unsigned relativeOffset = currentInstruction[2].u.operand;
- NodeIndex value = get(currentInstruction[1].u.operand);
- NodeIndex condition = addToGraph(CompareEq, value, constantNull());
+ Node* value = get(currentInstruction[1].u.operand);
+ Node* condition = addToGraph(CompareEqConstant, value, constantNull());
addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_null)), OpInfo(m_currentIndex + relativeOffset), condition);
LAST_OPCODE(op_jneq_null);
}
case op_jless: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareLess, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a < b) {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jless);
+ } else {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jless);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareLess, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jless)), condition);
LAST_OPCODE(op_jless);
}
case op_jlesseq: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareLessEq, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a <= b) {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jlesseq);
+ } else {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jlesseq);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareLessEq, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jlesseq)), condition);
LAST_OPCODE(op_jlesseq);
}
case op_jgreater: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareGreater, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a > b) {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jgreater);
+ } else {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jgreater);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareGreater, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jgreater)), condition);
LAST_OPCODE(op_jgreater);
}
case op_jgreatereq: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareGreaterEq, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a >= b) {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jgreatereq);
+ } else {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jgreatereq);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareGreaterEq, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_jgreatereq)), condition);
LAST_OPCODE(op_jgreatereq);
}
case op_jnless: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareLess, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a < b) {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jnless);
+ } else {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jnless);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareLess, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jnless)), OpInfo(m_currentIndex + relativeOffset), condition);
LAST_OPCODE(op_jnless);
}
case op_jnlesseq: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareLessEq, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a <= b) {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jnlesseq);
+ } else {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jnlesseq);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareLessEq, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jnlesseq)), OpInfo(m_currentIndex + relativeOffset), condition);
LAST_OPCODE(op_jnlesseq);
}
case op_jngreater: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareGreater, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a > b) {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jngreater);
+ } else {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jngreater);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareGreater, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jngreater)), OpInfo(m_currentIndex + relativeOffset), condition);
LAST_OPCODE(op_jngreater);
}
case op_jngreatereq: {
unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareGreaterEq, op1, op2);
+ Node* op1 = get(currentInstruction[1].u.operand);
+ Node* op2 = get(currentInstruction[2].u.operand);
+ if (canFold(op1) && canFold(op2)) {
+ JSValue aValue = valueOfJSConstant(op1);
+ JSValue bValue = valueOfJSConstant(op2);
+ if (aValue.isNumber() && bValue.isNumber()) {
+ double a = aValue.asNumber();
+ double b = bValue.asNumber();
+ if (a >= b) {
+ // Emit a placeholder for this bytecode operation but otherwise
+ // just fall through.
+ addToGraph(Phantom);
+ NEXT_OPCODE(op_jngreatereq);
+ } else {
+ addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
+ LAST_OPCODE(op_jngreatereq);
+ }
+ }
+ }
+ Node* condition = addToGraph(CompareGreaterEq, op1, op2);
addToGraph(Branch, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jngreatereq)), OpInfo(m_currentIndex + relativeOffset), condition);
LAST_OPCODE(op_jngreatereq);
}
- case op_loop_if_less: {
- unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareLess, op1, op2);
- addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_less)), condition);
- LAST_OPCODE(op_loop_if_less);
- }
-
- case op_loop_if_lesseq: {
- unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareLessEq, op1, op2);
- addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_lesseq)), condition);
- LAST_OPCODE(op_loop_if_lesseq);
- }
-
- case op_loop_if_greater: {
- unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareGreater, op1, op2);
- addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_greater)), condition);
- LAST_OPCODE(op_loop_if_greater);
- }
-
- case op_loop_if_greatereq: {
- unsigned relativeOffset = currentInstruction[3].u.operand;
- NodeIndex op1 = get(currentInstruction[1].u.operand);
- NodeIndex op2 = get(currentInstruction[2].u.operand);
- NodeIndex condition = addToGraph(CompareGreaterEq, op1, op2);
- addToGraph(Branch, OpInfo(m_currentIndex + relativeOffset), OpInfo(m_currentIndex + OPCODE_LENGTH(op_loop_if_greatereq)), condition);
- LAST_OPCODE(op_loop_if_greatereq);
- }
-
case op_ret:
flushArgumentsAndCapturedVariables();
- if (m_inlineStackTop->m_inlineCallFrame) {
+ if (inlineCallFrame()) {
if (m_inlineStackTop->m_returnValue != InvalidVirtualRegister)
setDirect(m_inlineStackTop->m_returnValue, get(currentInstruction[1].u.operand));
m_inlineStackTop->m_didReturn = true;
@@ -2913,17 +3026,17 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_end:
flushArgumentsAndCapturedVariables();
- ASSERT(!m_inlineStackTop->m_inlineCallFrame);
+ ASSERT(!inlineCallFrame());
addToGraph(Return, get(currentInstruction[1].u.operand));
LAST_OPCODE(op_end);
case op_throw:
- flushArgumentsAndCapturedVariables();
+ flushAllArgumentsAndCapturedVariablesInInlineStack();
addToGraph(Throw, get(currentInstruction[1].u.operand));
LAST_OPCODE(op_throw);
case op_throw_static_error:
- flushArgumentsAndCapturedVariables();
+ flushAllArgumentsAndCapturedVariablesInInlineStack();
addToGraph(ThrowReferenceError);
LAST_OPCODE(op_throw_static_error);
@@ -2936,7 +3049,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_construct);
case op_call_varargs: {
- ASSERT(m_inlineStackTop->m_inlineCallFrame);
+ ASSERT(inlineCallFrame());
ASSERT(currentInstruction[3].u.operand == m_inlineStackTop->m_codeBlock->argumentsRegister());
ASSERT(!m_inlineStackTop->m_codeBlock->symbolTable()->slowArguments());
// It would be cool to funnel this into handleCall() so that it can handle
@@ -2954,7 +3067,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
addToGraph(CheckArgumentsNotCreated);
- unsigned argCount = m_inlineStackTop->m_inlineCallFrame->arguments.size();
+ unsigned argCount = inlineCallFrame()->arguments.size();
if (JSStack::CallFrameHeaderSize + argCount > m_parameterSlots)
m_parameterSlots = JSStack::CallFrameHeaderSize + argCount;
@@ -2963,7 +3076,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
for (unsigned argument = 1; argument < argCount; ++argument)
addVarArgChild(get(argumentToOperand(argument)));
- NodeIndex call = addToGraph(Node::VarArg, Call, OpInfo(0), OpInfo(prediction));
+ Node* call = addToGraph(Node::VarArg, Call, OpInfo(0), OpInfo(prediction));
if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
set(putInstruction[1].u.operand, call);
@@ -2985,6 +3098,32 @@ bool ByteCodeParser::parseBlock(unsigned limit)
addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr)));
LAST_OPCODE(op_jneq_ptr);
+ case op_get_scoped_var: {
+ SpeculatedType prediction = getPrediction();
+ int dst = currentInstruction[1].u.operand;
+ int slot = currentInstruction[2].u.operand;
+ int depth = currentInstruction[3].u.operand;
+ bool hasTopScope = m_codeBlock->codeType() == FunctionCode && m_inlineStackTop->m_codeBlock->needsFullScopeChain();
+ ASSERT(!hasTopScope || depth >= 1);
+ Node* scope = getScope(hasTopScope, depth - hasTopScope);
+ Node* getScopeRegisters = addToGraph(GetScopeRegisters, scope);
+ Node* getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo(prediction), getScopeRegisters);
+ set(dst, getScopedVar);
+ NEXT_OPCODE(op_get_scoped_var);
+ }
+
+ case op_put_scoped_var: {
+ int slot = currentInstruction[1].u.operand;
+ int depth = currentInstruction[2].u.operand;
+ int source = currentInstruction[3].u.operand;
+ bool hasTopScope = m_codeBlock->codeType() == FunctionCode && m_inlineStackTop->m_codeBlock->needsFullScopeChain();
+ ASSERT(!hasTopScope || depth >= 1);
+ Node* scope = getScope(hasTopScope, depth - hasTopScope);
+ Node* scopeRegisters = addToGraph(GetScopeRegisters, scope);
+ addToGraph(PutScopedVar, OpInfo(slot), scope, scopeRegisters, get(source));
+ NEXT_OPCODE(op_put_scoped_var);
+ }
+
case op_resolve:
case op_resolve_global_property:
case op_resolve_global_var:
@@ -2994,18 +3133,18 @@ bool ByteCodeParser::parseBlock(unsigned limit)
SpeculatedType prediction = getPrediction();
unsigned identifier = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
- unsigned operations = m_inlineStackTop->m_resolveOperationRemap[currentInstruction[3].u.operand];
- NodeIndex value = 0;
+ ResolveOperations* operations = currentInstruction[3].u.resolveOperations;
+ Node* value = 0;
if (parseResolveOperations(prediction, identifier, operations, 0, 0, &value)) {
set(currentInstruction[1].u.operand, value);
NEXT_OPCODE(op_resolve);
}
- NodeIndex resolve = addToGraph(Resolve, OpInfo(m_graph.m_resolveOperationsData.size()), OpInfo(prediction));
+ Node* resolve = addToGraph(Resolve, OpInfo(m_graph.m_resolveOperationsData.size()), OpInfo(prediction));
m_graph.m_resolveOperationsData.append(ResolveOperationData());
ResolveOperationData& data = m_graph.m_resolveOperationsData.last();
data.identifierNumber = identifier;
- data.resolveOperationsIndex = operations;
+ data.resolveOperations = operations;
set(currentInstruction[1].u.operand, resolve);
@@ -3017,19 +3156,18 @@ bool ByteCodeParser::parseBlock(unsigned limit)
unsigned base = currentInstruction[1].u.operand;
unsigned identifier = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
unsigned value = currentInstruction[3].u.operand;
- unsigned operation = m_inlineStackTop->m_putToBaseOperationRemap[currentInstruction[4].u.operand];
- PutToBaseOperation* putToBase = m_codeBlock->putToBaseOperation(operation);
+ PutToBaseOperation* putToBase = currentInstruction[4].u.putToBaseOperation;
if (putToBase->m_isDynamic) {
- addToGraph(Phantom, get(base));
addToGraph(PutById, OpInfo(identifier), get(base), get(value));
NEXT_OPCODE(op_put_to_base);
}
switch (putToBase->m_kind) {
case PutToBaseOperation::Uninitialised:
- addToGraph(Phantom, get(base));
addToGraph(ForceOSRExit);
+ addToGraph(Phantom, get(base));
+ addToGraph(Phantom, get(value));
break;
case PutToBaseOperation::GlobalVariablePutChecked: {
@@ -3050,21 +3188,21 @@ bool ByteCodeParser::parseBlock(unsigned limit)
get(value));
break;
case PutToBaseOperation::VariablePut: {
- addToGraph(Phantom, get(base));
- NodeIndex getScope = addToGraph(GetScope, OpInfo(putToBase->m_scopeDepth));
- NodeIndex getScopeRegisters = addToGraph(GetScopeRegisters, getScope);
- addToGraph(PutScopedVar, OpInfo(putToBase->m_offset), getScope, getScopeRegisters, get(value));
+ Node* scope = get(base);
+ Node* scopeRegisters = addToGraph(GetScopeRegisters, scope);
+ addToGraph(PutScopedVar, OpInfo(putToBase->m_offset), scope, scopeRegisters, get(value));
break;
}
case PutToBaseOperation::GlobalPropertyPut: {
if (!putToBase->m_structure) {
- addToGraph(Phantom, get(base));
addToGraph(ForceOSRExit);
+ addToGraph(Phantom, get(base));
+ addToGraph(Phantom, get(value));
NEXT_OPCODE(op_put_to_base);
}
- NodeIndex baseNode = get(base);
+ Node* baseNode = get(base);
addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(putToBase->m_structure.get())), baseNode);
- NodeIndex propertyStorage;
+ Node* propertyStorage;
if (isInlineOffset(putToBase->m_offset))
propertyStorage = baseNode;
else
@@ -3079,7 +3217,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case PutToBaseOperation::Readonly:
case PutToBaseOperation::Generic:
- addToGraph(Phantom, get(base));
addToGraph(PutById, OpInfo(identifier), get(base), get(value));
}
NEXT_OPCODE(op_put_to_base);
@@ -3093,21 +3230,21 @@ bool ByteCodeParser::parseBlock(unsigned limit)
SpeculatedType prediction = getPrediction();
unsigned identifier = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
- unsigned operations = m_inlineStackTop->m_resolveOperationRemap[currentInstruction[4].u.operand];
- unsigned putToBaseOperation = m_inlineStackTop->m_putToBaseOperationRemap[currentInstruction[5].u.operand];
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
+ PutToBaseOperation* putToBaseOperation = currentInstruction[5].u.putToBaseOperation;
- NodeIndex base = 0;
+ Node* base = 0;
if (parseResolveOperations(prediction, identifier, operations, 0, &base, 0)) {
set(currentInstruction[1].u.operand, base);
NEXT_OPCODE(op_resolve_base);
}
- NodeIndex resolve = addToGraph(currentInstruction[3].u.operand ? ResolveBaseStrictPut : ResolveBase, OpInfo(m_graph.m_resolveOperationsData.size()), OpInfo(prediction));
+ Node* resolve = addToGraph(currentInstruction[3].u.operand ? ResolveBaseStrictPut : ResolveBase, OpInfo(m_graph.m_resolveOperationsData.size()), OpInfo(prediction));
m_graph.m_resolveOperationsData.append(ResolveOperationData());
ResolveOperationData& data = m_graph.m_resolveOperationsData.last();
data.identifierNumber = identifier;
- data.resolveOperationsIndex = operations;
- data.putToBaseOperationIndex = putToBaseOperation;
+ data.resolveOperations = operations;
+ data.putToBaseOperation = putToBaseOperation;
set(currentInstruction[1].u.operand, resolve);
@@ -3118,11 +3255,11 @@ bool ByteCodeParser::parseBlock(unsigned limit)
unsigned baseDst = currentInstruction[1].u.operand;
unsigned valueDst = currentInstruction[2].u.operand;
unsigned identifier = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
- unsigned operations = m_inlineStackTop->m_resolveOperationRemap[currentInstruction[4].u.operand];
- unsigned putToBaseOperation = m_inlineStackTop->m_putToBaseOperationRemap[currentInstruction[5].u.operand];
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
+ PutToBaseOperation* putToBaseOperation = currentInstruction[5].u.putToBaseOperation;
- NodeIndex base = 0;
- NodeIndex value = 0;
+ Node* base = 0;
+ Node* value = 0;
if (parseResolveOperations(prediction, identifier, operations, putToBaseOperation, &base, &value))
setPair(baseDst, base, valueDst, value);
else {
@@ -3137,10 +3274,10 @@ bool ByteCodeParser::parseBlock(unsigned limit)
unsigned baseDst = currentInstruction[1].u.operand;
unsigned valueDst = currentInstruction[2].u.operand;
unsigned identifier = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
- unsigned operations = m_inlineStackTop->m_resolveOperationRemap[currentInstruction[4].u.operand];
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
- NodeIndex base = 0;
- NodeIndex value = 0;
+ Node* base = 0;
+ Node* value = 0;
if (parseResolveOperations(prediction, identifier, operations, 0, &base, &value))
setPair(baseDst, base, valueDst, value);
else {
@@ -3154,7 +3291,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
// Baseline->DFG OSR jumps between loop hints. The DFG assumes that Baseline->DFG
// OSR can only happen at basic block boundaries. Assert that these two statements
// are compatible.
- ASSERT_UNUSED(blockBegin, m_currentIndex == blockBegin);
+ RELEASE_ASSERT(m_currentIndex == blockBegin);
// We never do OSR into an inlined code block. That could not happen, since OSR
// looks up the code block that is the replacement for the baseline JIT code
@@ -3162,9 +3299,13 @@ bool ByteCodeParser::parseBlock(unsigned limit)
if (!m_inlineStackTop->m_caller)
m_currentBlock->isOSRTarget = true;
- // Emit a phantom node to ensure that there is a placeholder node for this bytecode
- // op.
- addToGraph(Phantom);
+ if (m_vm->watchdog.isEnabled())
+ addToGraph(CheckWatchdogTimer);
+ else {
+ // Emit a phantom node to ensure that there is a placeholder
+ // node for this bytecode op.
+ addToGraph(Phantom);
+ }
NEXT_OPCODE(op_loop_hint);
}
@@ -3181,7 +3322,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_create_arguments: {
m_graph.m_hasArguments = true;
- NodeIndex createArguments = addToGraph(CreateArguments, get(currentInstruction[1].u.operand));
+ Node* createArguments = addToGraph(CreateArguments, get(currentInstruction[1].u.operand));
set(currentInstruction[1].u.operand, createArguments);
set(unmodifiedArgumentsRegister(currentInstruction[1].u.operand), createArguments);
NEXT_OPCODE(op_create_arguments);
@@ -3233,195 +3374,47 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NEXT_OPCODE(op_new_func_exp);
}
+ case op_typeof: {
+ set(currentInstruction[1].u.operand,
+ addToGraph(TypeOf, get(currentInstruction[2].u.operand)));
+ NEXT_OPCODE(op_typeof);
+ }
+
+ case op_to_number: {
+ set(currentInstruction[1].u.operand,
+ addToGraph(Identity, Edge(get(currentInstruction[2].u.operand), NumberUse)));
+ NEXT_OPCODE(op_to_number);
+ }
+
default:
// Parse failed! This should not happen because the capabilities checker
// should have caught it.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
}
-template<ByteCodeParser::PhiStackType stackType>
-void ByteCodeParser::processPhiStack()
-{
- Vector<PhiStackEntry, 16>& phiStack = (stackType == ArgumentPhiStack) ? m_argumentPhiStack : m_localPhiStack;
-
- while (!phiStack.isEmpty()) {
- PhiStackEntry entry = phiStack.last();
- phiStack.removeLast();
-
- if (!entry.m_block->isReachable)
- continue;
-
- if (!entry.m_block->isReachable)
- continue;
-
- PredecessorList& predecessors = entry.m_block->m_predecessors;
- unsigned varNo = entry.m_varNo;
- VariableAccessData* dataForPhi = m_graph[entry.m_phi].variableAccessData();
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Handling phi entry for var %u, phi @%u.\n", entry.m_varNo, entry.m_phi);
-#endif
-
- for (size_t i = 0; i < predecessors.size(); ++i) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Dealing with predecessor block %u.\n", predecessors[i]);
-#endif
-
- BasicBlock* predecessorBlock = m_graph.m_blocks[predecessors[i]].get();
-
- NodeIndex& var = (stackType == ArgumentPhiStack) ? predecessorBlock->variablesAtTail.argument(varNo) : predecessorBlock->variablesAtTail.local(varNo);
-
- NodeIndex valueInPredecessor = var;
- if (valueInPredecessor == NoNode) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Did not find node, adding phi.\n");
-#endif
-
- valueInPredecessor = insertPhiNode(OpInfo(newVariableAccessData(stackType == ArgumentPhiStack ? argumentToOperand(varNo) : static_cast<int>(varNo), false)), predecessorBlock);
- var = valueInPredecessor;
- if (stackType == ArgumentPhiStack)
- predecessorBlock->variablesAtHead.setArgumentFirstTime(varNo, valueInPredecessor);
- else
- predecessorBlock->variablesAtHead.setLocalFirstTime(varNo, valueInPredecessor);
- phiStack.append(PhiStackEntry(predecessorBlock, valueInPredecessor, varNo));
- } else if (m_graph[valueInPredecessor].op() == GetLocal) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Found GetLocal @%u.\n", valueInPredecessor);
-#endif
-
- // We want to ensure that the VariableAccessDatas are identical between the
- // GetLocal and its block-local Phi. Strictly speaking we only need the two
- // to be unified. But for efficiency, we want the code that creates GetLocals
- // and Phis to try to reuse VariableAccessDatas as much as possible.
- ASSERT(m_graph[valueInPredecessor].variableAccessData() == m_graph[m_graph[valueInPredecessor].child1().index()].variableAccessData());
-
- valueInPredecessor = m_graph[valueInPredecessor].child1().index();
- } else {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" 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));
-
- VariableAccessData* dataForPredecessor = m_graph[valueInPredecessor].variableAccessData();
-
- dataForPredecessor->unify(dataForPhi);
-
- Node* phiNode = &m_graph[entry.m_phi];
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Ref count of @%u = %u.\n", entry.m_phi, phiNode->refCount());
-#endif
- if (phiNode->refCount()) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Reffing @%u.\n", valueInPredecessor);
-#endif
- m_graph.ref(valueInPredecessor);
- }
-
- if (!phiNode->child1()) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Setting @%u->child1 = @%u.\n", entry.m_phi, valueInPredecessor);
-#endif
- phiNode->children.setChild1(Edge(valueInPredecessor));
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Children of @%u: ", entry.m_phi);
- phiNode->dumpChildren(WTF::dataFile());
- dataLogF(".\n");
-#endif
- continue;
- }
- if (!phiNode->child2()) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Setting @%u->child2 = @%u.\n", entry.m_phi, valueInPredecessor);
-#endif
- phiNode->children.setChild2(Edge(valueInPredecessor));
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Children of @%u: ", entry.m_phi);
- phiNode->dumpChildren(WTF::dataFile());
- dataLogF(".\n");
-#endif
- continue;
- }
- if (!phiNode->child3()) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Setting @%u->child3 = @%u.\n", entry.m_phi, valueInPredecessor);
-#endif
- phiNode->children.setChild3(Edge(valueInPredecessor));
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Children of @%u: ", entry.m_phi);
- phiNode->dumpChildren(WTF::dataFile());
- dataLogF(".\n");
-#endif
- continue;
- }
-
- NodeIndex newPhi = insertPhiNode(OpInfo(dataForPhi), entry.m_block);
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Splitting @%u, created @%u.\n", entry.m_phi, newPhi);
-#endif
-
- phiNode = &m_graph[entry.m_phi]; // reload after vector resize
- Node& newPhiNode = m_graph[newPhi];
- if (phiNode->refCount())
- m_graph.ref(newPhi);
-
- newPhiNode.children = phiNode->children;
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Children of @%u: ", newPhi);
- newPhiNode.dumpChildren(WTF::dataFile());
- dataLogF(".\n");
-#endif
-
- phiNode->children.initialize(newPhi, valueInPredecessor, NoNode);
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Children of @%u: ", entry.m_phi);
- phiNode->dumpChildren(WTF::dataFile());
- dataLogF(".\n");
-#endif
- }
- }
-}
-
-void ByteCodeParser::fixVariableAccessPredictions()
-{
- for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
- VariableAccessData* data = &m_graph.m_variableAccessData[i];
- data->find()->predict(data->nonUnifiedPrediction());
- data->find()->mergeIsCaptured(data->isCaptured());
- data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
- }
-}
-
void ByteCodeParser::linkBlock(BasicBlock* block, Vector<BlockIndex>& possibleTargets)
{
ASSERT(!block->isLinked);
ASSERT(!block->isEmpty());
- Node& node = m_graph[block->last()];
- ASSERT(node.isTerminal());
+ Node* node = block->last();
+ ASSERT(node->isTerminal());
- switch (node.op()) {
+ switch (node->op()) {
case Jump:
- node.setTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node.takenBytecodeOffsetDuringParsing()));
+ node->setTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Linked basic block %p to %p, #%u.\n", block, m_graph.m_blocks[node.takenBlockIndex()].get(), node.takenBlockIndex());
+ dataLogF("Linked basic block %p to %p, #%u.\n", block, m_graph.m_blocks[node->takenBlockIndex()].get(), node->takenBlockIndex());
#endif
break;
case Branch:
- node.setTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node.takenBytecodeOffsetDuringParsing()));
- node.setNotTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node.notTakenBytecodeOffsetDuringParsing()));
+ node->setTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node->takenBytecodeOffsetDuringParsing()));
+ node->setNotTakenBlockIndex(m_graph.blockIndexForBytecodeOffset(possibleTargets, node->notTakenBytecodeOffsetDuringParsing()));
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Linked basic block %p to %p, #%u and %p, #%u.\n", block, m_graph.m_blocks[node.takenBlockIndex()].get(), node.takenBlockIndex(), m_graph.m_blocks[node.notTakenBlockIndex()].get(), node.notTakenBlockIndex());
+ dataLogF("Linked basic block %p to %p, #%u and %p, #%u.\n", block, m_graph.m_blocks[node->takenBlockIndex()].get(), node->takenBlockIndex(), m_graph.m_blocks[node->notTakenBlockIndex()].get(), node->notTakenBlockIndex());
#endif
break;
@@ -3470,8 +3463,7 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
CodeBlock* codeBlock,
CodeBlock* profiledBlock,
BlockIndex callsiteBlockHead,
- VirtualRegister calleeVR,
- JSFunction* callee,
+ JSFunction* callee, // Null if this is a closure call.
VirtualRegister returnValueVR,
VirtualRegister inlineCallFrameStart,
int argumentCountIncludingThis,
@@ -3479,7 +3471,6 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
: m_byteCodeParser(byteCodeParser)
, m_codeBlock(codeBlock)
, m_profiledBlock(profiledBlock)
- , m_calleeVR(calleeVR)
, m_exitProfile(profiledBlock->exitProfile())
, m_callsiteBlockHead(callsiteBlockHead)
, m_returnValue(returnValueVR)
@@ -3504,15 +3495,14 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
if (m_caller) {
// Inline case.
ASSERT(codeBlock != byteCodeParser->m_codeBlock);
- ASSERT(callee);
- ASSERT(calleeVR != InvalidVirtualRegister);
ASSERT(inlineCallFrameStart != InvalidVirtualRegister);
ASSERT(callsiteBlockHead != NoBlock);
InlineCallFrame inlineCallFrame;
- inlineCallFrame.executable.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), codeBlock->ownerExecutable());
+ inlineCallFrame.executable.set(*byteCodeParser->m_vm, byteCodeParser->m_codeBlock->ownerExecutable(), codeBlock->ownerExecutable());
inlineCallFrame.stackOffset = inlineCallFrameStart + JSStack::CallFrameHeaderSize;
- inlineCallFrame.callee.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), callee);
+ if (callee)
+ inlineCallFrame.callee.set(*byteCodeParser->m_vm, byteCodeParser->m_codeBlock->ownerExecutable(), callee);
inlineCallFrame.caller = byteCodeParser->currentCodeOrigin();
inlineCallFrame.arguments.resize(argumentCountIncludingThis); // Set the number of arguments including this, but don't configure the value recoveries, yet.
inlineCallFrame.isCall = isCall(kind);
@@ -3549,14 +3539,12 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
- m_resolveOperationRemap.resize(codeBlock->numberOfResolveOperations());
- m_putToBaseOperationRemap.resize(codeBlock->numberOfPutToBaseOperations());
for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i) {
StringImpl* rep = codeBlock->identifier(i).impl();
IdentifierMap::AddResult result = byteCodeParser->m_identifierMap.add(rep, byteCodeParser->m_codeBlock->numberOfIdentifiers());
if (result.isNewEntry)
- byteCodeParser->m_codeBlock->addIdentifier(Identifier(byteCodeParser->m_globalData, rep));
+ byteCodeParser->m_codeBlock->addIdentifier(Identifier(byteCodeParser->m_vm, rep));
m_identifierRemap[i] = result.iterator->value;
}
for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) {
@@ -3577,11 +3565,6 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
}
m_constantRemap[i] = result.iterator->value;
}
- for (size_t i = 0; i < codeBlock->numberOfResolveOperations(); i++) {
- uint32_t newResolve = byteCodeParser->m_codeBlock->addResolve();
- m_resolveOperationRemap[i] = newResolve;
- byteCodeParser->m_codeBlock->resolveOperations(newResolve)->append(*codeBlock->resolveOperations(i));
- }
for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) {
// If we inline the same code block multiple times, we don't want to needlessly
// duplicate its constant buffers.
@@ -3596,18 +3579,11 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
m_constantBufferRemap[i] = newIndex;
byteCodeParser->m_constantBufferCache.add(ConstantBufferKey(codeBlock, i), newIndex);
}
- for (size_t i = 0; i < codeBlock->numberOfPutToBaseOperations(); i++) {
- uint32_t putToBaseResolve = byteCodeParser->m_codeBlock->addPutToBase();
- m_putToBaseOperationRemap[i] = putToBaseResolve;
- *byteCodeParser->m_codeBlock->putToBaseOperation(putToBaseResolve) = *codeBlock->putToBaseOperation(i);
- }
-
m_callsiteBlockHeadNeedsLinking = true;
} else {
// Machine code block case.
ASSERT(codeBlock == byteCodeParser->m_codeBlock);
ASSERT(!callee);
- ASSERT(calleeVR == InvalidVirtualRegister);
ASSERT(returnValueVR == InvalidVirtualRegister);
ASSERT(inlineCallFrameStart == InvalidVirtualRegister);
ASSERT(callsiteBlockHead == NoBlock);
@@ -3617,20 +3593,12 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
- m_resolveOperationRemap.resize(codeBlock->numberOfResolveOperations());
- m_putToBaseOperationRemap.resize(codeBlock->numberOfPutToBaseOperations());
-
for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i)
m_identifierRemap[i] = i;
for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i)
m_constantRemap[i] = i + FirstConstantRegisterIndex;
for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i)
m_constantBufferRemap[i] = i;
- for (size_t i = 0; i < codeBlock->numberOfResolveOperations(); ++i)
- m_resolveOperationRemap[i] = i;
- for (size_t i = 0; i < codeBlock->numberOfPutToBaseOperations(); ++i)
- m_putToBaseOperationRemap[i] = i;
-
m_callsiteBlockHeadNeedsLinking = false;
}
@@ -3644,24 +3612,48 @@ void ByteCodeParser::parseCodeBlock()
{
CodeBlock* codeBlock = m_inlineStackTop->m_codeBlock;
+ if (m_graph.m_compilation) {
+ m_graph.m_compilation->addProfiledBytecodes(
+ *m_vm->m_perBytecodeProfiler, m_inlineStackTop->m_profiledBlock);
+ }
+
+ bool shouldDumpBytecode = Options::dumpBytecodeAtDFGTime();
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog(
- "Parsing ", *codeBlock,
- ": captureCount = ", codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0,
- ", needsFullScopeChain = ", codeBlock->needsFullScopeChain(),
- ", needsActivation = ", codeBlock->ownerExecutable()->needsActivation(),
- ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
- codeBlock->baselineVersion()->dumpBytecode();
+ shouldDumpBytecode |= true;
#endif
+ if (shouldDumpBytecode) {
+ dataLog("Parsing ", *codeBlock);
+ if (inlineCallFrame()) {
+ dataLog(
+ " for inlining at ", CodeBlockWithJITType(m_codeBlock, JITCode::DFGJIT),
+ " ", inlineCallFrame()->caller);
+ }
+ dataLog(
+ ": captureCount = ", codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0,
+ ", needsFullScopeChain = ", codeBlock->needsFullScopeChain(),
+ ", needsActivation = ", codeBlock->ownerExecutable()->needsActivation(),
+ ", isStrictMode = ", codeBlock->ownerExecutable()->isStrictMode(), "\n");
+ codeBlock->baselineVersion()->dumpBytecode();
+ }
- for (unsigned jumpTargetIndex = 0; jumpTargetIndex <= codeBlock->numberOfJumpTargets(); ++jumpTargetIndex) {
+ Vector<unsigned, 32> jumpTargets;
+ computePreciseJumpTargets(codeBlock, jumpTargets);
+ if (Options::dumpBytecodeAtDFGTime()) {
+ dataLog("Jump targets: ");
+ CommaPrinter comma;
+ for (unsigned i = 0; i < jumpTargets.size(); ++i)
+ dataLog(comma, jumpTargets[i]);
+ dataLog("\n");
+ }
+
+ for (unsigned jumpTargetIndex = 0; jumpTargetIndex <= jumpTargets.size(); ++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();
+ unsigned limit = jumpTargetIndex < jumpTargets.size() ? jumpTargets[jumpTargetIndex] : codeBlock->instructions().size();
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog(
- "Parsing bytecode with limit ", m_inlineStackTop->m_inlineCallFrame->hash(),
+ "Parsing bytecode with limit ", pointerDump(inlineCallFrame()),
" bc#", limit, " at inline depth ",
- CodeOrigin::inlineDepthForCallFrame(m_inlineStackTop->m_inlineCallFrame), ".\n");
+ CodeOrigin::inlineDepthForCallFrame(inlineCallFrame()), ".\n");
#endif
ASSERT(m_currentIndex < limit);
@@ -3689,9 +3681,15 @@ void ByteCodeParser::parseCodeBlock()
} else {
OwnPtr<BasicBlock> block = adoptPtr(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals));
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("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));
+ dataLogF("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(inlineCallFrame()));
#endif
m_currentBlock = block.get();
+ // This assertion checks two things:
+ // 1) If the bytecodeBegin is greater than currentIndex, then something has gone
+ // horribly wrong. So, we're probably generating incorrect code.
+ // 2) If the bytecodeBegin is equal to the currentIndex, then we failed to do
+ // a peephole coalescing of this block in the if statement above. So, we're
+ // generating suboptimal code and leaving more work for the CFG simplifier.
ASSERT(m_inlineStackTop->m_unlinkedBlocks.isEmpty() || m_graph.m_blocks[m_inlineStackTop->m_unlinkedBlocks.last().m_blockIndex]->bytecodeBegin < m_currentIndex);
m_inlineStackTop->m_unlinkedBlocks.append(UnlinkedBlock(m_graph.m_blocks.size()));
m_inlineStackTop->m_blockLinkingTargets.append(m_graph.m_blocks.size());
@@ -3713,7 +3711,7 @@ void ByteCodeParser::parseCodeBlock()
// are at the end of an inline function, or we realized that we
// should stop parsing because there was a return in the first
// basic block.
- ASSERT(m_currentBlock->isEmpty() || m_graph.last().isTerminal() || (m_currentIndex == codeBlock->instructions().size() && m_inlineStackTop->m_inlineCallFrame) || !shouldContinueParsing);
+ ASSERT(m_currentBlock->isEmpty() || m_currentBlock->last()->isTerminal() || (m_currentIndex == codeBlock->instructions().size() && inlineCallFrame()) || !shouldContinueParsing);
if (!shouldContinueParsing)
return;
@@ -3737,53 +3735,33 @@ bool ByteCodeParser::parse()
#endif
InlineStackEntry inlineStackEntry(
- this, m_codeBlock, m_profiledBlock, NoBlock, InvalidVirtualRegister, 0,
- InvalidVirtualRegister, InvalidVirtualRegister, m_codeBlock->numParameters(),
- CodeForCall);
+ this, m_codeBlock, m_profiledBlock, NoBlock, 0, InvalidVirtualRegister, InvalidVirtualRegister,
+ m_codeBlock->numParameters(), CodeForCall);
parseCodeBlock();
linkBlocks(inlineStackEntry.m_unlinkedBlocks, inlineStackEntry.m_blockLinkingTargets);
m_graph.determineReachability();
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Processing local variable phis.\n");
-#endif
- m_currentProfilingIndex = m_currentIndex;
+ ASSERT(m_preservedVars.size());
+ size_t numberOfLocals = 0;
+ for (size_t i = m_preservedVars.size(); i--;) {
+ if (m_preservedVars.quickGet(i)) {
+ numberOfLocals = i + 1;
+ break;
+ }
+ }
- processPhiStack<LocalPhiStack>();
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Processing argument phis.\n");
-#endif
- processPhiStack<ArgumentPhiStack>();
-
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
ASSERT(block);
- if (!block->isReachable)
+ if (!block->isReachable) {
m_graph.m_blocks[blockIndex].clear();
- }
-
- fixVariableAccessPredictions();
-
- for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
- BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- if (!block)
- continue;
- if (!block->isOSRTarget)
continue;
- if (block->bytecodeBegin != m_graph.m_osrEntryBytecodeIndex)
- continue;
- for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) {
- NodeIndex nodeIndex = block->variablesAtHead.operand(
- m_graph.m_mustHandleValues.operandForIndex(i));
- if (nodeIndex == NoNode)
- continue;
- Node& node = m_graph[nodeIndex];
- ASSERT(node.hasLocal());
- node.variableAccessData()->predict(
- speculationFromValue(m_graph.m_mustHandleValues[i]));
}
+
+ block->variablesAtHead.ensureLocals(numberOfLocals);
+ block->variablesAtTail.ensureLocals(numberOfLocals);
}
m_graph.m_preservedVars = m_preservedVars;
@@ -3793,7 +3771,7 @@ bool ByteCodeParser::parse()
return true;
}
-bool parse(ExecState* exec, Graph& graph)
+bool parse(ExecState*, Graph& graph)
{
SamplingRegion samplingRegion("DFG Parsing");
#if DFG_DEBUG_LOCAL_DISBALE
@@ -3801,7 +3779,7 @@ bool parse(ExecState* exec, Graph& graph)
UNUSED_PARAM(graph);
return false;
#else
- return ByteCodeParser(exec, graph).parse();
+ return ByteCodeParser(graph).parse();
#endif
}
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.h b/Source/JavaScriptCore/dfg/DFGByteCodeParser.h
index f1648acf8..53b8dba11 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.h
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.h
@@ -28,12 +28,12 @@
#if ENABLE(DFG_JIT)
-#include <dfg/DFGGraph.h>
+#include "DFGGraph.h"
namespace JSC {
class CodeBlock;
-class JSGlobalData;
+class VM;
namespace DFG {
diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
index 3d99f6feb..ab33677ba 100644
--- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
+++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
@@ -37,8 +37,8 @@ namespace JSC { namespace DFG {
class CCallHelpers : public AssemblyHelpers {
public:
- CCallHelpers(JSGlobalData* globalData, CodeBlock* codeBlock = 0)
- : AssemblyHelpers(globalData, codeBlock)
+ CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
+ : AssemblyHelpers(vm, codeBlock)
{
}
@@ -609,6 +609,37 @@ public:
move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
poke(arg3, 4);
}
+#elif CPU(SH4)
+ ALWAYS_INLINE void setupArguments(FPRReg arg1)
+ {
+ moveDouble(arg1, FPRInfo::argumentFPR0);
+ }
+
+ ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
+ {
+ if (arg2 != FPRInfo::argumentFPR0) {
+ moveDouble(arg1, FPRInfo::argumentFPR0);
+ moveDouble(arg2, FPRInfo::argumentFPR1);
+ } else if (arg1 != FPRInfo::argumentFPR1) {
+ moveDouble(arg2, FPRInfo::argumentFPR1);
+ moveDouble(arg1, FPRInfo::argumentFPR0);
+ } else
+ swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
+ }
+
+ ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
+ {
+ moveDouble(arg1, FPRInfo::argumentFPR0);
+ move(arg2, GPRInfo::argumentGPR1);
+ move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ }
+
+ ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
+ {
+ moveDouble(arg3, FPRInfo::argumentFPR0);
+ setupStubArguments(arg1, arg2);
+ move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ }
#else
#error "DFG JIT not supported on this platform."
#endif
@@ -874,6 +905,13 @@ public:
setupArgumentsWithExecState(arg1, arg2, arg3);
}
+ ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4, TrustedImm32 arg5)
+ {
+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
+ poke(arg4, POKE_ARGUMENT_OFFSET);
+ setupArgumentsWithExecState(arg1, arg2, arg3);
+ }
+
ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
{
poke(arg4, POKE_ARGUMENT_OFFSET);
diff --git a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
index 1a88066d1..599a7918a 100644
--- a/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFAPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
#include "DFGAbstractState.h"
#include "DFGGraph.h"
#include "DFGPhase.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
@@ -44,6 +45,10 @@ public:
bool run()
{
+ ASSERT(m_graph.m_form == ThreadedCPS);
+ ASSERT(m_graph.m_unificationState == GloballyUnified);
+ ASSERT(m_graph.m_refCountState == EverythingIsLive);
+
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
m_count = 0;
#endif
@@ -87,11 +92,9 @@ private:
dataLogF("\n");
#endif
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)
- dataLogF(" %s @%u: ", Graph::opName(m_graph[nodeIndex].op()), nodeIndex);
+ Node* node = block->at(i);
+ dataLogF(" %s @%u: ", Graph::opName(node->op()), node->index());
m_state.dump(WTF::dataFile());
dataLogF("\n");
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
index 52cebf80f..c022fce2b 100644
--- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,11 +29,12 @@
#if ENABLE(DFG_JIT)
#include "DFGAbstractState.h"
-#include "DFGBasicBlock.h"
+#include "DFGBasicBlockInlines.h"
#include "DFGGraph.h"
#include "DFGInsertionSet.h"
#include "DFGPhase.h"
#include "DFGValidate.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
@@ -59,7 +60,7 @@ public:
continue;
ASSERT(block->isReachable);
- switch (m_graph[block->last()].op()) {
+ switch (block->last()->op()) {
case Jump: {
// Successor with one predecessor -> merge.
if (m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors.size() == 1) {
@@ -71,6 +72,7 @@ public:
#endif
if (extremeLogging)
m_graph.dump();
+ m_graph.dethread();
mergeBlocks(blockIndex, m_graph.successor(block, 0), NoBlock);
innerChanged = outerChanged = true;
break;
@@ -112,6 +114,7 @@ public:
#endif
if (extremeLogging)
m_graph.dump();
+ m_graph.dethread();
mergeBlocks(
blockIndex,
m_graph.successorForCondition(block, condition),
@@ -125,21 +128,20 @@ public:
#endif
if (extremeLogging)
m_graph.dump();
+ m_graph.dethread();
BlockIndex takenBlockIndex = m_graph.successorForCondition(block, condition);
BlockIndex notTakenBlockIndex = m_graph.successorForCondition(block, !condition);
- ASSERT(m_graph[block->last()].isTerminal());
- CodeOrigin boundaryCodeOrigin = m_graph[block->last()].codeOrigin;
- m_graph[block->last()].setOpAndDefaultFlags(Phantom);
- ASSERT(m_graph[block->last()].refCount() == 1);
+ ASSERT(block->last()->isTerminal());
+ CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin;
+ block->last()->convertToPhantom();
+ ASSERT(block->last()->refCount() == 1);
jettisonBlock(blockIndex, notTakenBlockIndex, boundaryCodeOrigin);
- NodeIndex jumpNodeIndex = m_graph.size();
- Node jump(Jump, boundaryCodeOrigin, OpInfo(takenBlockIndex));
- jump.ref();
- m_graph.append(jump);
- block->append(jumpNodeIndex);
+ block->appendNode(
+ m_graph, SpecNone, Jump, boundaryCodeOrigin,
+ OpInfo(takenBlockIndex));
}
innerChanged = outerChanged = true;
break;
@@ -155,24 +157,22 @@ public:
dataLogF("CFGSimplify: Branch to same successor merge on Block #%u to Block #%u.\n",
blockIndex, targetBlockIndex);
#endif
+ m_graph.dethread();
mergeBlocks(blockIndex, targetBlockIndex, NoBlock);
} else {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("CFGSimplify: Branch->jump conversion to same successor on Block #%u to Block #%u.\n",
blockIndex, targetBlockIndex);
#endif
- ASSERT(m_graph[block->last()].isTerminal());
- Node& branch = m_graph[block->last()];
- ASSERT(branch.isTerminal());
- ASSERT(branch.op() == Branch);
- branch.setOpAndDefaultFlags(Phantom);
- ASSERT(branch.refCount() == 1);
+ Node* branch = block->last();
+ ASSERT(branch->isTerminal());
+ ASSERT(branch->op() == Branch);
+ branch->convertToPhantom();
+ ASSERT(branch->refCount() == 1);
- Node jump(Jump, branch.codeOrigin, OpInfo(targetBlockIndex));
- jump.ref();
- NodeIndex jumpNodeIndex = m_graph.size();
- m_graph.append(jump);
- block->append(jumpNodeIndex);
+ block->appendNode(
+ m_graph, SpecNone, Jump, branch->codeOrigin,
+ OpInfo(targetBlockIndex));
}
innerChanged = outerChanged = true;
break;
@@ -239,7 +239,8 @@ public:
}
}
- validate(m_graph);
+ if (Options::validateGraphAtEachPhase())
+ validate(m_graph);
} while (innerChanged);
return outerChanged;
@@ -253,109 +254,24 @@ private:
ASSERT(block);
ASSERT(!block->isReachable);
- // 1) Remove references from other blocks to this block.
- for (unsigned i = m_graph.numSuccessors(block); i--;)
- fixPhis(blockIndex, m_graph.successor(block, i));
+ for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+ m_graph.m_allocator.free(block->phis[phiIndex]);
+ for (unsigned nodeIndex = block->size(); nodeIndex--;)
+ m_graph.m_allocator.free(block->at(nodeIndex));
- // 2) Kill the block
m_graph.m_blocks[blockIndex].clear();
}
- void keepOperandAlive(BasicBlock* block, CodeOrigin codeOrigin, int operand)
+ void keepOperandAlive(BasicBlock* block, BasicBlock* jettisonedBlock, CodeOrigin codeOrigin, int operand)
{
- NodeIndex nodeIndex = block->variablesAtTail.operand(operand);
- if (nodeIndex == NoNode)
+ Node* livenessNode = jettisonedBlock->variablesAtHead.operand(operand);
+ if (!livenessNode)
return;
- if (m_graph[nodeIndex].variableAccessData()->isCaptured())
+ if (livenessNode->variableAccessData()->isCaptured())
return;
- if (m_graph[nodeIndex].op() == SetLocal)
- nodeIndex = m_graph[nodeIndex].child1().index();
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate())
- return;
- ASSERT(m_graph[nodeIndex].op() != SetLocal);
- NodeIndex phantomNodeIndex = m_graph.size();
- Node phantom(Phantom, codeOrigin, nodeIndex);
- m_graph.append(phantom);
- m_graph.ref(phantomNodeIndex);
- block->append(phantomNodeIndex);
- }
-
- void fixPossibleGetLocal(BasicBlock* block, Edge& edge, bool changeRef)
- {
- Node& child = m_graph[edge];
- if (child.op() != GetLocal)
- return;
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Considering GetLocal at @%u, local r%d.\n", edge.index(), child.local());
-#endif
- if (child.variableAccessData()->isCaptured()) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" It's captured.\n");
-#endif
- return;
- }
- NodeIndex originalNodeIndex = block->variablesAtTail.operand(child.local());
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Dealing with original @%u.\n", originalNodeIndex);
-#endif
- ASSERT(originalNodeIndex != NoNode);
- Node* originalNode = &m_graph[originalNodeIndex];
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Original has local r%d.\n", originalNode->local());
-#endif
- ASSERT(child.local() == originalNode->local());
- // Possibilities:
- // SetLocal -> the secondBlock is getting the value of something that is immediately
- // available in the first block with a known NodeIndex.
- // GetLocal -> the secondBlock is getting the value of something that the first
- // block also gets.
- // Phi -> the secondBlock is asking for keep-alive on an operand that the first block
- // was also asking for keep-alive on.
- // SetArgument -> the secondBlock is asking for keep-alive on an operand that the
- // first block was keeping alive by virtue of the firstBlock being the root and
- // the operand being an argument.
- // Flush -> the secondBlock is asking for keep-alive on an operand that the first
- // block was forcing to be alive, so the second block should refer child of
- // the flush.
- if (originalNode->op() == Flush) {
- originalNodeIndex = originalNode->child1().index();
- originalNode = &m_graph[originalNodeIndex];
- }
- switch (originalNode->op()) {
- case SetLocal: {
- if (changeRef)
- ASSERT(originalNode->shouldGenerate());
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" It's a SetLocal.\n");
-#endif
- m_graph.changeIndex(edge, originalNode->child1().index(), changeRef);
- break;
- }
- case GetLocal: {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" It's a GetLocal.\n");
-#endif
- if (originalNode->shouldGenerate())
- m_graph.changeIndex(edge, originalNodeIndex, changeRef);
- // If we have a GetLocal that points to a child GetLocal that is dead, then
- // we have no need to do anything: this original GetLocal is still valid.
- break;
- }
- case Phi:
- case SetArgument: {
- if (changeRef)
- ASSERT(originalNode->shouldGenerate());
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" It's Phi/SetArgument.\n");
-#endif
- // Keep the GetLocal!
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- break;
- }
+ block->appendNode(
+ m_graph, SpecNone, PhantomLocal, codeOrigin,
+ OpInfo(livenessNode->variableAccessData()));
}
void jettisonBlock(BlockIndex blockIndex, BlockIndex jettisonedBlockIndex, CodeOrigin boundaryCodeOrigin)
@@ -364,46 +280,13 @@ private:
BasicBlock* jettisonedBlock = m_graph.m_blocks[jettisonedBlockIndex].get();
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i)
- keepOperandAlive(block, boundaryCodeOrigin, argumentToOperand(i));
+ keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, argumentToOperand(i));
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i)
- keepOperandAlive(block, boundaryCodeOrigin, i);
+ keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, i);
fixJettisonedPredecessors(blockIndex, jettisonedBlockIndex);
}
- void fixPhis(BlockIndex sourceBlockIndex, BlockIndex destinationBlockIndex)
- {
- BasicBlock* sourceBlock = m_graph.m_blocks[sourceBlockIndex].get();
- BasicBlock* destinationBlock = m_graph.m_blocks[destinationBlockIndex].get();
- if (!destinationBlock) {
- // If we're trying to kill off the source block and the destination block is already
- // dead, then we're done!
- return;
- }
- for (size_t i = 0; i < destinationBlock->phis.size(); ++i) {
- NodeIndex phiNodeIndex = destinationBlock->phis[i];
- Node& phiNode = m_graph[phiNodeIndex];
- NodeIndex myNodeIndex = sourceBlock->variablesAtTail.operand(phiNode.local());
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Considering removing reference from phi @%u to @%u on local r%d:",
- phiNodeIndex, myNodeIndex, phiNode.local());
-#endif
- if (myNodeIndex == NoNode) {
- // This will happen if there is a phi in the destination that refers into
- // the destination itself.
- continue;
- }
- Node& myNode = m_graph[myNodeIndex];
- if (myNode.op() == GetLocal)
- myNodeIndex = myNode.child1().index();
- for (unsigned j = 0; j < AdjacencyList::Size; ++j)
- removePotentiallyDeadPhiReference(myNodeIndex, phiNode, j, sourceBlock->isReachable);
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("\n");
-#endif
- }
- }
-
void fixJettisonedPredecessors(BlockIndex blockIndex, BlockIndex jettisonedBlockIndex)
{
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
@@ -418,145 +301,6 @@ private:
jettisonedBlock->m_predecessors.removeLast();
break;
}
-
- fixPhis(blockIndex, jettisonedBlockIndex);
- }
-
- void removePotentiallyDeadPhiReference(NodeIndex myNodeIndex, Node& phiNode, unsigned edgeIndex, bool changeRef)
- {
- if (phiNode.children.child(edgeIndex).indexUnchecked() != myNodeIndex)
- return;
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Removing reference at child %u.", edgeIndex);
-#endif
- if (changeRef && phiNode.shouldGenerate())
- m_graph.deref(myNodeIndex);
- phiNode.children.removeEdgeFromBag(edgeIndex);
- }
-
- struct OperandSubstitution {
- OperandSubstitution()
- : oldChild(NoNode)
- , newChild(NoNode)
- {
- }
-
- explicit OperandSubstitution(NodeIndex oldChild)
- : oldChild(oldChild)
- , newChild(oldChild)
- {
- }
-
- OperandSubstitution(NodeIndex oldChild, NodeIndex newChild)
- : oldChild(oldChild)
- , newChild(newChild)
- {
- ASSERT((oldChild == NoNode) == (newChild == NoNode));
- }
-
- void dump(FILE* out)
- {
- if (oldChild == NoNode)
- fprintf(out, "-");
- else
- fprintf(out, "@%u -> @%u", oldChild, newChild);
- }
-
- NodeIndex oldChild;
- NodeIndex newChild;
- };
-
- NodeIndex skipGetLocal(NodeIndex nodeIndex)
- {
- if (nodeIndex == NoNode)
- return NoNode;
- Node& node = m_graph[nodeIndex];
- if (node.op() == GetLocal)
- return node.child1().index();
- return nodeIndex;
- }
-
- void recordPossibleIncomingReference(
- BasicBlock* secondBlock, Operands<OperandSubstitution>& substitutions, int operand)
- {
- substitutions.operand(operand) = OperandSubstitution(
- skipGetLocal(secondBlock->variablesAtTail.operand(operand)));
- }
-
- void recordNewTarget(Operands<OperandSubstitution>& substitutions, int operand, NodeIndex nodeIndex)
- {
- ASSERT(m_graph[nodeIndex].op() == SetLocal
- || m_graph[nodeIndex].op() == SetArgument
- || m_graph[nodeIndex].op() == Flush
- || m_graph[nodeIndex].op() == Phi);
- substitutions.operand(operand).newChild = nodeIndex;
- }
-
- void fixTailOperand(
- BasicBlock* firstBlock, BasicBlock* secondBlock, int operand,
- Operands<OperandSubstitution>& substitutions)
- {
- NodeIndex atSecondTail = secondBlock->variablesAtTail.operand(operand);
-
- if (atSecondTail == NoNode) {
- // If the variable is dead at the end of the second block, then do nothing; essentially
- // this means that we want the tail state to reflect whatever the first block did.
- return;
- }
-
- Node& secondNode = m_graph[atSecondTail];
-
- switch (secondNode.op()) {
- case SetLocal:
- case Flush: {
- // The second block did interesting things to the variables, so update the tail
- // accordingly.
- firstBlock->variablesAtTail.operand(operand) = atSecondTail;
- break;
- }
-
- case Phi: {
- // Keep what was in the first block.
- ASSERT(firstBlock->variablesAtTail.operand(operand) != NoNode);
- recordNewTarget(substitutions, operand, skipGetLocal(firstBlock->variablesAtTail.operand(operand)));
- break;
- }
-
- case GetLocal: {
- // If it's a GetLocal on a captured var, then definitely keep what was
- // in the second block. In particular, it's possible that the first
- // block doesn't even know about this variable.
- if (secondNode.variableAccessData()->isCaptured()) {
- firstBlock->variablesAtTail.operand(operand) = atSecondTail;
- recordNewTarget(substitutions, operand, secondNode.child1().index());
- break;
- }
-
- // It's possible that the second block had a GetLocal and the first block
- // had a SetArgument or a Phi. Then update the tail. Otherwise keep what was in the
- // first block.
- NodeIndex atFirstTail = firstBlock->variablesAtTail.operand(operand);
- ASSERT(atFirstTail != NoNode);
- switch (m_graph[atFirstTail].op()) {
- case SetArgument:
- case Phi:
- firstBlock->variablesAtTail.operand(operand) = atSecondTail;
- recordNewTarget(substitutions, operand, secondNode.child1().index());
- break;
-
- default:
- // Keep what was in the first block, and adjust the substitution to account for
- // the fact that successors will refer to the child of the GetLocal.
- ASSERT(firstBlock->variablesAtTail.operand(operand) != NoNode);
- recordNewTarget(substitutions, operand, skipGetLocal(firstBlock->variablesAtTail.operand(operand)));
- break;
- }
- break;
- }
-
- default:
- ASSERT_NOT_REACHED();
- }
}
void mergeBlocks(
@@ -573,10 +317,10 @@ private:
// Remove the terminal of firstBlock since we don't need it anymore. Well, we don't
// really remove it; we actually turn it into a Phantom.
- ASSERT(m_graph[firstBlock->last()].isTerminal());
- CodeOrigin boundaryCodeOrigin = m_graph[firstBlock->last()].codeOrigin;
- m_graph[firstBlock->last()].setOpAndDefaultFlags(Phantom);
- ASSERT(m_graph[firstBlock->last()].refCount() == 1);
+ ASSERT(firstBlock->last()->isTerminal());
+ CodeOrigin boundaryCodeOrigin = firstBlock->last()->codeOrigin;
+ firstBlock->last()->convertToPhantom();
+ ASSERT(firstBlock->last()->refCount() == 1);
if (jettisonedBlockIndex != NoBlock) {
BasicBlock* jettisonedBlock = m_graph.m_blocks[jettisonedBlockIndex].get();
@@ -586,101 +330,18 @@ private:
// different path than secondBlock.
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i)
- keepOperandAlive(firstBlock, boundaryCodeOrigin, argumentToOperand(i));
+ keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, argumentToOperand(i));
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i)
- keepOperandAlive(firstBlock, boundaryCodeOrigin, i);
+ keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, i);
}
for (size_t i = 0; i < secondBlock->phis.size(); ++i)
firstBlock->phis.append(secondBlock->phis[i]);
- // Before we start changing the second block's graph, record what nodes would
- // be referenced by successors of the second block.
- Operands<OperandSubstitution> substitutions(
- secondBlock->variablesAtTail.numberOfArguments(),
- secondBlock->variablesAtTail.numberOfLocals());
- for (size_t i = 0; i < secondBlock->variablesAtTail.numberOfArguments(); ++i)
- recordPossibleIncomingReference(secondBlock, substitutions, argumentToOperand(i));
- for (size_t i = 0; i < secondBlock->variablesAtTail.numberOfLocals(); ++i)
- recordPossibleIncomingReference(secondBlock, substitutions, i);
-
- for (size_t i = 0; i < secondBlock->size(); ++i) {
- NodeIndex nodeIndex = secondBlock->at(i);
- Node& node = m_graph[nodeIndex];
-
- bool childrenAlreadyFixed = false;
-
- switch (node.op()) {
- case Phantom: {
- if (!node.child1())
- break;
-
- ASSERT(node.shouldGenerate());
- Node& possibleLocalOp = m_graph[node.child1()];
- if (possibleLocalOp.op() != GetLocal
- && possibleLocalOp.hasLocal()
- && !possibleLocalOp.variableAccessData()->isCaptured()) {
- NodeIndex setLocalIndex =
- firstBlock->variablesAtTail.operand(possibleLocalOp.local());
- Node& setLocal = m_graph[setLocalIndex];
- if (setLocal.op() == SetLocal) {
- m_graph.changeEdge(node.children.child1(), setLocal.child1());
- ASSERT(!node.child2());
- ASSERT(!node.child3());
- childrenAlreadyFixed = true;
- }
- }
- break;
- }
-
- case Flush:
- case GetLocal: {
- // A Flush could use a GetLocal, SetLocal, SetArgument, or a Phi.
- // If it uses a GetLocal, it'll be taken care of below. If it uses a
- // SetLocal or SetArgument, then it must be using a node from the
- // same block. But if it uses a Phi, then we should redirect it to
- // use whatever the first block advertised as a tail operand.
- // Similarly for GetLocal; it could use any of those except for
- // GetLocal. If it uses a Phi then it should be redirected to use a
- // Phi from the tail operand.
- if (m_graph[node.child1()].op() != Phi)
- break;
-
- NodeIndex atFirstIndex = firstBlock->variablesAtTail.operand(node.local());
- m_graph.changeEdge(node.children.child1(), Edge(skipGetLocal(atFirstIndex)), node.shouldGenerate());
- childrenAlreadyFixed = true;
- break;
- }
-
- default:
- break;
- }
-
- if (!childrenAlreadyFixed) {
- bool changeRef = node.shouldGenerate();
-
- // If the child is a GetLocal, then we might like to fix it.
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- ++childIdx) {
- if (!!m_graph.m_varArgChildren[childIdx])
- fixPossibleGetLocal(firstBlock, m_graph.m_varArgChildren[childIdx], changeRef);
- }
- } else if (!!node.child1()) {
- fixPossibleGetLocal(firstBlock, node.children.child1(), changeRef);
- if (!!node.child2()) {
- fixPossibleGetLocal(firstBlock, node.children.child2(), changeRef);
- if (!!node.child3())
- fixPossibleGetLocal(firstBlock, node.children.child3(), changeRef);
- }
- }
- }
-
- firstBlock->append(nodeIndex);
- }
+ for (size_t i = 0; i < secondBlock->size(); ++i)
+ firstBlock->append(secondBlock->at(i));
- ASSERT(m_graph[firstBlock->last()].isTerminal());
+ ASSERT(firstBlock->last()->isTerminal());
// Fix the predecessors of my new successors. This is tricky, since we are going to reset
// all predecessors anyway due to reachability analysis. But we need to fix the
@@ -700,39 +361,6 @@ private:
if (jettisonedBlockIndex != NoBlock)
fixJettisonedPredecessors(firstBlockIndex, jettisonedBlockIndex);
- // Fix up the variables at tail.
- for (size_t i = 0; i < secondBlock->variablesAtHead.numberOfArguments(); ++i)
- fixTailOperand(firstBlock, secondBlock, argumentToOperand(i), substitutions);
- for (size_t i = 0; i < secondBlock->variablesAtHead.numberOfLocals(); ++i)
- fixTailOperand(firstBlock, secondBlock, i, substitutions);
-
- // Fix up the references from our new successors.
- for (unsigned i = m_graph.numSuccessors(firstBlock); i--;) {
- BasicBlock* successor = m_graph.m_blocks[m_graph.successor(firstBlock, i)].get();
- for (unsigned j = 0; j < successor->phis.size(); ++j) {
- NodeIndex phiNodeIndex = successor->phis[j];
- Node& phiNode = m_graph[phiNodeIndex];
- bool changeRef = phiNode.shouldGenerate();
- OperandSubstitution substitution = substitutions.operand(phiNode.local());
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Performing operand substitution @%u -> @%u.\n",
- substitution.oldChild, substitution.newChild);
-#endif
- if (!phiNode.child1())
- continue;
- if (phiNode.child1().index() == substitution.oldChild)
- m_graph.changeIndex(phiNode.children.child1(), substitution.newChild, changeRef);
- if (!phiNode.child2())
- continue;
- if (phiNode.child2().index() == substitution.oldChild)
- m_graph.changeIndex(phiNode.children.child2(), substitution.newChild, changeRef);
- if (!phiNode.child3())
- continue;
- if (phiNode.child3().index() == substitution.oldChild)
- m_graph.changeIndex(phiNode.children.child3(), substitution.newChild, changeRef);
- }
- }
-
firstBlock->valuesAtTail = secondBlock->valuesAtTail;
firstBlock->cfaBranchDirection = secondBlock->cfaBranchDirection;
diff --git a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
new file mode 100644
index 000000000..a10fbe853
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGCPSRethreadingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+class CPSRethreadingPhase : public Phase {
+public:
+ CPSRethreadingPhase(Graph& graph)
+ : Phase(graph, "CPS rethreading")
+ {
+ }
+
+ bool run()
+ {
+ if (m_graph.m_form == ThreadedCPS)
+ return false;
+
+ clearIsLoadedFrom();
+ freeUnnecessaryNodes();
+ canonicalizeLocalsInBlocks();
+ propagatePhis<LocalOperand>();
+ propagatePhis<ArgumentOperand>();
+
+ m_graph.m_form = ThreadedCPS;
+ return true;
+ }
+
+private:
+
+ void clearIsLoadedFrom()
+ {
+ for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
+ m_graph.m_variableAccessData[i].setIsLoadedFrom(false);
+ }
+
+ void freeUnnecessaryNodes()
+ {
+ SamplingRegion samplingRegion("DFG CPS Rethreading: freeUnnecessaryNodes");
+
+ for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(block->isReachable);
+
+ unsigned fromIndex = 0;
+ unsigned toIndex = 0;
+ while (fromIndex < block->size()) {
+ Node* node = block->at(fromIndex++);
+ switch (node->op()) {
+ case GetLocal:
+ case Flush:
+ case PhantomLocal:
+ node->children.setChild1(Edge());
+ break;
+ case Phantom:
+ if (!node->child1())
+ continue;
+ switch (node->child1()->op()) {
+ case Phi:
+ case SetArgument:
+ case SetLocal:
+ node->convertToPhantomLocal();
+ break;
+ default:
+ ASSERT(node->child1()->hasResult());
+ break;
+ }
+ break;
+ case Nop:
+ continue;
+ default:
+ break;
+ }
+ node->replacement = 0; // Reset the replacement since the next phase will use it.
+ block->at(toIndex++) = node;
+ }
+ block->resize(toIndex);
+
+ for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+ m_graph.m_allocator.free(block->phis[phiIndex]);
+ block->phis.resize(0);
+ }
+ }
+
+ template<OperandKind operandKind>
+ void clearVariablesAtHeadAndTail()
+ {
+ ASSERT(
+ m_block->variablesAtHead.sizeFor<operandKind>()
+ == m_block->variablesAtTail.sizeFor<operandKind>());
+
+ for (unsigned i = m_block->variablesAtHead.sizeFor<operandKind>(); i--;) {
+ m_block->variablesAtHead.atFor<operandKind>(i) = 0;
+ m_block->variablesAtTail.atFor<operandKind>(i) = 0;
+ }
+ }
+
+ ALWAYS_INLINE Node* addPhiSilently(BasicBlock* block, const CodeOrigin& codeOrigin, VariableAccessData* variable)
+ {
+ Node* result = m_graph.addNode(SpecNone, Phi, codeOrigin, OpInfo(variable));
+ block->phis.append(result);
+ return result;
+ }
+
+ template<OperandKind operandKind>
+ ALWAYS_INLINE Node* addPhi(BasicBlock* block, const CodeOrigin& codeOrigin, VariableAccessData* variable, size_t index)
+ {
+ Node* result = addPhiSilently(block, codeOrigin, variable);
+ phiStackFor<operandKind>().append(PhiStackEntry(block, index, result));
+ return result;
+ }
+
+ template<OperandKind operandKind>
+ ALWAYS_INLINE Node* addPhi(const CodeOrigin& codeOrigin, VariableAccessData* variable, size_t index)
+ {
+ return addPhi<operandKind>(m_block, codeOrigin, variable, index);
+ }
+
+ template<OperandKind operandKind>
+ void canonicalizeGetLocalFor(Node* node, VariableAccessData* variable, size_t idx)
+ {
+ ASSERT(!node->child1());
+
+ if (Node* otherNode = m_block->variablesAtTail.atFor<operandKind>(idx)) {
+ ASSERT(otherNode->variableAccessData() == variable);
+
+ switch (otherNode->op()) {
+ case Flush:
+ case PhantomLocal:
+ otherNode = otherNode->child1().node();
+ if (otherNode->op() == Phi) {
+ // We need to have a GetLocal, so this might as well be the one.
+ node->children.setChild1(Edge(otherNode));
+ m_block->variablesAtTail.atFor<operandKind>(idx) = node;
+ return;
+ }
+ ASSERT(otherNode->op() == SetLocal || otherNode->op() == SetArgument);
+ break;
+ default:
+ break;
+ }
+
+ ASSERT(otherNode->op() == SetLocal || otherNode->op() == SetArgument || otherNode->op() == GetLocal);
+ ASSERT(otherNode->variableAccessData() == variable);
+
+ if (otherNode->op() == SetArgument) {
+ variable->setIsLoadedFrom(true);
+ node->children.setChild1(Edge(otherNode));
+ m_block->variablesAtTail.atFor<operandKind>(idx) = node;
+ return;
+ }
+
+ if (variable->isCaptured()) {
+ variable->setIsLoadedFrom(true);
+ if (otherNode->op() == GetLocal)
+ otherNode = otherNode->child1().node();
+ else
+ ASSERT(otherNode->op() == SetLocal || otherNode->op() == SetArgument);
+
+ ASSERT(otherNode->op() == Phi || otherNode->op() == SetLocal || otherNode->op() == SetArgument);
+
+ // Keep this GetLocal but link it to the prior ones.
+ node->children.setChild1(Edge(otherNode));
+ m_block->variablesAtTail.atFor<operandKind>(idx) = node;
+ return;
+ }
+
+ if (otherNode->op() == GetLocal) {
+ // Replace all references to this GetLocal with otherNode.
+ node->replacement = otherNode;
+ return;
+ }
+
+ ASSERT(otherNode->op() == SetLocal);
+ node->replacement = otherNode->child1().node();
+ return;
+ }
+
+ variable->setIsLoadedFrom(true);
+ Node* phi = addPhi<operandKind>(node->codeOrigin, variable, idx);
+ node->children.setChild1(Edge(phi));
+ m_block->variablesAtHead.atFor<operandKind>(idx) = phi;
+ m_block->variablesAtTail.atFor<operandKind>(idx) = node;
+ }
+
+ void canonicalizeGetLocal(Node* node)
+ {
+ VariableAccessData* variable = node->variableAccessData();
+ if (operandIsArgument(variable->local()))
+ canonicalizeGetLocalFor<ArgumentOperand>(node, variable, operandToArgument(variable->local()));
+ else
+ canonicalizeGetLocalFor<LocalOperand>(node, variable, variable->local());
+ }
+
+ void canonicalizeSetLocal(Node* node)
+ {
+ m_block->variablesAtTail.setOperand(node->local(), node);
+ }
+
+ template<NodeType nodeType, OperandKind operandKind>
+ void canonicalizeFlushOrPhantomLocalFor(Node* node, VariableAccessData* variable, size_t idx)
+ {
+ ASSERT(!node->child1());
+
+ if (Node* otherNode = m_block->variablesAtTail.atFor<operandKind>(idx)) {
+ ASSERT(otherNode->variableAccessData() == variable);
+
+ switch (otherNode->op()) {
+ case Flush:
+ case PhantomLocal:
+ case GetLocal:
+ otherNode = otherNode->child1().node();
+ break;
+ default:
+ break;
+ }
+
+ ASSERT(otherNode->op() == Phi || otherNode->op() == SetLocal || otherNode->op() == SetArgument);
+
+ if (nodeType == PhantomLocal && otherNode->op() == SetLocal) {
+ // PhantomLocal(SetLocal) doesn't make sense. PhantomLocal means: at this
+ // point I know I would have been interested in the value of this variable
+ // for the purpose of OSR. PhantomLocal(SetLocal) means: at this point I
+ // know that I would have read the value written by that SetLocal. This is
+ // redundant and inefficient, since really it just means that we want to
+ // be keeping the operand to the SetLocal alive. The SetLocal may die, and
+ // we'll be fine because OSR tracks dead SetLocals.
+
+ // So we turn this into a Phantom on the child of the SetLocal.
+
+ node->convertToPhantom();
+ node->children.setChild1(otherNode->child1());
+ return;
+ }
+
+ variable->setIsLoadedFrom(true);
+ // There is nothing wrong with having redundant Flush's. It just needs to
+ // be linked appropriately. Note that if there had already been a previous
+ // use at tail then we don't override it. It's fine for variablesAtTail to
+ // omit Flushes and PhantomLocals. On the other hand, having it refer to a
+ // Flush or a PhantomLocal if just before it the last use was a GetLocal would
+ // seriously confuse the CFA.
+ node->children.setChild1(Edge(otherNode));
+ return;
+ }
+
+ variable->setIsLoadedFrom(true);
+ node->children.setChild1(Edge(addPhi<operandKind>(node->codeOrigin, variable, idx)));
+ m_block->variablesAtHead.atFor<operandKind>(idx) = node;
+ m_block->variablesAtTail.atFor<operandKind>(idx) = node;
+ }
+
+ template<NodeType nodeType>
+ void canonicalizeFlushOrPhantomLocal(Node* node)
+ {
+ VariableAccessData* variable = node->variableAccessData();
+ if (operandIsArgument(variable->local()))
+ canonicalizeFlushOrPhantomLocalFor<nodeType, ArgumentOperand>(node, variable, operandToArgument(variable->local()));
+ else
+ canonicalizeFlushOrPhantomLocalFor<nodeType, LocalOperand>(node, variable, variable->local());
+ }
+
+ void canonicalizeSetArgument(Node* node)
+ {
+ int local = node->local();
+ ASSERT(operandIsArgument(local));
+ int argument = operandToArgument(local);
+ m_block->variablesAtHead.setArgumentFirstTime(argument, node);
+ m_block->variablesAtTail.setArgumentFirstTime(argument, node);
+ }
+
+ void canonicalizeLocalsInBlock()
+ {
+ if (!m_block)
+ return;
+ ASSERT(m_block->isReachable);
+
+ clearVariablesAtHeadAndTail<ArgumentOperand>();
+ clearVariablesAtHeadAndTail<LocalOperand>();
+
+ // Assumes that all phi references have been removed. Assumes that things that
+ // should be live have a non-zero ref count, but doesn't assume that the ref
+ // counts are correct beyond that (more formally !!logicalRefCount == !!actualRefCount
+ // but not logicalRefCount == actualRefCount). Assumes that it can break ref
+ // counts.
+
+ for (unsigned nodeIndex = 0; nodeIndex < m_block->size(); ++nodeIndex) {
+ Node* node = m_block->at(nodeIndex);
+
+ m_graph.performSubstitution(node);
+
+ // The rules for threaded CPS form:
+ //
+ // Head variable: describes what is live at the head of the basic block.
+ // Head variable links may refer to Flush, PhantomLocal, Phi, or SetArgument.
+ // SetArgument may only appear in the root block.
+ //
+ // Tail variable: the last thing that happened to the variable in the block.
+ // It may be a Flush, PhantomLocal, GetLocal, SetLocal, or SetArgument.
+ // SetArgument may only appear in the root block. Note that if there ever
+ // was a GetLocal to the variable, and it was followed by PhantomLocals and
+ // Flushes but not SetLocals, then the tail variable will be the GetLocal.
+ // This reflects the fact that you only care that the tail variable is a
+ // Flush or PhantomLocal if nothing else interesting happened.
+ //
+ // Child of GetLocal: the operation that the GetLocal keeps alive. For
+ // uncaptured locals, it may be a Phi from the current block. For arguments,
+ // it may be a SetArgument. For captured locals and arguments it may also be
+ // a SetLocal.
+ //
+ // Child of SetLocal: must be a value producing node.
+ //
+ // Child of Flush: it may be a Phi from the current block or a SetLocal. For
+ // arguments it may also be a SetArgument.
+ //
+ // Child of PhantomLocal: it may be a Phi from the current block. For
+ // arguments it may also be a SetArgument.
+ //
+ // Children of Phi: other Phis in the same basic block, or any of the
+ // following from predecessor blocks: SetLocal, Phi, or SetArgument. These
+ // are computed by looking at the tail variables of the predecessor blocks
+ // and either using it directly (if it's a SetLocal, Phi, or SetArgument) or
+ // loading that nodes child (if it's a GetLocal, PhanomLocal, or Flush - all
+ // of these will have children that are SetLocal, Phi, or SetArgument).
+
+ switch (node->op()) {
+ case GetLocal:
+ canonicalizeGetLocal(node);
+ break;
+
+ case SetLocal:
+ canonicalizeSetLocal(node);
+ break;
+
+ case Flush:
+ canonicalizeFlushOrPhantomLocal<Flush>(node);
+ break;
+
+ case PhantomLocal:
+ canonicalizeFlushOrPhantomLocal<PhantomLocal>(node);
+ break;
+
+ case SetArgument:
+ canonicalizeSetArgument(node);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ void canonicalizeLocalsInBlocks()
+ {
+ SamplingRegion samplingRegion("DFG CPS Rethreading: canonicalizeLocalsInBlocks");
+
+ for (m_blockIndex = m_graph.m_blocks.size(); m_blockIndex--;) {
+ m_block = m_graph.m_blocks[m_blockIndex].get();
+ canonicalizeLocalsInBlock();
+ }
+ }
+
+ template<OperandKind operandKind>
+ void propagatePhis()
+ {
+ Vector<PhiStackEntry, 128>& phiStack = operandKind == ArgumentOperand ? m_argumentPhiStack : m_localPhiStack;
+
+ SamplingRegion samplingRegion("DFG CPS Rethreading: propagatePhis");
+
+ // Ensure that attempts to use this fail instantly.
+ m_block = 0;
+ m_blockIndex = NoBlock;
+
+ while (!phiStack.isEmpty()) {
+ PhiStackEntry entry = phiStack.last();
+ phiStack.removeLast();
+
+ BasicBlock* block = entry.m_block;
+ PredecessorList& predecessors = block->m_predecessors;
+ Node* currentPhi = entry.m_phi;
+ VariableAccessData* variable = currentPhi->variableAccessData();
+ size_t index = entry.m_index;
+
+ for (size_t i = predecessors.size(); i--;) {
+ BasicBlock* predecessorBlock = m_graph.m_blocks[predecessors[i]].get();
+
+ Node* variableInPrevious = predecessorBlock->variablesAtTail.atFor<operandKind>(index);
+ if (!variableInPrevious) {
+ variableInPrevious = addPhi<operandKind>(predecessorBlock, currentPhi->codeOrigin, variable, index);
+ predecessorBlock->variablesAtTail.atFor<operandKind>(index) = variableInPrevious;
+ predecessorBlock->variablesAtHead.atFor<operandKind>(index) = variableInPrevious;
+ } else {
+ switch (variableInPrevious->op()) {
+ case GetLocal:
+ case PhantomLocal:
+ case Flush:
+ ASSERT(variableInPrevious->variableAccessData() == variableInPrevious->child1()->variableAccessData());
+ variableInPrevious = variableInPrevious->child1().node();
+ break;
+ default:
+ break;
+ }
+ }
+
+ ASSERT(
+ variableInPrevious->op() == SetLocal
+ || variableInPrevious->op() == Phi
+ || variableInPrevious->op() == SetArgument);
+
+ if (!currentPhi->child1()) {
+ currentPhi->children.setChild1(Edge(variableInPrevious));
+ continue;
+ }
+ if (!currentPhi->child2()) {
+ currentPhi->children.setChild2(Edge(variableInPrevious));
+ continue;
+ }
+ if (!currentPhi->child3()) {
+ currentPhi->children.setChild3(Edge(variableInPrevious));
+ continue;
+ }
+
+ Node* newPhi = addPhiSilently(block, currentPhi->codeOrigin, variable);
+ newPhi->children = currentPhi->children;
+ currentPhi->children.initialize(newPhi, variableInPrevious, 0);
+ }
+ }
+ }
+
+ struct PhiStackEntry {
+ PhiStackEntry(BasicBlock* block, size_t index, Node* phi)
+ : m_block(block)
+ , m_index(index)
+ , m_phi(phi)
+ {
+ }
+
+ BasicBlock* m_block;
+ size_t m_index;
+ Node* m_phi;
+ };
+
+ template<OperandKind operandKind>
+ Vector<PhiStackEntry, 128>& phiStackFor()
+ {
+ if (operandKind == ArgumentOperand)
+ return m_argumentPhiStack;
+ return m_localPhiStack;
+ }
+
+ BlockIndex m_blockIndex;
+ BasicBlock* m_block;
+ Vector<PhiStackEntry, 128> m_argumentPhiStack;
+ Vector<PhiStackEntry, 128> m_localPhiStack;
+};
+
+bool performCPSRethreading(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG CPS Rethreading Phase");
+ return runPhase<CPSRethreadingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.h b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.h
new file mode 100644
index 000000000..128847f2e
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGCPSRethreadingPhase_h
+#define DFGCPSRethreadingPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// CPS Rethreading:
+//
+// Takes a graph in which there are arbitrary GetLocals/SetLocals with no connections
+// between them. Removes redundant ones in the case of uncaptured variables. Connects
+// all of them with Phi functions to represent live ranges.
+
+bool performCPSRethreading(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGCPSRethreadingPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 36acb2c21..47af696a0 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,49 +30,54 @@
#include "DFGGraph.h"
#include "DFGPhase.h"
+#include "JSCellInlines.h"
+#include <wtf/FastBitVector.h>
namespace JSC { namespace DFG {
+enum CSEMode { NormalCSE, StoreElimination };
+
+template<CSEMode cseMode>
class CSEPhase : public Phase {
public:
CSEPhase(Graph& graph)
- : Phase(graph, "common subexpression elimination")
+ : Phase(graph, cseMode == NormalCSE ? "common subexpression elimination" : "store elimination")
{
- // Replacements are used to implement local common subexpression elimination.
- m_replacements.resize(m_graph.size());
-
- for (unsigned i = 0; i < m_graph.size(); ++i)
- m_replacements[i] = NoNode;
}
bool run()
{
+ ASSERT((cseMode == NormalCSE) == (m_graph.m_fixpointState == FixpointNotConverged));
+ ASSERT(m_graph.m_fixpointState != BeforeFixpoint);
+
m_changed = false;
+
for (unsigned block = 0; block < m_graph.m_blocks.size(); ++block)
performBlockCSE(m_graph.m_blocks[block].get());
+
return m_changed;
}
private:
- NodeIndex canonicalize(NodeIndex nodeIndex)
+ Node* canonicalize(Node* node)
{
- if (nodeIndex == NoNode)
- return NoNode;
+ if (!node)
+ return 0;
- if (m_graph[nodeIndex].op() == ValueToInt32)
- nodeIndex = m_graph[nodeIndex].child1().index();
+ if (node->op() == ValueToInt32)
+ node = node->child1().node();
- return nodeIndex;
+ return node;
}
- NodeIndex canonicalize(Edge nodeUse)
+ Node* canonicalize(Edge edge)
{
- return canonicalize(nodeUse.indexUnchecked());
+ return canonicalize(edge.node());
}
unsigned endIndexForPureCSE()
{
- unsigned result = m_lastSeen[m_graph[m_compileIndex].op()];
+ unsigned result = m_lastSeen[m_currentNode->op()];
if (result == UINT_MAX)
result = 0;
else
@@ -83,278 +88,300 @@ private:
#endif
return result;
}
-
- NodeIndex pureCSE(Node& node)
+
+ Node* pureCSE(Node* node)
{
- NodeIndex child1 = canonicalize(node.child1());
- NodeIndex child2 = canonicalize(node.child2());
- NodeIndex child3 = canonicalize(node.child3());
+ Node* child1 = canonicalize(node->child1());
+ Node* child2 = canonicalize(node->child2());
+ Node* child3 = canonicalize(node->child3());
for (unsigned i = endIndexForPureCSE(); i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1 || index == child2 || index == child3)
+ Node* otherNode = m_currentBlock->at(i);
+ if (otherNode == child1 || otherNode == child2 || otherNode == child3)
break;
- Node& otherNode = m_graph[index];
- if (!otherNode.shouldGenerate())
- continue;
-
- if (node.op() != otherNode.op())
+ if (node->op() != otherNode->op())
continue;
- if (node.arithNodeFlags() != otherNode.arithNodeFlags())
+ if (node->arithNodeFlags() != otherNode->arithNodeFlags())
continue;
- NodeIndex otherChild = canonicalize(otherNode.child1());
- if (otherChild == NoNode)
- return index;
+ Node* otherChild = canonicalize(otherNode->child1());
+ if (!otherChild)
+ return otherNode;
if (otherChild != child1)
continue;
- otherChild = canonicalize(otherNode.child2());
- if (otherChild == NoNode)
- return index;
+ otherChild = canonicalize(otherNode->child2());
+ if (!otherChild)
+ return otherNode;
if (otherChild != child2)
continue;
- otherChild = canonicalize(otherNode.child3());
- if (otherChild == NoNode)
- return index;
+ otherChild = canonicalize(otherNode->child3());
+ if (!otherChild)
+ return otherNode;
if (otherChild != child3)
continue;
- return index;
+ return otherNode;
}
- return NoNode;
+ return 0;
}
- NodeIndex constantCSE(Node& node)
+ Node* int32ToDoubleCSE(Node* node)
+ {
+ for (unsigned i = m_indexInBlock; i--;) {
+ Node* otherNode = m_currentBlock->at(i);
+ if (otherNode == node->child1())
+ return 0;
+ switch (otherNode->op()) {
+ case Int32ToDouble:
+ case ForwardInt32ToDouble:
+ if (otherNode->child1() == node->child1())
+ return otherNode;
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+ }
+
+ Node* constantCSE(Node* node)
{
for (unsigned i = endIndexForPureCSE(); i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& otherNode = m_graph[index];
- if (otherNode.op() != JSConstant)
+ Node* otherNode = m_currentBlock->at(i);
+ if (otherNode->op() != JSConstant)
continue;
- if (otherNode.constantNumber() != node.constantNumber())
+ if (otherNode->constantNumber() != node->constantNumber())
continue;
- return index;
+ return otherNode;
}
- return NoNode;
+ return 0;
}
- NodeIndex weakConstantCSE(Node& node)
+ Node* weakConstantCSE(Node* node)
{
for (unsigned i = endIndexForPureCSE(); i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& otherNode = m_graph[index];
- if (otherNode.op() != WeakJSConstant)
+ Node* otherNode = m_currentBlock->at(i);
+ if (otherNode->op() != WeakJSConstant)
continue;
- if (otherNode.weakConstant() != node.weakConstant())
+ if (otherNode->weakConstant() != node->weakConstant())
continue;
- return index;
+ return otherNode;
}
- return NoNode;
+ return 0;
}
- NodeIndex getArrayLengthElimination(NodeIndex array)
+ Node* getCalleeLoadElimination(InlineCallFrame* inlineCallFrame)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
+ Node* node = m_currentBlock->at(i);
+ if (node->codeOrigin.inlineCallFrame != inlineCallFrame)
continue;
- switch (node.op()) {
+ switch (node->op()) {
+ case GetCallee:
+ return node;
+ case SetCallee:
+ return node->child1().node();
+ default:
+ break;
+ }
+ }
+ return 0;
+ }
+
+ Node* getArrayLengthElimination(Node* array)
+ {
+ for (unsigned i = m_indexInBlock; i--;) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case GetArrayLength:
- if (node.child1() == array)
- return index;
+ if (node->child1() == array)
+ return node;
break;
case PutByVal:
if (!m_graph.byValIsPure(node))
- return NoNode;
- if (node.arrayMode().mayStoreToHole())
- return NoNode;
+ return 0;
+ if (node->arrayMode().mayStoreToHole())
+ return 0;
break;
default:
- if (m_graph.clobbersWorld(index))
- return NoNode;
+ if (m_graph.clobbersWorld(node))
+ return 0;
}
}
- return NoNode;
+ return 0;
}
- NodeIndex globalVarLoadElimination(WriteBarrier<Unknown>* registerPointer)
+ Node* globalVarLoadElimination(WriteBarrier<Unknown>* registerPointer)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case GetGlobalVar:
- if (node.registerPointer() == registerPointer)
- return index;
+ if (node->registerPointer() == registerPointer)
+ return node;
break;
case PutGlobalVar:
- if (node.registerPointer() == registerPointer)
- return node.child1().index();
+ if (node->registerPointer() == registerPointer)
+ return node->child1().node();
break;
default:
break;
}
- if (m_graph.clobbersWorld(index))
+ if (m_graph.clobbersWorld(node))
break;
}
- return NoNode;
+ return 0;
}
- NodeIndex scopedVarLoadElimination(unsigned scopeChainDepth, unsigned varNumber)
+ Node* scopedVarLoadElimination(Node* registers, unsigned varNumber)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case GetScopedVar: {
- Node& getScopeRegisters = m_graph[node.child1()];
- Node& getScope = m_graph[getScopeRegisters.child1()];
- if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
- return index;
+ if (node->child1() == registers && node->varNumber() == varNumber)
+ return node;
break;
}
case PutScopedVar: {
- Node& getScope = m_graph[node.child1()];
- if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
- return node.child3().index();
+ if (node->child2() == registers && node->varNumber() == varNumber)
+ return node->child3().node();
+ break;
+ }
+ case SetLocal: {
+ VariableAccessData* variableAccessData = node->variableAccessData();
+ if (variableAccessData->isCaptured()
+ && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
+ return 0;
break;
}
default:
break;
}
- if (m_graph.clobbersWorld(index))
+ if (m_graph.clobbersWorld(node))
break;
}
- return NoNode;
+ return 0;
}
bool globalVarWatchpointElimination(WriteBarrier<Unknown>* registerPointer)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case GlobalVarWatchpoint:
- if (node.registerPointer() == registerPointer)
+ if (node->registerPointer() == registerPointer)
return true;
break;
case PutGlobalVar:
- if (node.registerPointer() == registerPointer)
+ if (node->registerPointer() == registerPointer)
return false;
break;
default:
break;
}
- if (m_graph.clobbersWorld(index))
+ if (m_graph.clobbersWorld(node))
break;
}
return false;
}
- NodeIndex globalVarStoreElimination(WriteBarrier<Unknown>* registerPointer)
+ Node* globalVarStoreElimination(WriteBarrier<Unknown>* registerPointer)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case PutGlobalVar:
case PutGlobalVarCheck:
- if (node.registerPointer() == registerPointer)
- return index;
+ if (node->registerPointer() == registerPointer)
+ return node;
break;
case GetGlobalVar:
- if (node.registerPointer() == registerPointer)
- return NoNode;
+ if (node->registerPointer() == registerPointer)
+ return 0;
break;
default:
break;
}
- if (m_graph.clobbersWorld(index) || node.canExit())
- return NoNode;
+ if (m_graph.clobbersWorld(node) || node->canExit())
+ return 0;
}
- return NoNode;
+ return 0;
}
- NodeIndex scopedVarStoreElimination(unsigned scopeChainDepth, unsigned varNumber)
+ Node* scopedVarStoreElimination(Node* scope, Node* registers, unsigned varNumber)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case PutScopedVar: {
- Node& getScope = m_graph[node.child1()];
- if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
- return index;
+ if (node->child1() == scope && node->child2() == registers && node->varNumber() == varNumber)
+ return node;
break;
}
case GetScopedVar: {
- Node& getScopeRegisters = m_graph[node.child1()];
- Node& getScope = m_graph[getScopeRegisters.child1()];
- if (getScope.scopeChainDepth() == scopeChainDepth && node.varNumber() == varNumber)
- return NoNode;
+ // Let's be conservative.
+ if (node->varNumber() == varNumber)
+ return 0;
+ break;
+ }
+
+ case GetLocal: {
+ VariableAccessData* variableAccessData = node->variableAccessData();
+ if (variableAccessData->isCaptured()
+ && variableAccessData->local() == static_cast<VirtualRegister>(varNumber))
+ return 0;
break;
}
default:
break;
}
- if (m_graph.clobbersWorld(index) || node.canExit())
- return NoNode;
+ if (m_graph.clobbersWorld(node) || node->canExit())
+ return 0;
}
- return NoNode;
+ return 0;
}
- NodeIndex getByValLoadElimination(NodeIndex child1, NodeIndex child2)
+ Node* getByValLoadElimination(Node* child1, Node* child2)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1 || index == canonicalize(child2))
+ Node* node = m_currentBlock->at(i);
+ if (node == child1 || node == canonicalize(child2))
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case GetByVal:
if (!m_graph.byValIsPure(node))
- return NoNode;
- if (node.child1() == child1 && canonicalize(node.child2()) == canonicalize(child2))
- return index;
+ return 0;
+ if (node->child1() == child1 && canonicalize(node->child2()) == canonicalize(child2))
+ return node;
break;
case PutByVal:
case PutByValAlias: {
if (!m_graph.byValIsPure(node))
- return NoNode;
+ return 0;
if (m_graph.varArgChild(node, 0) == child1 && canonicalize(m_graph.varArgChild(node, 1)) == canonicalize(child2))
- return m_graph.varArgChild(node, 2).index();
+ return m_graph.varArgChild(node, 2).node();
// We must assume that the PutByVal will clobber the location we're getting from.
// FIXME: We can do better; if we know that the PutByVal is accessing an array of a
// different type than the GetByVal, then we know that they won't clobber each other.
- return NoNode;
+ // ... except of course for typed arrays, where all typed arrays clobber all other
+ // typed arrays! An Int32Array can alias a Float64Array for example, and so on.
+ return 0;
}
case PutStructure:
case PutByOffset:
@@ -364,58 +391,67 @@ private:
// the GetByVal.
break;
default:
- if (m_graph.clobbersWorld(index))
- return NoNode;
+ if (m_graph.clobbersWorld(node))
+ return 0;
break;
}
}
- return NoNode;
+ return 0;
}
- bool checkFunctionElimination(JSCell* function, NodeIndex child1)
+ bool checkFunctionElimination(JSCell* function, Node* child1)
{
for (unsigned i = endIndexForPureCSE(); i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (node.op() == CheckFunction && node.child1() == child1 && node.function() == function)
+ if (node->op() == CheckFunction && node->child1() == child1 && node->function() == function)
return true;
}
return false;
}
+
+ bool checkExecutableElimination(ExecutableBase* executable, Node* child1)
+ {
+ for (unsigned i = endIndexForPureCSE(); i--;) {
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
+ break;
- bool checkStructureElimination(const StructureSet& structureSet, NodeIndex child1)
+ if (node->op() == CheckExecutable && node->child1() == child1 && node->executable() == executable)
+ return true;
+ }
+ return false;
+ }
+
+ bool checkStructureElimination(const StructureSet& structureSet, Node* child1)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case CheckStructure:
case ForwardCheckStructure:
- if (node.child1() == child1
- && structureSet.isSupersetOf(node.structureSet()))
+ if (node->child1() == child1
+ && structureSet.isSupersetOf(node->structureSet()))
return true;
break;
case StructureTransitionWatchpoint:
case ForwardStructureTransitionWatchpoint:
- if (node.child1() == child1
- && structureSet.contains(node.structure()))
+ if (node->child1() == child1
+ && structureSet.contains(node->structure()))
return true;
break;
case PutStructure:
- if (node.child1() == child1
- && structureSet.contains(node.structureTransitionData().newStructure))
+ if (node->child1() == child1
+ && structureSet.contains(node->structureTransitionData().newStructure))
return true;
- if (structureSet.contains(node.structureTransitionData().previousStructure))
+ if (structureSet.contains(node->structureTransitionData().previousStructure))
return false;
break;
@@ -440,7 +476,7 @@ private:
return false;
default:
- if (m_graph.clobbersWorld(index))
+ if (m_graph.clobbersWorld(node))
return false;
break;
}
@@ -448,26 +484,23 @@ private:
return false;
}
- bool structureTransitionWatchpointElimination(Structure* structure, NodeIndex child1)
+ bool structureTransitionWatchpointElimination(Structure* structure, Node* child1)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case CheckStructure:
case ForwardCheckStructure:
- if (node.child1() == child1
- && node.structureSet().containsOnly(structure))
+ if (node->child1() == child1
+ && node->structureSet().containsOnly(structure))
return true;
break;
case PutStructure:
- ASSERT(node.structureTransitionData().previousStructure != structure);
+ ASSERT(node->structureTransitionData().previousStructure != structure);
break;
case PutByOffset:
@@ -486,7 +519,7 @@ private:
case StructureTransitionWatchpoint:
case ForwardStructureTransitionWatchpoint:
- if (node.structure() == structure && node.child1() == child1)
+ if (node->structure() == structure && node->child1() == child1)
return true;
break;
@@ -497,7 +530,7 @@ private:
return false;
default:
- if (m_graph.clobbersWorld(index))
+ if (m_graph.clobbersWorld(node))
return false;
break;
}
@@ -505,28 +538,25 @@ private:
return false;
}
- NodeIndex putStructureStoreElimination(NodeIndex child1)
+ Node* putStructureStoreElimination(Node* child1)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case CheckStructure:
case ForwardCheckStructure:
- return NoNode;
+ return 0;
case PhantomPutStructure:
- if (node.child1() == child1) // No need to retrace our steps.
- return NoNode;
+ if (node->child1() == child1) // No need to retrace our steps.
+ return 0;
break;
case PutStructure:
- if (node.child1() == child1)
- return index;
+ if (node->child1() == child1)
+ return node;
break;
// PutStructure needs to execute if we GC. Hence this needs to
@@ -538,7 +568,6 @@ private:
case NewFunctionExpression:
case CreateActivation:
case TearOffActivation:
- case StrCat:
case ToPrimitive:
case NewRegexp:
case NewArrayBuffer:
@@ -547,39 +576,45 @@ private:
case CreateThis:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
- return NoNode;
+ case TypeOf:
+ case ToString:
+ case NewStringObject:
+ case MakeRope:
+ return 0;
+
+ case GetIndexedPropertyStorage:
+ if (node->arrayMode().getIndexedPropertyStorageMayTriggerGC())
+ return 0;
+ break;
default:
break;
}
- if (m_graph.clobbersWorld(index) || node.canExit())
- return NoNode;
+ if (m_graph.clobbersWorld(node) || node->canExit())
+ return 0;
}
- return NoNode;
+ return 0;
}
- NodeIndex getByOffsetLoadElimination(unsigned identifierNumber, NodeIndex child1)
+ Node* getByOffsetLoadElimination(unsigned identifierNumber, Node* child1)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case GetByOffset:
- if (node.child1() == child1
- && m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber)
- return index;
+ if (node->child1() == child1
+ && m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber)
+ return node;
break;
case PutByOffset:
- if (m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber) {
- if (node.child1() == child1) // Must be same property storage.
- return node.child3().index();
- return NoNode;
+ if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber) {
+ if (node->child1() == child1) // Must be same property storage.
+ return node->child3().node();
+ return 0;
}
break;
@@ -595,38 +630,35 @@ private:
// change.
break;
}
- return NoNode;
+ return 0;
default:
- if (m_graph.clobbersWorld(index))
- return NoNode;
+ if (m_graph.clobbersWorld(node))
+ return 0;
break;
}
}
- return NoNode;
+ return 0;
}
- NodeIndex putByOffsetStoreElimination(unsigned identifierNumber, NodeIndex child1)
+ Node* putByOffsetStoreElimination(unsigned identifierNumber, Node* child1)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case GetByOffset:
- if (m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber)
- return NoNode;
+ if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber)
+ return 0;
break;
case PutByOffset:
- if (m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber == identifierNumber) {
- if (node.child1() == child1) // Must be same property storage.
- return index;
- return NoNode;
+ if (m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber == identifierNumber) {
+ if (node->child1() == child1) // Must be same property storage.
+ return node;
+ return 0;
}
break;
@@ -639,45 +671,42 @@ private:
// change.
break;
}
- return NoNode;
+ return 0;
default:
- if (m_graph.clobbersWorld(index))
- return NoNode;
+ if (m_graph.clobbersWorld(node))
+ return 0;
break;
}
- if (node.canExit())
- return NoNode;
+ if (node->canExit())
+ return 0;
}
- return NoNode;
+ return 0;
}
- NodeIndex getPropertyStorageLoadElimination(NodeIndex child1)
+ Node* getPropertyStorageLoadElimination(Node* child1)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case GetButterfly:
- if (node.child1() == child1)
- return index;
+ if (node->child1() == child1)
+ return node;
break;
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
// If we can cheaply prove this is a change to our object's storage, we
// can optimize and use its result.
- if (node.child1() == child1)
- return index;
+ if (node->child1() == child1)
+ return node;
// Otherwise, we currently can't prove that this doesn't change our object's
// storage, so we conservatively assume that it may change the storage
// pointer of any object, including ours.
- return NoNode;
+ return 0;
case PutByOffset:
case PutStructure:
@@ -693,34 +722,31 @@ private:
// change.
break;
}
- return NoNode;
+ return 0;
case Arrayify:
case ArrayifyToStructure:
// We could check if the arrayification could affect our butterfly.
// But that seems like it would take Effort.
- return NoNode;
+ return 0;
default:
- if (m_graph.clobbersWorld(index))
- return NoNode;
+ if (m_graph.clobbersWorld(node))
+ return 0;
break;
}
}
- return NoNode;
+ return 0;
}
- bool checkArrayElimination(NodeIndex child1, ArrayMode arrayMode)
+ bool checkArrayElimination(Node* child1, ArrayMode arrayMode)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case PutByOffset:
case PutStructure:
// Changing the structure or putting to the storage cannot
@@ -728,7 +754,7 @@ private:
break;
case CheckArray:
- if (node.child1() == child1 && node.arrayMode() == arrayMode)
+ if (node->child1() == child1 && node->arrayMode() == arrayMode)
return true;
break;
@@ -739,7 +765,7 @@ private:
return false;
default:
- if (m_graph.clobbersWorld(index))
+ if (m_graph.clobbersWorld(node))
return false;
break;
}
@@ -747,20 +773,17 @@ private:
return false;
}
- NodeIndex getIndexedPropertyStorageLoadElimination(NodeIndex child1, ArrayMode arrayMode)
+ Node* getIndexedPropertyStorageLoadElimination(Node* child1, ArrayMode arrayMode)
{
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- if (index == child1)
+ Node* node = m_currentBlock->at(i);
+ if (node == child1)
break;
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ switch (node->op()) {
case GetIndexedPropertyStorage: {
- if (node.child1() == child1 && node.arrayMode() == arrayMode)
- return index;
+ if (node->child1() == child1 && node->arrayMode() == arrayMode)
+ return node;
break;
}
@@ -771,80 +794,75 @@ private:
break;
default:
- if (m_graph.clobbersWorld(index))
- return NoNode;
+ if (m_graph.clobbersWorld(node))
+ return 0;
break;
}
}
- return NoNode;
+ return 0;
}
- NodeIndex getScopeLoadElimination(unsigned depth)
- {
- for (unsigned i = endIndexForPureCSE(); i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- if (node.op() == GetScope
- && node.scopeChainDepth() == depth)
- return index;
- }
- return NoNode;
- }
-
- NodeIndex getScopeRegistersLoadElimination(unsigned depth)
+ Node* getMyScopeLoadElimination(InlineCallFrame* inlineCallFrame)
{
- for (unsigned i = endIndexForPureCSE(); i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
+ for (unsigned i = m_indexInBlock; i--;) {
+ Node* node = m_currentBlock->at(i);
+ if (node->codeOrigin.inlineCallFrame != inlineCallFrame)
continue;
- if (node.op() == GetScopeRegisters
- && m_graph[node.scope()].scopeChainDepth() == depth)
- return index;
+ switch (node->op()) {
+ case CreateActivation:
+ // This may cause us to return a different scope.
+ return 0;
+ case GetMyScope:
+ return node;
+ case SetMyScope:
+ return node->child1().node();
+ default:
+ break;
+ }
}
- return NoNode;
+ return 0;
}
- NodeIndex getLocalLoadElimination(VirtualRegister local, NodeIndex& relevantLocalOp, bool careAboutClobbering)
+ Node* getLocalLoadElimination(VirtualRegister local, Node*& relevantLocalOp, bool careAboutClobbering)
{
- relevantLocalOp = NoNode;
+ relevantLocalOp = 0;
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case GetLocal:
- if (node.local() == local) {
- relevantLocalOp = index;
- return index;
+ if (node->local() == local) {
+ relevantLocalOp = node;
+ return node;
}
break;
case GetLocalUnlinked:
- if (node.unlinkedLocal() == local) {
- relevantLocalOp = index;
- return index;
+ if (node->unlinkedLocal() == local) {
+ relevantLocalOp = node;
+ return node;
}
break;
case SetLocal:
- if (node.local() == local) {
- relevantLocalOp = index;
- return node.child1().index();
+ if (node->local() == local) {
+ relevantLocalOp = node;
+ return node->child1().node();
}
break;
+ case PutScopedVar:
+ if (static_cast<VirtualRegister>(node->varNumber()) == local)
+ return 0;
+ break;
+
default:
- if (careAboutClobbering && m_graph.clobbersWorld(index))
- return NoNode;
+ if (careAboutClobbering && m_graph.clobbersWorld(node))
+ return 0;
break;
}
}
- return NoNode;
+ return 0;
}
struct SetLocalStoreEliminationResult {
@@ -860,46 +878,46 @@ private:
bool mayClobberWorld;
};
SetLocalStoreEliminationResult setLocalStoreElimination(
- VirtualRegister local, NodeIndex expectedNodeIndex)
+ VirtualRegister local, Node* expectedNode)
{
SetLocalStoreEliminationResult result;
for (unsigned i = m_indexInBlock; i--;) {
- NodeIndex index = m_currentBlock->at(i);
- Node& node = m_graph[index];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
+ Node* node = m_currentBlock->at(i);
+ switch (node->op()) {
case GetLocal:
case Flush:
- if (node.local() == local)
+ if (node->local() == local)
result.mayBeAccessed = true;
break;
case GetLocalUnlinked:
- if (node.unlinkedLocal() == local)
+ if (node->unlinkedLocal() == local)
result.mayBeAccessed = true;
break;
case SetLocal: {
- if (node.local() != local)
+ if (node->local() != local)
break;
- if (index != expectedNodeIndex)
- result.mayBeAccessed = true;
- if (m_graph[index].refCount() > 1)
+ if (node != expectedNode)
result.mayBeAccessed = true;
return result;
}
- case GetScope:
- case GetScopeRegisters:
- if (m_graph.uncheckedActivationRegisterFor(node.codeOrigin) == local)
+ case GetScopedVar:
+ if (static_cast<VirtualRegister>(node->varNumber()) == local)
+ result.mayBeAccessed = true;
+ break;
+
+ case GetMyScope:
+ case SkipTopScope:
+ if (m_graph.uncheckedActivationRegisterFor(node->codeOrigin) == local)
result.mayBeAccessed = true;
break;
case CheckArgumentsNotCreated:
case GetMyArgumentsLength:
case GetMyArgumentsLengthSafe:
- if (m_graph.uncheckedArgumentsRegisterFor(node.codeOrigin) == local)
+ if (m_graph.uncheckedArgumentsRegisterFor(node->codeOrigin) == local)
result.mayBeAccessed = true;
break;
@@ -910,7 +928,7 @@ private:
case GetByVal:
// If this is accessing arguments then it's potentially accessing locals.
- if (m_graph[node.child1()].shouldSpeculateArguments())
+ if (node->arrayMode().type() == Array::Arguments)
result.mayBeAccessed = true;
break;
@@ -927,58 +945,49 @@ private:
default:
break;
}
- result.mayExit |= node.canExit();
- result.mayClobberWorld |= m_graph.clobbersWorld(index);
+ result.mayExit |= node->canExit();
+ result.mayClobberWorld |= m_graph.clobbersWorld(node);
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
// Be safe in release mode.
result.mayBeAccessed = true;
return result;
}
- void performSubstitution(Edge& child, bool addRef = true)
+ void eliminateIrrelevantPhantomChildren(Node* node)
{
- // Check if this operand is actually unused.
- if (!child)
- return;
-
- // Check if there is any replacement.
- NodeIndex replacement = m_replacements[child.index()];
- if (replacement == NoNode)
- return;
-
- child.setIndex(replacement);
-
- // There is definitely a replacement. Assert that the replacement does not
- // have a replacement.
- ASSERT(m_replacements[child.index()] == NoNode);
-
- if (addRef)
- m_graph[child].ref();
+ ASSERT(node->op() == Phantom);
+ for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
+ Edge edge = node->children.child(i);
+ if (!edge)
+ continue;
+ if (edge.useKind() != UntypedUse)
+ continue; // Keep the type check.
+ if (edge->flags() & NodeRelevantToOSR)
+ continue;
+
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(" Eliminating edge @", m_currentNode->index(), " -> @", edge->index());
+#endif
+ node->children.removeEdge(i--);
+ m_changed = true;
+ }
}
- enum PredictionHandlingMode { RequireSamePrediction, AllowPredictionMismatch };
- bool setReplacement(NodeIndex replacement, PredictionHandlingMode predictionHandlingMode = RequireSamePrediction)
+ bool setReplacement(Node* replacement)
{
- if (replacement == NoNode)
- return false;
-
- // Be safe. Don't try to perform replacements if the predictions don't
- // agree.
- if (predictionHandlingMode == RequireSamePrediction
- && m_graph[m_compileIndex].prediction() != m_graph[replacement].prediction())
+ if (!replacement)
return false;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Replacing @%u -> @%u", m_compileIndex, replacement);
+ dataLogF(" Replacing @%u -> @%u", m_currentNode->index(), replacement->index());
#endif
- Node& node = m_graph[m_compileIndex];
- node.setOpAndDefaultFlags(Phantom);
- node.setRefCount(1);
+ m_currentNode->convertToPhantom();
+ eliminateIrrelevantPhantomChildren(m_currentNode);
// At this point we will eliminate all references to this node.
- m_replacements[m_compileIndex] = replacement;
+ m_currentNode->replacement = replacement;
m_changed = true;
@@ -988,63 +997,55 @@ private:
void eliminate()
{
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Eliminating @%u", m_compileIndex);
+ dataLogF(" Eliminating @%u", m_currentNode->index());
#endif
- Node& node = m_graph[m_compileIndex];
- ASSERT(node.refCount() == 1);
- ASSERT(node.mustGenerate());
- node.setOpAndDefaultFlags(Phantom);
+ ASSERT(m_currentNode->mustGenerate());
+ m_currentNode->convertToPhantom();
+ eliminateIrrelevantPhantomChildren(m_currentNode);
m_changed = true;
}
- void eliminate(NodeIndex nodeIndex, NodeType phantomType = Phantom)
+ void eliminate(Node* node, NodeType phantomType = Phantom)
{
- if (nodeIndex == NoNode)
+ if (!node)
return;
- Node& node = m_graph[nodeIndex];
- if (node.refCount() != 1)
- return;
- ASSERT(node.mustGenerate());
- node.setOpAndDefaultFlags(phantomType);
+ ASSERT(node->mustGenerate());
+ node->setOpAndDefaultNonExitFlags(phantomType);
+ if (phantomType == Phantom)
+ eliminateIrrelevantPhantomChildren(node);
m_changed = true;
}
- void performNodeCSE(Node& node)
+ void performNodeCSE(Node* node)
{
- bool shouldGenerate = node.shouldGenerate();
-
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
- performSubstitution(m_graph.m_varArgChildren[childIdx], shouldGenerate);
- } else {
- performSubstitution(node.children.child1(), shouldGenerate);
- performSubstitution(node.children.child2(), shouldGenerate);
- performSubstitution(node.children.child3(), shouldGenerate);
- }
+ if (cseMode == NormalCSE)
+ m_graph.performSubstitution(node);
- if (!shouldGenerate)
- return;
+ if (node->op() == SetLocal)
+ node->child1()->mergeFlags(NodeRelevantToOSR);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" %s @%u: ", Graph::opName(m_graph[m_compileIndex].op()), m_compileIndex);
+ dataLogF(" %s @%u: ", Graph::opName(node->op()), node->index());
#endif
// NOTE: there are some nodes that we deliberately don't CSE even though we
- // probably could, like StrCat and ToPrimitive. That's because there is no
+ // probably could, like MakeRope and ToPrimitive. That's because there is no
// evidence that doing CSE on these nodes would result in a performance
// progression. Hence considering these nodes in CSE would just mean that this
// code does more work with no win. Of course, we may want to reconsider this,
- // since StrCat is trivially CSE-able. It's not trivially doable for
+ // since MakeRope is trivially CSE-able. It's not trivially doable for
// ToPrimitive, but we could change that with some speculations if we really
// needed to.
- switch (node.op()) {
+ switch (node->op()) {
case Identity:
- setReplacement(node.child1().index());
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(node->child1().node());
break;
// Handle the pure nodes. These nodes never have any side-effects.
@@ -1058,16 +1059,15 @@ private:
case ArithSub:
case ArithNegate:
case ArithMul:
+ case ArithIMul:
case ArithMod:
case ArithDiv:
case ArithAbs:
case ArithMin:
case ArithMax:
case ArithSqrt:
- case GetCallee:
case StringCharAt:
case StringCharCodeAt:
- case Int32ToDouble:
case IsUndefined:
case IsBoolean:
case IsNumber:
@@ -1076,64 +1076,77 @@ private:
case IsFunction:
case DoubleAsInt32:
case LogicalNot:
+ case SkipTopScope:
+ case SkipScope:
+ case GetScopeRegisters:
+ case GetScope:
+ case TypeOf:
+ case CompareEqConstant:
+ case ValueToInt32:
+ if (cseMode == StoreElimination)
+ break;
setReplacement(pureCSE(node));
break;
+ case Int32ToDouble:
+ case ForwardInt32ToDouble:
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(int32ToDoubleCSE(node));
+ break;
+
+ case GetCallee:
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(getCalleeLoadElimination(node->codeOrigin.inlineCallFrame));
+ break;
+
case GetLocal: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ if (cseMode == StoreElimination)
+ break;
+ VariableAccessData* variableAccessData = node->variableAccessData();
if (!variableAccessData->isCaptured())
break;
- NodeIndex relevantLocalOp;
- NodeIndex possibleReplacement = getLocalLoadElimination(variableAccessData->local(), relevantLocalOp, variableAccessData->isCaptured());
- if (relevantLocalOp == NoNode)
+ Node* relevantLocalOp;
+ Node* possibleReplacement = getLocalLoadElimination(variableAccessData->local(), relevantLocalOp, variableAccessData->isCaptured());
+ if (!relevantLocalOp)
break;
- if (m_graph[relevantLocalOp].op() != GetLocalUnlinked
- && m_graph[relevantLocalOp].variableAccessData() != variableAccessData)
+ if (relevantLocalOp->op() != GetLocalUnlinked
+ && relevantLocalOp->variableAccessData() != variableAccessData)
break;
- NodeIndex phiIndex = node.child1().index();
+ Node* phi = node->child1().node();
if (!setReplacement(possibleReplacement))
break;
- // If the GetLocal we replaced used to refer to a SetLocal, then it now
- // should refer to the child of the SetLocal instead.
- if (m_graph[phiIndex].op() == SetLocal) {
- ASSERT(node.child1().index() == phiIndex);
- m_graph.changeEdge(node.children.child1(), m_graph[phiIndex].child1());
- }
- NodeIndex oldTailIndex = m_currentBlock->variablesAtTail.operand(
- variableAccessData->local());
- if (oldTailIndex == m_compileIndex) {
- m_currentBlock->variablesAtTail.operand(variableAccessData->local()) =
- relevantLocalOp;
-
- // Maintain graph integrity: since we're replacing a GetLocal with a GetLocalUnlinked,
- // make sure that the GetLocalUnlinked is now linked.
- if (m_graph[relevantLocalOp].op() == GetLocalUnlinked) {
- m_graph[relevantLocalOp].setOp(GetLocal);
- m_graph[relevantLocalOp].children.child1() = Edge(phiIndex);
- m_graph.ref(phiIndex);
- }
- }
+
+ m_graph.dethread();
+
+ // If we replace a GetLocal with a GetLocalUnlinked, then turn the GetLocalUnlinked
+ // into a GetLocal.
+ if (relevantLocalOp->op() == GetLocalUnlinked)
+ relevantLocalOp->convertToGetLocal(variableAccessData, phi);
+
m_changed = true;
break;
}
case GetLocalUnlinked: {
- NodeIndex relevantLocalOpIgnored;
- setReplacement(getLocalLoadElimination(node.unlinkedLocal(), relevantLocalOpIgnored, true));
+ if (cseMode == StoreElimination)
+ break;
+ Node* relevantLocalOpIgnored;
+ setReplacement(getLocalLoadElimination(node->unlinkedLocal(), relevantLocalOpIgnored, true));
break;
}
case Flush: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
VirtualRegister local = variableAccessData->local();
- NodeIndex replacementIndex = node.child1().index();
- Node& replacement = m_graph[replacementIndex];
- if (replacement.op() != SetLocal)
+ Node* replacement = node->child1().node();
+ if (replacement->op() != SetLocal)
break;
- ASSERT(replacement.variableAccessData() == variableAccessData);
+ ASSERT(replacement->variableAccessData() == variableAccessData);
// FIXME: We should be able to remove SetLocals that can exit; we just need
// to replace them with appropriate type checks.
- if (m_graph.m_fixpointState == FixpointNotConverged) {
+ if (cseMode == NormalCSE) {
// Need to be conservative at this time; if the SetLocal has any chance of performing
// any speculations then we cannot do anything.
if (variableAccessData->isCaptured()) {
@@ -1150,53 +1163,52 @@ private:
break;
}
} else {
- if (replacement.canExit())
+ if (replacement->canExit())
break;
}
SetLocalStoreEliminationResult result =
- setLocalStoreElimination(local, replacementIndex);
+ setLocalStoreElimination(local, replacement);
if (result.mayBeAccessed || result.mayClobberWorld)
break;
- ASSERT(replacement.op() == SetLocal);
- ASSERT(replacement.refCount() == 1);
- ASSERT(replacement.shouldGenerate());
+ ASSERT(replacement->op() == SetLocal);
// FIXME: Investigate using mayExit as a further optimization.
- node.setOpAndDefaultFlags(Phantom);
- NodeIndex dataNodeIndex = replacement.child1().index();
- ASSERT(m_graph[dataNodeIndex].hasResult());
+ node->convertToPhantom();
+ Node* dataNode = replacement->child1().node();
+ ASSERT(dataNode->hasResult());
m_graph.clearAndDerefChild1(node);
- node.children.child1() = Edge(dataNodeIndex);
- m_graph.ref(dataNodeIndex);
- NodeIndex oldTailIndex = m_currentBlock->variablesAtTail.operand(local);
- if (oldTailIndex == m_compileIndex)
- m_currentBlock->variablesAtTail.operand(local) = replacementIndex;
+ node->children.child1() = Edge(dataNode);
+ m_graph.dethread();
m_changed = true;
break;
}
case JSConstant:
+ if (cseMode == StoreElimination)
+ break;
// This is strange, but necessary. Some phases will convert nodes to constants,
// which may result in duplicated constants. We use CSE to clean this up.
- setReplacement(constantCSE(node), AllowPredictionMismatch);
+ setReplacement(constantCSE(node));
break;
case WeakJSConstant:
+ if (cseMode == StoreElimination)
+ break;
// FIXME: have CSE for weak constants against strong constants and vice-versa.
setReplacement(weakConstantCSE(node));
break;
case GetArrayLength:
- setReplacement(getArrayLengthElimination(node.child1().index()));
- break;
-
- case GetScope:
- setReplacement(getScopeLoadElimination(node.scopeChainDepth()));
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(getArrayLengthElimination(node->child1().node()));
break;
- case GetScopeRegisters:
- setReplacement(getScopeRegistersLoadElimination(m_graph[node.scope()].scopeChainDepth()));
+ case GetMyScope:
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(getMyScopeLoadElimination(node->codeOrigin.inlineCallFrame));
break;
-
+
// Handle nodes that are conditionally pure: these are pure, and can
// be CSE'd, so long as the prediction is the one we want.
case ValueAdd:
@@ -1205,10 +1217,12 @@ private:
case CompareGreater:
case CompareGreaterEq:
case CompareEq: {
+ if (cseMode == StoreElimination)
+ break;
if (m_graph.isPredictedNumerical(node)) {
- NodeIndex replacementIndex = pureCSE(node);
- if (replacementIndex != NoNode && m_graph.isPredictedNumerical(m_graph[replacementIndex]))
- setReplacement(replacementIndex);
+ Node* replacement = pureCSE(node);
+ if (replacement && m_graph.isPredictedNumerical(replacement))
+ setReplacement(replacement);
}
break;
}
@@ -1216,98 +1230,132 @@ private:
// Finally handle heap accesses. These are not quite pure, but we can still
// optimize them provided that some subtle conditions are met.
case GetGlobalVar:
- setReplacement(globalVarLoadElimination(node.registerPointer()));
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(globalVarLoadElimination(node->registerPointer()));
break;
case GetScopedVar: {
- Node& getScopeRegisters = m_graph[node.child1()];
- Node& getScope = m_graph[getScopeRegisters.child1()];
- setReplacement(scopedVarLoadElimination(getScope.scopeChainDepth(), node.varNumber()));
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(scopedVarLoadElimination(node->child1().node(), node->varNumber()));
break;
}
case GlobalVarWatchpoint:
- if (globalVarWatchpointElimination(node.registerPointer()))
+ if (cseMode == StoreElimination)
+ break;
+ if (globalVarWatchpointElimination(node->registerPointer()))
eliminate();
break;
case PutGlobalVar:
case PutGlobalVarCheck:
- if (m_graph.m_fixpointState == FixpointNotConverged)
+ if (cseMode == NormalCSE)
break;
- eliminate(globalVarStoreElimination(node.registerPointer()));
+ eliminate(globalVarStoreElimination(node->registerPointer()));
break;
case PutScopedVar: {
- if (m_graph.m_fixpointState == FixpointNotConverged)
+ if (cseMode == NormalCSE)
break;
- Node& getScope = m_graph[node.child1()];
- eliminate(scopedVarStoreElimination(getScope.scopeChainDepth(), node.varNumber()));
+ eliminate(scopedVarStoreElimination(node->child1().node(), node->child2().node(), node->varNumber()));
break;
}
case GetByVal:
+ if (cseMode == StoreElimination)
+ break;
if (m_graph.byValIsPure(node))
- setReplacement(getByValLoadElimination(node.child1().index(), node.child2().index()));
+ setReplacement(getByValLoadElimination(node->child1().node(), node->child2().node()));
break;
case PutByVal: {
+ if (cseMode == StoreElimination)
+ break;
Edge child1 = m_graph.varArgChild(node, 0);
Edge child2 = m_graph.varArgChild(node, 1);
- if (node.arrayMode().canCSEStorage()) {
- NodeIndex nodeIndex = getByValLoadElimination(child1.index(), child2.index());
- if (nodeIndex == NoNode)
+ if (node->arrayMode().canCSEStorage()) {
+ Node* replacement = getByValLoadElimination(child1.node(), child2.node());
+ if (!replacement)
break;
- node.setOp(PutByValAlias);
+ node->setOp(PutByValAlias);
}
break;
}
case CheckStructure:
case ForwardCheckStructure:
- if (checkStructureElimination(node.structureSet(), node.child1().index()))
+ if (cseMode == StoreElimination)
+ break;
+ if (checkStructureElimination(node->structureSet(), node->child1().node()))
eliminate();
break;
case StructureTransitionWatchpoint:
case ForwardStructureTransitionWatchpoint:
- if (structureTransitionWatchpointElimination(node.structure(), node.child1().index()))
+ if (cseMode == StoreElimination)
+ break;
+ if (structureTransitionWatchpointElimination(node->structure(), node->child1().node()))
eliminate();
break;
case PutStructure:
- if (m_graph.m_fixpointState == FixpointNotConverged)
+ if (cseMode == NormalCSE)
break;
- eliminate(putStructureStoreElimination(node.child1().index()), PhantomPutStructure);
+ eliminate(putStructureStoreElimination(node->child1().node()), PhantomPutStructure);
break;
case CheckFunction:
- if (checkFunctionElimination(node.function(), node.child1().index()))
+ if (cseMode == StoreElimination)
+ break;
+ if (checkFunctionElimination(node->function(), node->child1().node()))
+ eliminate();
+ break;
+
+ case CheckExecutable:
+ if (cseMode == StoreElimination)
+ break;
+ if (checkExecutableElimination(node->executable(), node->child1().node()))
eliminate();
break;
case CheckArray:
- if (checkArrayElimination(node.child1().index(), node.arrayMode()))
+ if (cseMode == StoreElimination)
+ break;
+ if (checkArrayElimination(node->child1().node(), node->arrayMode()))
eliminate();
break;
case GetIndexedPropertyStorage: {
- setReplacement(getIndexedPropertyStorageLoadElimination(node.child1().index(), node.arrayMode()));
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(getIndexedPropertyStorageLoadElimination(node->child1().node(), node->arrayMode()));
break;
}
case GetButterfly:
- setReplacement(getPropertyStorageLoadElimination(node.child1().index()));
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(getPropertyStorageLoadElimination(node->child1().node()));
break;
case GetByOffset:
- setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber, node.child1().index()));
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(getByOffsetLoadElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child1().node()));
break;
case PutByOffset:
- if (m_graph.m_fixpointState == FixpointNotConverged)
+ if (cseMode == NormalCSE)
break;
- eliminate(putByOffsetStoreElimination(m_graph.m_storageAccessData[node.storageAccessDataIndex()].identifierNumber, node.child1().index()));
+ eliminate(putByOffsetStoreElimination(m_graph.m_storageAccessData[node->storageAccessDataIndex()].identifierNumber, node->child1().node()));
+ break;
+
+ case Phantom:
+ // FIXME: we ought to remove Phantom's that have no children.
+
+ eliminateIrrelevantPhantomChildren(node);
break;
default:
@@ -1315,7 +1363,7 @@ private:
break;
}
- m_lastSeen[node.op()] = m_indexInBlock;
+ m_lastSeen[node->op()] = m_indexInBlock;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("\n");
#endif
@@ -1331,17 +1379,48 @@ private:
m_currentBlock = block;
for (unsigned i = 0; i < LastNodeType; ++i)
m_lastSeen[i] = UINT_MAX;
+
+ // All Phis need to already be marked as relevant to OSR, and have their
+ // replacements cleared, so we don't get confused while doing substitutions on
+ // GetLocal's.
+ for (unsigned i = 0; i < block->phis.size(); ++i) {
+ ASSERT(block->phis[i]->flags() & NodeRelevantToOSR);
+ block->phis[i]->replacement = 0;
+ }
+
+ // Make all of my SetLocal and GetLocal nodes relevant to OSR, and do some other
+ // necessary bookkeeping.
+ for (unsigned i = 0; i < block->size(); ++i) {
+ Node* node = block->at(i);
+
+ node->replacement = 0;
+
+ switch (node->op()) {
+ case SetLocal:
+ case GetLocal: // FIXME: The GetLocal case is only necessary until we do https://bugs.webkit.org/show_bug.cgi?id=106707.
+ node->mergeFlags(NodeRelevantToOSR);
+ break;
+ default:
+ node->clearFlags(NodeRelevantToOSR);
+ break;
+ }
+ }
for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
- m_compileIndex = block->at(m_indexInBlock);
- performNodeCSE(m_graph[m_compileIndex]);
+ m_currentNode = block->at(m_indexInBlock);
+ performNodeCSE(m_currentNode);
+ }
+
+ if (!ASSERT_DISABLED && cseMode == StoreElimination) {
+ // Nobody should have replacements set.
+ for (unsigned i = 0; i < block->size(); ++i)
+ ASSERT(!block->at(i)->replacement);
}
}
BasicBlock* m_currentBlock;
- NodeIndex m_compileIndex;
+ Node* m_currentNode;
unsigned m_indexInBlock;
- Vector<NodeIndex, 16> m_replacements;
FixedArray<unsigned, LastNodeType> m_lastSeen;
bool m_changed; // Only tracks changes that have a substantive effect on other optimizations.
};
@@ -1349,7 +1428,13 @@ private:
bool performCSE(Graph& graph)
{
SamplingRegion samplingRegion("DFG CSE Phase");
- return runPhase<CSEPhase>(graph);
+ return runPhase<CSEPhase<NormalCSE> >(graph);
+}
+
+bool performStoreElimination(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Store Elimination Phase");
+ return runPhase<CSEPhase<StoreElimination> >(graph);
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.h b/Source/JavaScriptCore/dfg/DFGCSEPhase.h
index 017bf5a4b..1dfd2b7dd 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.h
@@ -40,9 +40,11 @@ class Graph;
// it is rather profitable. It has fairly accurate heap modeling and will match
// a wide range of subexpression similarities. It's known to produce big wins
// on a few benchmarks, and is relatively cheap to run.
-
bool performCSE(Graph&);
+// Perform just block-local store elimination.
+bool performStoreElimination(Graph&);
+
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
index 869751372..1f58e1cc8 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
@@ -33,6 +33,41 @@
namespace JSC { namespace DFG {
#if ENABLE(DFG_JIT)
+bool mightCompileEval(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
+}
+bool mightCompileProgram(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
+}
+bool mightCompileFunctionForCall(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
+}
+bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
+}
+
+bool mightInlineFunctionForCall(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()
+ && !codeBlock->ownerExecutable()->needsActivation()
+ && codeBlock->ownerExecutable()->isInliningCandidate();
+}
+bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumFunctionForClosureCallInlineCandidateInstructionCount()
+ && !codeBlock->ownerExecutable()->needsActivation()
+ && codeBlock->ownerExecutable()->isInliningCandidate();
+}
+bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
+{
+ return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
+ && !codeBlock->ownerExecutable()->needsActivation()
+ && codeBlock->ownerExecutable()->isInliningCandidate();
+}
static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, bool result)
{
@@ -53,7 +88,6 @@ static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, Capability
if (result == CannotCompile)
dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]);
else {
- ASSERT(result == ShouldProfile);
dataLogF("Cannot compile code block %p because of opcode %s, but inlining might be possible.\n", codeBlock, opcodeNames[opcodeID]);
}
#else
@@ -66,7 +100,7 @@ static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, Capability
template<typename ReturnType, ReturnType (*canHandleOpcode)(OpcodeID, CodeBlock*, Instruction*)>
ReturnType canHandleOpcodes(CodeBlock* codeBlock, ReturnType initialValue)
{
- Interpreter* interpreter = codeBlock->globalData()->interpreter;
+ Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
unsigned instructionCount = codeBlock->instructions().size();
ReturnType result = initialValue;
@@ -87,7 +121,7 @@ ReturnType canHandleOpcodes(CodeBlock* codeBlock, ReturnType initialValue)
FOR_EACH_OPCODE_ID(DEFINE_OP)
#undef DEFINE_OP
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h
index a89c697f6..a9dc51325 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.h
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h
@@ -39,41 +39,17 @@ namespace JSC { namespace DFG {
#if ENABLE(DFG_JIT)
// Fast check functions; if they return true it is still necessary to
// check opcodes.
-inline bool mightCompileEval(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-inline bool mightCompileProgram(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-inline bool mightCompileFunctionForCall(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount();
-}
-
-inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount()
- && !codeBlock->ownerExecutable()->needsActivation();
-}
-inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
-{
- return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount()
- && !codeBlock->ownerExecutable()->needsActivation();
-}
+bool mightCompileEval(CodeBlock*);
+bool mightCompileProgram(CodeBlock*);
+bool mightCompileFunctionForCall(CodeBlock*);
+bool mightCompileFunctionForConstruct(CodeBlock*);
+bool mightInlineFunctionForCall(CodeBlock*);
+bool mightInlineFunctionForClosureCall(CodeBlock*);
+bool mightInlineFunctionForConstruct(CodeBlock*);
// Opcode checking.
-inline bool canInlineResolveOperations(OpcodeID opcode, ResolveOperations* operations)
+inline bool canInlineResolveOperations(ResolveOperations* operations)
{
- // Don't try to inline a resolve for which we have no information
- if (operations->isEmpty())
- return false;
-
for (unsigned i = 0; i < operations->size(); i++) {
switch (operations->data()[i].m_operation) {
case ResolveOperation::ReturnGlobalObjectAsBase:
@@ -82,24 +58,20 @@ inline bool canInlineResolveOperations(OpcodeID opcode, ResolveOperations* opera
case ResolveOperation::GetAndReturnGlobalProperty:
case ResolveOperation::GetAndReturnGlobalVar:
case ResolveOperation::GetAndReturnGlobalVarWatchable:
+ case ResolveOperation::SkipScopes:
+ case ResolveOperation::SetBaseToScope:
+ case ResolveOperation::ReturnScopeAsBase:
+ case ResolveOperation::GetAndReturnScopedVar:
continue;
case ResolveOperation::Fail:
- // The DFG can handle generic cases of failed resolves
- ASSERT(opcode != op_resolve_base_to_global_dynamic);
- ASSERT(opcode != op_resolve_base_to_scope_with_top_scope_check);
- ASSERT(opcode != op_resolve_base_to_global);
- ASSERT(opcode != op_resolve_base_to_scope);
- if (opcode != op_resolve && opcode != op_resolve_base)
- return false;
+ // Fall-back resolves don't know how to deal with the ExecState* having a different
+ // global object (and scope) than the inlined code that is invoking that resolve.
+ return false;
case ResolveOperation::SkipTopScopeNode:
- case ResolveOperation::SkipScopes:
- case ResolveOperation::SetBaseToScope:
- case ResolveOperation::ReturnScopeAsBase:
- case ResolveOperation::GetAndReturnScopedVar:
- // These opcodes would be easy to support with inlining, but we currently don't do it.
- // The issue is that the scope chain will not be set correctly.
+ // We don't inline code blocks that create activations. Creation of
+ // activations is the only thing that leads to SkipTopScopeNode.
return false;
case ResolveOperation::CheckForDynamicEntriesBeforeGlobalScope:
@@ -123,10 +95,8 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_rshift:
case op_lshift:
case op_urshift:
- case op_pre_inc:
- case op_post_inc:
- case op_pre_dec:
- case op_post_dec:
+ case op_inc:
+ case op_dec:
case op_add:
case op_sub:
case op_negate:
@@ -171,11 +141,8 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_init_global_const:
case op_init_global_const_check:
case op_jmp:
- case op_loop:
case op_jtrue:
case op_jfalse:
- case op_loop_if_true:
- case op_loop_if_false:
case op_jeq_null:
case op_jneq_null:
case op_jless:
@@ -187,10 +154,6 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_jngreater:
case op_jngreatereq:
case op_loop_hint:
- case op_loop_if_less:
- case op_loop_if_lesseq:
- case op_loop_if_greater:
- case op_loop_if_greatereq:
case op_ret:
case op_end:
case op_call_put_result:
@@ -217,10 +180,12 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_jneq_ptr:
case op_put_to_base_variable:
case op_put_to_base:
+ case op_typeof:
+ case op_to_number:
return CanCompile;
case op_call_varargs:
- return ShouldProfile;
+ return MayInline;
case op_resolve:
case op_resolve_global_property:
@@ -230,6 +195,10 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
case op_resolve_scoped_var_with_top_scope_check:
return CanCompile;
+ case op_get_scoped_var:
+ case op_put_scoped_var:
+ return CanCompile;
+
case op_resolve_base_to_global:
case op_resolve_base_to_global_dynamic:
case op_resolve_base_to_scope:
@@ -253,7 +222,7 @@ inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction
case op_resolve_scoped_var:
case op_resolve_scoped_var_on_top_scope:
case op_resolve_scoped_var_with_top_scope_check:
- return canInlineResolveOperations(opcodeID, codeBlock->resolveOperations(pc[3].u.operand));
+ return canInlineResolveOperations(pc[3].u.resolveOperations);
case op_resolve_base_to_global:
case op_resolve_base_to_global_dynamic:
@@ -262,8 +231,12 @@ inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction
case op_resolve_base:
case op_resolve_with_base:
case op_resolve_with_this:
- return canInlineResolveOperations(opcodeID, codeBlock->resolveOperations(pc[4].u.operand));
-
+ return canInlineResolveOperations(pc[4].u.resolveOperations);
+
+ case op_get_scoped_var:
+ case op_put_scoped_var:
+ return !codeBlock->needsFullScopeChain();
+
// Inlining doesn't correctly remap regular expression operands.
case op_new_regexp:
@@ -292,6 +265,7 @@ inline bool mightCompileProgram(CodeBlock*) { return false; }
inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
+inline bool mightInlineFunctionForClosureCall(CodeBlock*) { return false; }
inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
inline CapabilityLevel canCompileOpcode(OpcodeID, CodeBlock*, Instruction*) { return CannotCompile; }
@@ -337,6 +311,11 @@ inline bool canInlineFunctionForCall(CodeBlock* codeBlock)
return mightInlineFunctionForCall(codeBlock) && canInlineOpcodes(codeBlock);
}
+inline bool canInlineFunctionForClosureCall(CodeBlock* codeBlock)
+{
+ return mightInlineFunctionForClosureCall(codeBlock) && canInlineOpcodes(codeBlock);
+}
+
inline bool canInlineFunctionForConstruct(CodeBlock* codeBlock)
{
return mightInlineFunctionForConstruct(codeBlock) && canInlineOpcodes(codeBlock);
@@ -350,8 +329,12 @@ inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind
return mightInlineFunctionForConstruct(codeBlock);
}
-inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
+inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind, bool isClosureCall)
{
+ if (isClosureCall) {
+ ASSERT(kind == CodeForCall);
+ return canInlineFunctionForClosureCall(codeBlock);
+ }
if (kind == CodeForCall)
return canInlineFunctionForCall(codeBlock);
ASSERT(kind == CodeForConstruct);
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.cpp b/Source/JavaScriptCore/dfg/DFGCommon.cpp
new file mode 100644
index 000000000..502a95eb1
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGCommon.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGCommon.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNode.h"
+
+namespace JSC { namespace DFG {
+
+void NodePointerTraits::dump(Node* value, PrintStream& out)
+{
+ out.print(value);
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, OptimizationFixpointState state)
+{
+ switch (state) {
+ case BeforeFixpoint:
+ out.print("BeforeFixpoint");
+ break;
+ case FixpointNotConverged:
+ out.print("FixpointNotConverged");
+ break;
+ case FixpointConverged:
+ out.print("FixpointConverged");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void printInternal(PrintStream& out, GraphForm form)
+{
+ switch (form) {
+ case LoadStore:
+ out.print("LoadStore");
+ break;
+ case ThreadedCPS:
+ out.print("ThreadedCPS");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void printInternal(PrintStream& out, UnificationState state)
+{
+ switch (state) {
+ case LocallyUnified:
+ out.print("LocallyUnified");
+ break;
+ case GloballyUnified:
+ out.print("GloballyUnified");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void printInternal(PrintStream& out, RefCountState state)
+{
+ switch (state) {
+ case EverythingIsLive:
+ out.print("EverythingIsLive");
+ break;
+ case ExactRefCount:
+ out.print("ExactRefCount");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void printInternal(PrintStream& out, ProofStatus status)
+{
+ switch (status) {
+ case IsProved:
+ out.print("IsProved");
+ break;
+ case NeedsCheck:
+ out.print("NeedsCheck");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGCommon.h b/Source/JavaScriptCore/dfg/DFGCommon.h
index 14c47cefc..7aef749b0 100644
--- a/Source/JavaScriptCore/dfg/DFGCommon.h
+++ b/Source/JavaScriptCore/dfg/DFGCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,7 +35,7 @@
#include "VirtualRegister.h"
/* DFG_ENABLE() - turn on a specific features in the DFG JIT */
-#define DFG_ENABLE(DFG_FEATURE) (defined DFG_ENABLE_##DFG_FEATURE && DFG_ENABLE_##DFG_FEATURE)
+#define DFG_ENABLE(DFG_FEATURE) (defined DFG_ENABLE_##DFG_FEATURE && DFG_ENABLE_##DFG_FEATURE)
// Emit various logging information for debugging, including dumping the dataflow graphs.
#define DFG_ENABLE_DEBUG_VERBOSE 0
@@ -50,14 +50,6 @@
#else
#define DFG_ENABLE_JIT_ASSERT 0
#endif
-// Enable validation of the graph.
-#if !ASSERT_DISABLED
-#define DFG_ENABLE_VALIDATION 1
-#else
-#define DFG_ENABLE_VALIDATION 0
-#endif
-// Enable validation on completion of each phase.
-#define DFG_ENABLE_PER_PHASE_VALIDATION 0
// Consistency check contents compiler data structures.
#define DFG_ENABLE_CONSISTENCY_CHECK 0
// Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
@@ -70,8 +62,6 @@
#define DFG_ENABLE_XOR_DEBUG_AID 0
// Emit a breakpoint into the speculation failure code.
#define DFG_ENABLE_JIT_BREAK_ON_SPECULATION_FAILURE 0
-// Log every speculation failure.
-#define DFG_ENABLE_VERBOSE_SPECULATION_FAILURE 0
// Disable the DFG JIT without having to touch Platform.h
#define DFG_DEBUG_LOCAL_DISBALE 0
// Enable OSR entry from baseline JIT.
@@ -83,49 +73,66 @@
namespace JSC { namespace DFG {
-// Type for a reference to another node in the graph.
-typedef uint32_t NodeIndex;
-static const NodeIndex NoNode = UINT_MAX;
+struct Node;
typedef uint32_t BlockIndex;
static const BlockIndex NoBlock = UINT_MAX;
-struct NodeIndexTraits {
- static NodeIndex defaultValue() { return NoNode; }
- static void dump(NodeIndex value, PrintStream& out)
- {
- if (value == NoNode)
- out.printf("-");
- else
- out.printf("@%u", value);
- }
+struct NodePointerTraits {
+ static Node* defaultValue() { return 0; }
+ static void dump(Node* value, PrintStream& out);
};
-enum UseKind {
- UntypedUse,
- DoubleUse,
- LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
+// Use RefChildren if the child ref counts haven't already been adjusted using
+// other means and either of the following is true:
+// - The node you're creating is MustGenerate.
+// - The place where you're inserting a reference to the node you're creating
+// will not also do RefChildren.
+enum RefChildrenMode {
+ RefChildren,
+ DontRefChildren
};
-inline const char* useKindToString(UseKind useKind)
+// Use RefNode if you know that the node will be used from another node, and you
+// will not already be ref'ing the node to account for that use.
+enum RefNodeMode {
+ RefNode,
+ DontRefNode
+};
+
+inline bool verboseCompilationEnabled()
{
- switch (useKind) {
- case UntypedUse:
- return "";
- case DoubleUse:
- return "d";
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ return true;
+#else
+ return Options::verboseCompilation() || Options::dumpGraphAtEachPhase();
+#endif
}
-inline bool isX86()
+inline bool logCompilationChanges()
{
-#if CPU(X86_64) || CPU(X86)
+#if DFG_ENABLE(DEBUG_VERBOSE)
return true;
#else
- return false;
+ return verboseCompilationEnabled() || Options::logCompilationChanges();
+#endif
+}
+
+inline bool shouldDumpGraphAtEachPhase()
+{
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ return true;
+#else
+ return Options::dumpGraphAtEachPhase();
+#endif
+}
+
+inline bool validationEnabled()
+{
+#if !ASSERT_DISABLED
+ return true;
+#else
+ return Options::validateGraph() || Options::validateGraphAtEachPhase();
#endif
}
@@ -135,15 +142,117 @@ enum NoResultTag { NoResult };
enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
+// Describes the form you can expect the entire graph to be in.
+enum GraphForm {
+ // LoadStore form means that basic blocks may freely use GetLocal, SetLocal,
+ // GetLocalUnlinked, and Flush for accessing local variables and indicating
+ // where their live ranges ought to be. Data flow between local accesses is
+ // implicit. Liveness is only explicit at block heads (variablesAtHead).
+ // This is only used by the DFG simplifier and is only preserved by same.
+ //
+ // For example, LoadStore form gives no easy way to determine which SetLocal's
+ // flow into a GetLocal. As well, LoadStore form implies no restrictions on
+ // redundancy: you can freely emit multiple GetLocals, or multiple SetLocals
+ // (or any combination thereof) to the same local in the same block. LoadStore
+ // form does not require basic blocks to declare how they affect or use locals,
+ // other than implicitly by using the local ops and by preserving
+ // variablesAtHead. Finally, LoadStore allows flexibility in how liveness of
+ // locals is extended; for example you can replace a GetLocal with a Phantom
+ // and so long as the Phantom retains the GetLocal's children (i.e. the Phi
+ // most likely) then it implies that the local is still live but that it need
+ // not be stored to the stack necessarily. This implies that Phantom can
+ // reference nodes that have no result, as long as those nodes are valid
+ // GetLocal children (i.e. Phi, SetLocal, SetArgument).
+ //
+ // LoadStore form also implies that Phis need not have children. By default,
+ // they end up having no children if you enter LoadStore using the canonical
+ // way (call Graph::dethread).
+ //
+ // LoadStore form is suitable for CFG transformations, as well as strength
+ // reduction, folding, and CSE.
+ LoadStore,
+
+ // ThreadedCPS form means that basic blocks list up-front which locals they
+ // expect to be live at the head, and which locals they make available at the
+ // tail. ThreadedCPS form also implies that:
+ //
+ // - GetLocals and SetLocals to uncaptured variables are not redundant within
+ // a basic block.
+ //
+ // - All GetLocals and Flushes are linked directly to the last access point
+ // of the variable, which must not be another GetLocal if the variable is
+ // uncaptured.
+ //
+ // - Phantom(Phi) is not legal, but PhantomLocal is.
+ //
+ // ThreadedCPS form is suitable for data flow analysis (CFA, prediction
+ // propagation), register allocation, and code generation.
+ ThreadedCPS
+};
+
+// Describes the state of the UnionFind structure of VariableAccessData's.
+enum UnificationState {
+ // BasicBlock-local accesses to variables are appropriately unified with each other.
+ LocallyUnified,
+
+ // Unification has been performed globally.
+ GloballyUnified
+};
+
+// Describes how reference counts in the graph behave.
+enum RefCountState {
+ // Everything has refCount() == 1.
+ EverythingIsLive,
+
+ // Set after DCE has run.
+ ExactRefCount
+};
+
+enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };
+
+enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
+
+enum ProofStatus { NeedsCheck, IsProved };
+
+inline bool isProved(ProofStatus proofStatus)
+{
+ ASSERT(proofStatus == IsProved || proofStatus == NeedsCheck);
+ return proofStatus == IsProved;
+}
+
+inline ProofStatus proofStatusForIsProved(bool isProved)
+{
+ return isProved ? IsProved : NeedsCheck;
+}
+
+template<typename T, typename U>
+bool checkAndSet(T& left, U right)
+{
+ if (left == right)
+ return false;
+ left = right;
+ return true;
+}
+
} } // namespace JSC::DFG
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::OptimizationFixpointState);
+void printInternal(PrintStream&, JSC::DFG::GraphForm);
+void printInternal(PrintStream&, JSC::DFG::UnificationState);
+void printInternal(PrintStream&, JSC::DFG::RefCountState);
+void printInternal(PrintStream&, JSC::DFG::ProofStatus);
+
+} // namespace WTF
+
#endif // ENABLE(DFG_JIT)
namespace JSC { namespace DFG {
// Put things here that must be defined even if ENABLE(DFG_JIT) is false.
-enum CapabilityLevel { CannotCompile, ShouldProfile, CanCompile, CapabilityLevelNotSet };
+enum CapabilityLevel { CannotCompile, MayInline, CanCompile, CapabilityLevelNotSet };
// Unconditionally disable DFG disassembly support if the DFG is not compiled in.
inline bool shouldShowDisassembly()
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index 2221954b5..39ac2ff7a 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#include "DFGInsertionSet.h"
#include "DFGPhase.h"
#include "GetByIdStatus.h"
+#include "Operations.h"
#include "PutByIdStatus.h"
namespace JSC { namespace DFG {
@@ -43,6 +44,7 @@ public:
ConstantFoldingPhase(Graph& graph)
: Phase(graph, "constant folding")
, m_state(graph)
+ , m_insertionSet(graph)
{
}
@@ -73,22 +75,20 @@ private:
bool changed = false;
m_state.beginBasicBlock(block);
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
-
if (!m_state.isValid())
break;
+ Node* node = block->at(indexInBlock);
+
bool eliminated = false;
- switch (node.op()) {
+ switch (node->op()) {
case CheckArgumentsNotCreated: {
if (!isEmptySpeculation(
m_state.variables().operand(
- m_graph.argumentsRegisterFor(node.codeOrigin)).m_type))
+ m_graph.argumentsRegisterFor(node->codeOrigin)).m_type))
break;
- ASSERT(node.refCount() == 1);
- node.setOpAndDefaultFlags(Phantom);
+ node->convertToPhantom();
eliminated = true;
break;
}
@@ -96,61 +96,55 @@ private:
case CheckStructure:
case ForwardCheckStructure:
case ArrayifyToStructure: {
- AbstractValue& value = m_state.forNode(node.child1());
+ AbstractValue& value = m_state.forNode(node->child1());
StructureSet set;
- if (node.op() == ArrayifyToStructure)
- set = node.structure();
+ if (node->op() == ArrayifyToStructure)
+ set = node->structure();
else
- set = node.structureSet();
+ set = node->structureSet();
if (value.m_currentKnownStructure.isSubsetOf(set)) {
- ASSERT(node.refCount() == 1);
- node.setOpAndDefaultFlags(Phantom);
+ m_state.execute(indexInBlock); // Catch the fact that we may filter on cell.
+ node->convertToPhantom();
eliminated = true;
break;
}
StructureAbstractValue& structureValue = value.m_futurePossibleStructure;
if (structureValue.isSubsetOf(set)
- && structureValue.hasSingleton()
- && isCellSpeculation(value.m_type)) {
- node.convertToStructureTransitionWatchpoint(structureValue.singleton());
- changed = true;
+ && structureValue.hasSingleton()) {
+ Structure* structure = structureValue.singleton();
+ m_state.execute(indexInBlock); // Catch the fact that we may filter on cell.
+ node->convertToStructureTransitionWatchpoint(structure);
+ eliminated = true;
+ break;
}
break;
}
case CheckArray:
case Arrayify: {
- if (!node.arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node.child1())))
+ if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1())))
break;
- ASSERT(node.refCount() == 1);
- node.setOpAndDefaultFlags(Phantom);
+ node->convertToPhantom();
eliminated = true;
break;
}
case CheckFunction: {
- if (m_state.forNode(node.child1()).value() != node.function())
+ if (m_state.forNode(node->child1()).value() != node->function())
break;
- node.setOpAndDefaultFlags(Phantom);
+ node->convertToPhantom();
eliminated = true;
break;
}
- case ConvertThis: {
- if (!isObjectSpeculation(m_state.forNode(node.child1()).m_type))
- break;
- node.setOpAndDefaultFlags(Identity);
- changed = true;
- break;
- }
-
case GetById:
case GetByIdFlush: {
- CodeOrigin codeOrigin = node.codeOrigin;
- NodeIndex child = node.child1().index();
- unsigned identifierNumber = node.identifierNumber();
+ CodeOrigin codeOrigin = node->codeOrigin;
+ Edge childEdge = node->child1();
+ Node* child = childEdge.node();
+ unsigned identifierNumber = node->identifierNumber();
- if (!isCellSpeculation(m_graph[child].prediction()))
+ if (childEdge.useKind() != CellUse)
break;
Structure* structure = m_state.forNode(child).bestProvenStructure();
@@ -158,12 +152,16 @@ private:
break;
bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
+ bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
GetByIdStatus status = GetByIdStatus::computeFor(
- globalData(), structure, codeBlock()->identifier(identifierNumber));
+ vm(), structure, codeBlock()->identifier(identifierNumber));
- if (!status.isSimple())
+ if (!status.isSimple()) {
+ // FIXME: We could handle prototype cases.
+ // https://bugs.webkit.org/show_bug.cgi?id=110386
break;
+ }
ASSERT(status.structureSet().size() == 1);
ASSERT(status.chain().isEmpty());
@@ -177,28 +175,26 @@ private:
if (needsWatchpoint) {
ASSERT(m_state.forNode(child).m_futurePossibleStructure.isSubsetOf(StructureSet(structure)));
- m_graph[child].ref();
- Node watchpoint(StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), child);
- watchpoint.ref();
- NodeIndex watchpointIndex = m_graph.size();
- m_graph.append(watchpoint);
- m_insertionSet.append(indexInBlock, watchpointIndex);
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, StructureTransitionWatchpoint, codeOrigin,
+ OpInfo(structure), childEdge);
+ } else if (needsCellCheck) {
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, codeOrigin, childEdge);
}
- NodeIndex propertyStorageIndex;
+ childEdge.setUseKind(KnownCellUse);
+
+ Edge propertyStorage;
- m_graph[child].ref();
if (isInlineOffset(status.offset()))
- propertyStorageIndex = child;
+ propertyStorage = childEdge;
else {
- Node getButterfly(GetButterfly, codeOrigin, child);
- getButterfly.ref();
- propertyStorageIndex = m_graph.size();
- m_graph.append(getButterfly);
- m_insertionSet.append(indexInBlock, propertyStorageIndex);
+ propertyStorage = Edge(m_insertionSet.insertNode(
+ indexInBlock, SpecNone, GetButterfly, codeOrigin, childEdge));
}
- m_graph[nodeIndex].convertToGetByOffset(m_graph.m_storageAccessData.size(), propertyStorageIndex);
+ node->convertToGetByOffset(m_graph.m_storageAccessData.size(), propertyStorage);
StorageAccessData storageAccessData;
storageAccessData.offset = indexRelativeToBase(status.offset());
@@ -209,22 +205,26 @@ private:
case PutById:
case PutByIdDirect: {
- CodeOrigin codeOrigin = node.codeOrigin;
- NodeIndex child = node.child1().index();
- unsigned identifierNumber = node.identifierNumber();
+ CodeOrigin codeOrigin = node->codeOrigin;
+ Edge childEdge = node->child1();
+ Node* child = childEdge.node();
+ unsigned identifierNumber = node->identifierNumber();
+
+ ASSERT(childEdge.useKind() == CellUse);
Structure* structure = m_state.forNode(child).bestProvenStructure();
if (!structure)
break;
bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
+ bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
PutByIdStatus status = PutByIdStatus::computeFor(
- globalData(),
+ vm(),
m_graph.globalObjectFor(codeOrigin),
structure,
codeBlock()->identifier(identifierNumber),
- node.op() == PutByIdDirect);
+ node->op() == PutByIdDirect);
if (!status.isSimpleReplace() && !status.isSimpleTransition())
break;
@@ -239,20 +239,22 @@ private:
if (needsWatchpoint) {
ASSERT(m_state.forNode(child).m_futurePossibleStructure.isSubsetOf(StructureSet(structure)));
- m_graph[child].ref();
- Node watchpoint(StructureTransitionWatchpoint, codeOrigin, OpInfo(structure), child);
- watchpoint.ref();
- NodeIndex watchpointIndex = m_graph.size();
- m_graph.append(watchpoint);
- m_insertionSet.append(indexInBlock, watchpointIndex);
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, StructureTransitionWatchpoint, codeOrigin,
+ OpInfo(structure), childEdge);
+ } else if (needsCellCheck) {
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, codeOrigin, childEdge);
}
+ childEdge.setUseKind(KnownCellUse);
+
StructureTransitionData* transitionData = 0;
if (status.isSimpleTransition()) {
transitionData = m_graph.addStructureTransitionData(
StructureTransitionData(structure, status.newStructure()));
- if (node.op() == PutById) {
+ if (node->op() == PutById) {
if (!structure->storedPrototype().isNull()) {
addStructureTransitionCheck(
codeOrigin, indexInBlock,
@@ -269,57 +271,39 @@ private:
}
}
}
-
- NodeIndex propertyStorageIndex;
- m_graph[child].ref();
+ Edge propertyStorage;
+
if (isInlineOffset(status.offset()))
- propertyStorageIndex = child;
+ propertyStorage = childEdge;
else if (status.isSimpleReplace() || structure->outOfLineCapacity() == status.newStructure()->outOfLineCapacity()) {
- Node getButterfly(GetButterfly, codeOrigin, child);
- getButterfly.ref();
- propertyStorageIndex = m_graph.size();
- m_graph.append(getButterfly);
- m_insertionSet.append(indexInBlock, propertyStorageIndex);
+ propertyStorage = Edge(m_insertionSet.insertNode(
+ indexInBlock, SpecNone, GetButterfly, codeOrigin, childEdge));
} else if (!structure->outOfLineCapacity()) {
ASSERT(status.newStructure()->outOfLineCapacity());
ASSERT(!isInlineOffset(status.offset()));
- Node allocateStorage(AllocatePropertyStorage, codeOrigin, OpInfo(transitionData), child);
- allocateStorage.ref(); // Once for the use.
- allocateStorage.ref(); // Twice because it's must-generate.
- propertyStorageIndex = m_graph.size();
- m_graph.append(allocateStorage);
- m_insertionSet.append(indexInBlock, propertyStorageIndex);
+ propertyStorage = Edge(m_insertionSet.insertNode(
+ indexInBlock, SpecNone, AllocatePropertyStorage,
+ codeOrigin, OpInfo(transitionData), childEdge));
} else {
ASSERT(structure->outOfLineCapacity());
ASSERT(status.newStructure()->outOfLineCapacity() > structure->outOfLineCapacity());
ASSERT(!isInlineOffset(status.offset()));
- Node getButterfly(GetButterfly, codeOrigin, child);
- getButterfly.ref();
- NodeIndex getButterflyIndex = m_graph.size();
- m_graph.append(getButterfly);
- m_insertionSet.append(indexInBlock, getButterflyIndex);
-
- m_graph[child].ref();
- Node reallocateStorage(ReallocatePropertyStorage, codeOrigin, OpInfo(transitionData), child, getButterflyIndex);
- reallocateStorage.ref(); // Once for the use.
- reallocateStorage.ref(); // Twice because it's must-generate.
- propertyStorageIndex = m_graph.size();
- m_graph.append(reallocateStorage);
- m_insertionSet.append(indexInBlock, propertyStorageIndex);
+ propertyStorage = Edge(m_insertionSet.insertNode(
+ indexInBlock, SpecNone, ReallocatePropertyStorage, codeOrigin,
+ OpInfo(transitionData), childEdge,
+ Edge(m_insertionSet.insertNode(
+ indexInBlock, SpecNone, GetButterfly, codeOrigin, childEdge))));
}
if (status.isSimpleTransition()) {
- m_graph[child].ref();
- Node putStructure(PutStructure, codeOrigin, OpInfo(transitionData), child);
- putStructure.ref();
- NodeIndex putStructureIndex = m_graph.size();
- m_graph.append(putStructure);
- m_insertionSet.append(indexInBlock, putStructureIndex);
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, PutStructure, codeOrigin,
+ OpInfo(transitionData), childEdge);
}
- m_graph[nodeIndex].convertToPutByOffset(m_graph.m_storageAccessData.size(), propertyStorageIndex);
+ node->convertToPutByOffset(m_graph.m_storageAccessData.size(), propertyStorage);
StorageAccessData storageAccessData;
storageAccessData.offset = indexRelativeToBase(status.offset());
@@ -338,108 +322,91 @@ private:
}
m_state.execute(indexInBlock);
- if (!node.shouldGenerate() || m_state.didClobber() || node.hasConstant())
+ if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant())
continue;
- JSValue value = m_state.forNode(nodeIndex).value();
+ JSValue value = m_state.forNode(node).value();
if (!value)
continue;
- Node phantom(Phantom, node.codeOrigin);
-
- if (node.op() == GetLocal) {
- NodeIndex previousLocalAccess = NoNode;
- if (block->variablesAtHead.operand(node.local()) == nodeIndex
- && m_graph[node.child1()].op() == Phi) {
- // We expect this to be the common case.
- ASSERT(block->isInPhis(node.child1().index()));
- previousLocalAccess = node.child1().index();
- block->variablesAtHead.operand(node.local()) = previousLocalAccess;
- } else {
- ASSERT(indexInBlock > 0);
- // Must search for the previous access to this local.
- for (BlockIndex subIndexInBlock = indexInBlock; subIndexInBlock--;) {
- NodeIndex subNodeIndex = block->at(subIndexInBlock);
- Node& subNode = m_graph[subNodeIndex];
- if (!subNode.shouldGenerate())
- continue;
- if (!subNode.hasVariableAccessData())
- continue;
- if (subNode.local() != node.local())
- continue;
- // The two must have been unified.
- ASSERT(subNode.variableAccessData() == node.variableAccessData());
- previousLocalAccess = subNodeIndex;
- break;
- }
- if (previousLocalAccess == NoNode) {
- // The previous access must have been a Phi.
- for (BlockIndex phiIndexInBlock = block->phis.size(); phiIndexInBlock--;) {
- NodeIndex phiNodeIndex = block->phis[phiIndexInBlock];
- Node& phiNode = m_graph[phiNodeIndex];
- if (!phiNode.shouldGenerate())
- continue;
- if (phiNode.local() != node.local())
- continue;
- // The two must have been unified.
- ASSERT(phiNode.variableAccessData() == node.variableAccessData());
- previousLocalAccess = phiNodeIndex;
- break;
- }
- ASSERT(previousLocalAccess != NoNode);
+ CodeOrigin codeOrigin = node->codeOrigin;
+ AdjacencyList children = node->children;
+
+ if (node->op() == GetLocal) {
+ // GetLocals without a Phi child are guaranteed dead. We don't have to
+ // do anything about them.
+ if (!node->child1())
+ continue;
+
+ if (m_graph.m_form != LoadStore) {
+ VariableAccessData* variable = node->variableAccessData();
+ Node* phi = node->child1().node();
+ if (phi->op() == Phi
+ && block->variablesAtHead.operand(variable->local()) == phi
+ && block->variablesAtTail.operand(variable->local()) == node) {
+
+ // Keep the graph threaded for easy cases. This is improves compile
+ // times. It would be correct to just dethread here.
+
+ m_graph.convertToConstant(node, value);
+ Node* phantom = m_insertionSet.insertNode(
+ indexInBlock, SpecNone, PhantomLocal, codeOrigin,
+ OpInfo(variable), Edge(phi));
+ block->variablesAtHead.operand(variable->local()) = phantom;
+ block->variablesAtTail.operand(variable->local()) = phantom;
+
+ changed = true;
+
+ continue;
}
- }
- ASSERT(previousLocalAccess != NoNode);
-
- NodeIndex tailNodeIndex = block->variablesAtTail.operand(node.local());
- if (tailNodeIndex == nodeIndex)
- block->variablesAtTail.operand(node.local()) = previousLocalAccess;
- else {
- ASSERT(m_graph[tailNodeIndex].op() == Flush
- || m_graph[tailNodeIndex].op() == SetLocal
- || node.variableAccessData()->isCaptured());
+ m_graph.dethread();
}
- }
-
- phantom.children = node.children;
- phantom.ref();
+ } else
+ ASSERT(!node->hasVariableAccessData());
+
+ m_graph.convertToConstant(node, value);
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, codeOrigin, children);
- m_graph.convertToConstant(nodeIndex, value);
- NodeIndex phantomNodeIndex = m_graph.size();
- m_graph.append(phantom);
- m_insertionSet.append(indexInBlock, phantomNodeIndex);
-
changed = true;
}
m_state.reset();
- m_insertionSet.execute(*block);
+ m_insertionSet.execute(block);
return changed;
}
+#if !ASSERT_DISABLED
+ bool isCapturedAtOrAfter(BasicBlock* block, unsigned indexInBlock, int operand)
+ {
+ for (; indexInBlock < block->size(); ++indexInBlock) {
+ Node* node = block->at(indexInBlock);
+ if (!node->hasLocal())
+ continue;
+ if (node->local() != operand)
+ continue;
+ if (node->variableAccessData()->isCaptured())
+ return true;
+ }
+ return false;
+ }
+#endif // !ASSERT_DISABLED
+
void addStructureTransitionCheck(CodeOrigin codeOrigin, unsigned indexInBlock, JSCell* cell)
{
- Node weakConstant(WeakJSConstant, codeOrigin, OpInfo(cell));
- weakConstant.ref();
- weakConstant.predict(speculationFromValue(cell));
- NodeIndex weakConstantIndex = m_graph.size();
- m_graph.append(weakConstant);
- m_insertionSet.append(indexInBlock, weakConstantIndex);
+ Node* weakConstant = m_insertionSet.insertNode(
+ indexInBlock, speculationFromValue(cell), WeakJSConstant, codeOrigin, OpInfo(cell));
if (cell->structure()->transitionWatchpointSetIsStillValid()) {
- Node watchpoint(StructureTransitionWatchpoint, codeOrigin, OpInfo(cell->structure()), weakConstantIndex);
- watchpoint.ref();
- NodeIndex watchpointIndex = m_graph.size();
- m_graph.append(watchpoint);
- m_insertionSet.append(indexInBlock, watchpointIndex);
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, StructureTransitionWatchpoint, codeOrigin,
+ OpInfo(cell->structure()), Edge(weakConstant, CellUse));
return;
}
-
- Node check(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(cell->structure())), weakConstantIndex);
- check.ref();
- NodeIndex checkIndex = m_graph.size();
- m_graph.append(check);
- m_insertionSet.append(indexInBlock, checkIndex);
+
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, CheckStructure, codeOrigin,
+ OpInfo(m_graph.addStructureSet(cell->structure())), Edge(weakConstant, CellUse));
}
// This is necessary because the CFA may reach conclusions about constants based on its
@@ -464,9 +431,8 @@ private:
if (m_state.isValid())
continue;
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- switch (node.op()) {
+ Node* node = block->at(indexInBlock);
+ switch (node->op()) {
case Return:
case Throw:
case ThrowReferenceError:
@@ -475,24 +441,21 @@ private:
break;
default:
- Node forceOSRExit(ForceOSRExit, node.codeOrigin);
- forceOSRExit.ref();
- NodeIndex forceOSRExitIndex = m_graph.size();
- m_graph.append(forceOSRExit);
- m_insertionSet.append(indexInBlock, forceOSRExitIndex);
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, ForceOSRExit, node->codeOrigin);
changed = true;
break;
}
break;
}
m_state.reset();
- m_insertionSet.execute(*block);
+ m_insertionSet.execute(block);
return changed;
}
AbstractState m_state;
- InsertionSet<NodeIndex> m_insertionSet;
+ InsertionSet m_insertionSet;
};
bool performConstantFolding(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h b/Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h
deleted file mode 100644
index 93cb49c01..000000000
--- a/Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DFGCorrectableJumpPoint_h
-#define DFGCorrectableJumpPoint_h
-
-#if ENABLE(DFG_JIT)
-
-#include "LinkBuffer.h"
-#include "MacroAssembler.h"
-
-namespace JSC { namespace DFG {
-
-// This is a type-safe union of MacroAssembler::Jump and CodeLocationJump.
-// Furthermore, it supports the notion of branching (possibly conditionally, but
-// also possibly jumping unconditionally) to an out-of-line patchable jump.
-// Thus it goes through three states:
-//
-// 1) Label of unpatchable branch or jump (i.e. MacroAssembler::Jump).
-// 2) Label of patchable jump (i.e. MacroAssembler::PatchableJump).
-// 3) Corrected post-linking label of patchable jump (i.e. CodeLocationJump).
-//
-// The setting of state (1) corresponds to planting the in-line unpatchable
-// branch or jump. The state transition (1)->(2) corresponds to linking the
-// in-line branch or jump to the out-of-line patchable jump, and recording
-// the latter's label. The state transition (2)->(3) corresponds to recording
-// the out-of-line patchable jump's location after branch compaction has
-// completed.
-//
-// You can also go directly from the first state to the third state, if you
-// wish to use this class for in-line patchable jumps.
-
-class CorrectableJumpPoint {
-public:
- CorrectableJumpPoint(MacroAssembler::Jump check)
- : m_codeOffset(check.m_label.m_offset)
-#ifndef NDEBUG
- , m_mode(InitialJump)
-#endif
- {
-#if CPU(ARM_THUMB2)
- m_type = check.m_type;
- m_condition = check.m_condition;
-#endif
- }
-
- bool isSet()
- {
- return m_codeOffset != std::numeric_limits<uint32_t>::max();
- }
-
- void switchToLateJump(MacroAssembler::PatchableJump check)
- {
-#ifndef NDEBUG
- ASSERT(m_mode == InitialJump);
- m_mode = LateJump;
-#endif
- // Late jumps should only ever be real jumps.
-#if CPU(ARM_THUMB2)
- ASSERT(check.m_jump.m_type == ARMv7Assembler::JumpNoConditionFixedSize);
- ASSERT(check.m_jump.m_condition == ARMv7Assembler::ConditionInvalid);
- m_type = ARMv7Assembler::JumpNoConditionFixedSize;
- m_condition = ARMv7Assembler::ConditionInvalid;
-#endif
- m_codeOffset = check.m_jump.m_label.m_offset;
- }
-
- void correctInitialJump(LinkBuffer& linkBuffer)
- {
- ASSERT(m_mode == InitialJump);
-#if CPU(ARM_THUMB2)
- ASSERT(m_type == ARMv7Assembler::JumpNoConditionFixedSize);
- ASSERT(m_condition == ARMv7Assembler::ConditionInvalid);
-#endif
- correctJump(linkBuffer);
- }
-
- void correctLateJump(LinkBuffer& linkBuffer)
- {
- ASSERT(m_mode == LateJump);
- correctJump(linkBuffer);
- }
-
- MacroAssembler::Jump initialJump() const
- {
- ASSERT(m_mode == InitialJump);
- return getJump();
- }
-
- MacroAssembler::Jump lateJump() const
- {
- ASSERT(m_mode == LateJump);
- return getJump();
- }
-
- CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
-
-private:
- void correctJump(LinkBuffer& linkBuffer)
- {
-#ifndef NDEBUG
- m_mode = CorrectedJump;
-#endif
- MacroAssembler::Label label;
- label.m_label.m_offset = m_codeOffset;
- m_codeOffset = linkBuffer.offsetOf(label);
- }
-
- MacroAssembler::Jump getJump() const
- {
- MacroAssembler::Jump jump;
- jump.m_label.m_offset = m_codeOffset;
-#if CPU(ARM_THUMB2)
- jump.m_type = m_type;
- jump.m_condition = m_condition;
-#endif
- return jump;
- }
-
- unsigned m_codeOffset;
-
-#if CPU(ARM_THUMB2)
- ARMv7Assembler::JumpType m_type : 8;
- ARMv7Assembler::Condition m_condition : 8;
-#endif
-
-#ifndef NDEBUG
- enum Mode {
- InitialJump,
- LateJump,
- CorrectedJump
- };
-
- Mode m_mode;
-#endif
-};
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGCorrectableJumpPoint_h
diff --git a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
new file mode 100644
index 000000000..5cda11098
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGDCEPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+class DCEPhase : public Phase {
+public:
+ DCEPhase(Graph& graph)
+ : Phase(graph, "dead code elimination")
+ {
+ }
+
+ bool run()
+ {
+ // First reset the counts to 0 for all nodes.
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = block->size(); indexInBlock--;)
+ block->at(indexInBlock)->setRefCount(0);
+ for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+ block->phis[phiIndex]->setRefCount(0);
+ }
+
+ // Now find the roots:
+ // - Nodes that are must-generate.
+ // - Nodes that are reachable from type checks.
+ // Set their ref counts to 1 and put them on the worklist.
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = block->size(); indexInBlock--;) {
+ Node* node = block->at(indexInBlock);
+ DFG_NODE_DO_TO_CHILDREN(m_graph, node, findTypeCheckRoot);
+ if (!(node->flags() & NodeMustGenerate))
+ continue;
+ if (!node->postfixRef())
+ m_worklist.append(node);
+ }
+ }
+
+ while (!m_worklist.isEmpty()) {
+ Node* node = m_worklist.last();
+ m_worklist.removeLast();
+ ASSERT(node->shouldGenerate()); // It should not be on the worklist unless it's ref'ed.
+ DFG_NODE_DO_TO_CHILDREN(m_graph, node, countEdge);
+ }
+
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+
+ InsertionSet insertionSet(m_graph);
+
+ for (unsigned indexInBlock = block->size(); indexInBlock--;) {
+ Node* node = block->at(indexInBlock);
+ if (node->shouldGenerate())
+ continue;
+
+ switch (node->op()) {
+ case SetLocal: {
+ if (node->child1().isProved() || node->child1().useKind() == UntypedUse) {
+ // Consider the possibility that UInt32ToNumber is dead but its
+ // child isn't; if so then we should MovHint the child.
+ if (!node->child1()->shouldGenerate()
+ && node->child1()->op() == UInt32ToNumber)
+ node->child1() = node->child1()->child1();
+
+ if (!node->child1()->shouldGenerate()) {
+ node->setOpAndDefaultFlags(ZombieHint);
+ node->child1() = Edge();
+ break;
+ }
+ node->setOpAndDefaultFlags(MovHint);
+ break;
+ }
+ node->setOpAndDefaultFlags(MovHintAndCheck);
+ node->setRefCount(1);
+ break;
+ }
+
+ case GetLocal:
+ case SetArgument: {
+ // Leave them as not shouldGenerate.
+ break;
+ }
+
+ default: {
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
+ Edge edge = m_graph.m_varArgChildren[childIdx];
+
+ if (!edge || edge.isProved() || edge.useKind() == UntypedUse)
+ continue;
+
+ insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->codeOrigin, edge);
+ }
+
+ node->convertToPhantomUnchecked();
+ node->children.reset();
+ node->setRefCount(1);
+ break;
+ }
+
+ node->convertToPhantom();
+ eliminateIrrelevantPhantomChildren(node);
+ node->setRefCount(1);
+ break;
+ } }
+ }
+
+ insertionSet.execute(block);
+ }
+
+ m_graph.m_refCountState = ExactRefCount;
+
+ return true;
+ }
+
+private:
+ void findTypeCheckRoot(Node*, Edge edge)
+ {
+ // We may have an "unproved" untyped use for code that is unreachable. The CFA
+ // will just not have gotten around to it.
+ if (edge.isProved() || edge.useKind() == UntypedUse)
+ return;
+ if (!edge->postfixRef())
+ m_worklist.append(edge.node());
+ }
+
+ void countEdge(Node*, Edge edge)
+ {
+ // Don't count edges that are already counted for their type checks.
+ if (!(edge.isProved() || edge.useKind() == UntypedUse))
+ return;
+
+ if (edge->postfixRef())
+ return;
+ m_worklist.append(edge.node());
+ }
+
+ void eliminateIrrelevantPhantomChildren(Node* node)
+ {
+ for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
+ Edge edge = node->children.child(i);
+ if (!edge)
+ continue;
+ if (edge.isProved() || edge.useKind() == UntypedUse)
+ node->children.removeEdge(i--);
+ }
+ }
+
+ Vector<Node*, 128> m_worklist;
+};
+
+bool performDCE(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG DCE Phase");
+ return runPhase<DCEPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGDCEPhase.h b/Source/JavaScriptCore/dfg/DFGDCEPhase.h
new file mode 100644
index 000000000..2bb991306
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGDCEPhase.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGDCEPhase_h
+#define DFGDCEPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Global dead code elimination. Eliminates any node that is not NodeMustGenerate,
+// not used by any other live node, and not subject to any type check.
+
+bool performDCE(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGDCEPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
index a7fccd58f..bf445610d 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,34 +37,81 @@ Disassembler::Disassembler(Graph& graph)
: m_graph(graph)
{
m_labelForBlockIndex.resize(graph.m_blocks.size());
- m_labelForNodeIndex.resize(graph.size());
}
void Disassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
{
- m_graph.m_dominators.computeIfNecessary(m_graph);
+ Vector<DumpedOp> ops = createDumpList(linkBuffer);
+ for (unsigned i = 0; i < ops.size(); ++i)
+ out.print(ops[i].text);
+}
+
+void Disassembler::dump(LinkBuffer& linkBuffer)
+{
+ dump(WTF::dataFile(), linkBuffer);
+}
+
+void Disassembler::reportToProfiler(Profiler::Compilation* compilation, LinkBuffer& linkBuffer)
+{
+ Vector<DumpedOp> ops = createDumpList(linkBuffer);
- out.print("Generated JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITCode::DFGJIT), ", instruction count = ", m_graph.m_codeBlock->instructionCount(), ":\n");
+ for (unsigned i = 0; i < ops.size(); ++i) {
+ Profiler::OriginStack stack;
+
+ if (ops[i].codeOrigin.isSet())
+ stack = Profiler::OriginStack(*m_graph.m_vm.m_perBytecodeProfiler, m_graph.m_codeBlock, ops[i].codeOrigin);
+
+ compilation->addDescription(Profiler::CompiledBytecode(stack, ops[i].text));
+ }
+}
+
+void Disassembler::dumpHeader(PrintStream& out, LinkBuffer& linkBuffer)
+{
+ out.print("Generated DFG JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITCode::DFGJIT), ", instruction count = ", m_graph.m_codeBlock->instructionCount(), ":\n");
+ out.print(" Optimized with execution counter = ", m_graph.m_profiledBlock->jitExecuteCounter(), "\n");
+ out.print(" Source: ", m_graph.m_codeBlock->sourceCodeOnOneLine(), "\n");
out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
+}
+
+void Disassembler::append(Vector<Disassembler::DumpedOp>& result, StringPrintStream& out, CodeOrigin& previousOrigin)
+{
+ result.append(DumpedOp(previousOrigin, out.toCString()));
+ previousOrigin = CodeOrigin();
+ out.reset();
+}
+
+Vector<Disassembler::DumpedOp> Disassembler::createDumpList(LinkBuffer& linkBuffer)
+{
+ StringPrintStream out;
+ Vector<DumpedOp> result;
+
+ CodeOrigin previousOrigin = CodeOrigin();
+ dumpHeader(out, linkBuffer);
+ append(result, out, previousOrigin);
+
+ m_graph.m_dominators.computeIfNecessary(m_graph);
const char* prefix = " ";
const char* disassemblyPrefix = " ";
- NodeIndex lastNodeIndex = NoNode;
+ Node* lastNode = 0;
MacroAssembler::Label previousLabel = m_startOfCode;
for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
- dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNodeIndex);
+ dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_labelForBlockIndex[blockIndex], lastNode);
+ append(result, out, previousOrigin);
m_graph.dumpBlockHeader(out, prefix, blockIndex, Graph::DumpLivePhisOnly);
- NodeIndex lastNodeIndexForDisassembly = block->at(0);
+ append(result, out, previousOrigin);
+ Node* lastNodeForDisassembly = block->at(0);
for (size_t i = 0; i < block->size(); ++i) {
- if (!m_graph[block->at(i)].willHaveCodeGenOrOSR() && !Options::showAllDFGNodes())
+ if (!block->at(i)->willHaveCodeGenOrOSR() && !Options::showAllDFGNodes())
continue;
MacroAssembler::Label currentLabel;
- if (m_labelForNodeIndex[block->at(i)].isSet())
- currentLabel = m_labelForNodeIndex[block->at(i)];
+ HashMap<Node*, MacroAssembler::Label>::iterator iter = m_labelForNode.find(block->at(i));
+ if (iter != m_labelForNode.end())
+ currentLabel = iter->value;
else {
// Dump the last instruction by using the first label of the next block
// as the end point. This case is hit either during peephole compare
@@ -75,31 +122,36 @@ void Disassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
else
currentLabel = m_endOfMainPath;
}
- dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeIndexForDisassembly);
- m_graph.dumpCodeOrigin(out, prefix, lastNodeIndex, block->at(i));
+ dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, currentLabel, lastNodeForDisassembly);
+ append(result, out, previousOrigin);
+ previousOrigin = block->at(i)->codeOrigin;
+ if (m_graph.dumpCodeOrigin(out, prefix, lastNode, block->at(i))) {
+ append(result, out, previousOrigin);
+ previousOrigin = block->at(i)->codeOrigin;
+ }
m_graph.dump(out, prefix, block->at(i));
- lastNodeIndex = block->at(i);
- lastNodeIndexForDisassembly = block->at(i);
+ lastNode = block->at(i);
+ lastNodeForDisassembly = block->at(i);
}
}
- dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfMainPath, lastNodeIndex);
+ dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfMainPath, lastNode);
+ append(result, out, previousOrigin);
out.print(prefix, "(End Of Main Path)\n");
- dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, NoNode);
-}
-
-void Disassembler::dump(LinkBuffer& linkBuffer)
-{
- dump(WTF::dataFile(), linkBuffer);
+ append(result, out, previousOrigin);
+ dumpDisassembly(out, disassemblyPrefix, linkBuffer, previousLabel, m_endOfCode, 0);
+ append(result, out, previousOrigin);
+
+ return result;
}
-void Disassembler::dumpDisassembly(PrintStream& out, const char* prefix, LinkBuffer& linkBuffer, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, NodeIndex context)
+void Disassembler::dumpDisassembly(PrintStream& out, const char* prefix, LinkBuffer& linkBuffer, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, Node* context)
{
size_t prefixLength = strlen(prefix);
int amountOfNodeWhiteSpace;
- if (context == NoNode)
+ if (!context)
amountOfNodeWhiteSpace = 0;
else
- amountOfNodeWhiteSpace = Graph::amountOfNodeWhiteSpace(m_graph[context]);
+ amountOfNodeWhiteSpace = Graph::amountOfNodeWhiteSpace(context);
OwnArrayPtr<char> prefixBuffer = adoptArrayPtr(new char[prefixLength + amountOfNodeWhiteSpace + 1]);
strcpy(prefixBuffer.get(), prefix);
for (int i = 0; i < amountOfNodeWhiteSpace; ++i)
diff --git a/Source/JavaScriptCore/dfg/DFGDisassembler.h b/Source/JavaScriptCore/dfg/DFGDisassembler.h
index 8cc58c666..9f6c5b040 100644
--- a/Source/JavaScriptCore/dfg/DFGDisassembler.h
+++ b/Source/JavaScriptCore/dfg/DFGDisassembler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,6 +33,8 @@
#include "DFGCommon.h"
#include "LinkBuffer.h"
#include "MacroAssembler.h"
+#include <wtf/HashMap.h>
+#include <wtf/StringPrintStream.h>
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
@@ -49,9 +51,10 @@ public:
{
m_labelForBlockIndex[blockIndex] = label;
}
- void setForNode(NodeIndex nodeIndex, MacroAssembler::Label label)
+ void setForNode(Node* node, MacroAssembler::Label label)
{
- m_labelForNodeIndex[nodeIndex] = label;
+ ASSERT(label.isSet());
+ m_labelForNode.add(node, label);
}
void setEndOfMainPath(MacroAssembler::Label label)
{
@@ -64,14 +67,30 @@ public:
void dump(PrintStream&, LinkBuffer&);
void dump(LinkBuffer&);
+ void reportToProfiler(Profiler::Compilation*, LinkBuffer&);
private:
- void dumpDisassembly(PrintStream&, const char* prefix, LinkBuffer&, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, NodeIndex context);
+ void dumpHeader(PrintStream&, LinkBuffer&);
+
+ struct DumpedOp {
+ DumpedOp(CodeOrigin codeOrigin, CString text)
+ : codeOrigin(codeOrigin)
+ , text(text)
+ {
+ }
+
+ CodeOrigin codeOrigin;
+ CString text;
+ };
+ void append(Vector<DumpedOp>&, StringPrintStream&, CodeOrigin&);
+ Vector<DumpedOp> createDumpList(LinkBuffer&);
+
+ void dumpDisassembly(PrintStream&, const char* prefix, LinkBuffer&, MacroAssembler::Label& previousLabel, MacroAssembler::Label currentLabel, Node* context);
Graph& m_graph;
MacroAssembler::Label m_startOfCode;
Vector<MacroAssembler::Label> m_labelForBlockIndex;
- Vector<MacroAssembler::Label> m_labelForNodeIndex;
+ HashMap<Node*, MacroAssembler::Label> m_labelForNode;
MacroAssembler::Label m_endOfMainPath;
MacroAssembler::Label m_endOfCode;
};
diff --git a/Source/JavaScriptCore/dfg/DFGDoubleFormatState.h b/Source/JavaScriptCore/dfg/DFGDoubleFormatState.h
index 2aa0f3d4d..e469768a2 100644
--- a/Source/JavaScriptCore/dfg/DFGDoubleFormatState.h
+++ b/Source/JavaScriptCore/dfg/DFGDoubleFormatState.h
@@ -61,7 +61,7 @@ inline DoubleFormatState mergeDoubleFormatStates(DoubleFormatState a, DoubleForm
case CantUseDoubleFormat:
return CantUseDoubleFormat;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return CantUseDoubleFormat;
}
@@ -86,7 +86,7 @@ inline const char* doubleFormatStateToString(DoubleFormatState state)
case CantUseDoubleFormat:
return "ForceValue";
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp
index 8645c6dce..09649cc59 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,17 +33,23 @@
#if ENABLE(DFG_JIT)
#include "DFGArgumentsSimplificationPhase.h"
+#include "DFGBackwardsPropagationPhase.h"
#include "DFGByteCodeParser.h"
#include "DFGCFAPhase.h"
#include "DFGCFGSimplificationPhase.h"
+#include "DFGCPSRethreadingPhase.h"
#include "DFGCSEPhase.h"
#include "DFGConstantFoldingPhase.h"
+#include "DFGDCEPhase.h"
#include "DFGFixupPhase.h"
#include "DFGJITCompiler.h"
+#include "DFGPredictionInjectionPhase.h"
#include "DFGPredictionPropagationPhase.h"
-#include "DFGStructureCheckHoistingPhase.h"
+#include "DFGTypeCheckHoistingPhase.h"
+#include "DFGUnificationPhase.h"
#include "DFGValidate.h"
#include "DFGVirtualRegisterAllocationPhase.h"
+#include "Operations.h"
#include "Options.h"
namespace JSC { namespace DFG {
@@ -70,10 +76,12 @@ inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
if (!Options::useDFGJIT())
return false;
-
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("DFG compiling code block %p(%p) for executable %p, number of instructions = %u.\n", codeBlock, codeBlock->alternative(), codeBlock->ownerExecutable(), codeBlock->instructionCount());
-#endif
+
+ if (!Options::bytecodeRangeToDFGCompile().isInRange(codeBlock->instructionCount()))
+ return false;
+
+ if (logCompilationChanges())
+ dataLog("DFG compiling ", *codeBlock, ", number of instructions = ", codeBlock->instructionCount(), "\n");
// Derive our set of must-handle values. The compilation must be at least conservative
// enough to allow for OSR entry with these values.
@@ -98,54 +106,55 @@ inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
mustHandleValues[i] = exec->uncheckedR(operand).jsValue();
}
- Graph dfg(exec->globalData(), codeBlock, osrEntryBytecodeIndex, mustHandleValues);
+ Graph dfg(exec->vm(), codeBlock, osrEntryBytecodeIndex, mustHandleValues);
if (!parse(exec, dfg))
return false;
- if (compileMode == CompileFunction)
- dfg.predictArgumentTypes();
-
// By this point the DFG bytecode parser will have potentially mutated various tables
// in the CodeBlock. This is a good time to perform an early shrink, which is more
// powerful than a late one. It's safe to do so because we haven't generated any code
// that references any of the tables directly, yet.
codeBlock->shrinkToFit(CodeBlock::EarlyShrink);
- validate(dfg);
+ if (validationEnabled())
+ validate(dfg);
+
+ performCPSRethreading(dfg);
+ performUnification(dfg);
+ performPredictionInjection(dfg);
+
+ if (validationEnabled())
+ validate(dfg);
+
+ performBackwardsPropagation(dfg);
performPredictionPropagation(dfg);
performFixup(dfg);
- performStructureCheckHoisting(dfg);
- unsigned cnt = 1;
+ performTypeCheckHoisting(dfg);
+
dfg.m_fixpointState = FixpointNotConverged;
- for (;; ++cnt) {
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("DFG beginning optimization fixpoint iteration #%u.\n", cnt);
-#endif
- bool changed = false;
- performCFA(dfg);
- changed |= performConstantFolding(dfg);
- changed |= performArgumentsSimplification(dfg);
- changed |= performCFGSimplification(dfg);
- changed |= performCSE(dfg);
- if (!changed)
- break;
- dfg.resetExitStates();
- performFixup(dfg);
- }
- dfg.m_fixpointState = FixpointConverged;
+
performCSE(dfg);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("DFG optimization fixpoint converged in %u iterations.\n", cnt);
-#endif
+ performArgumentsSimplification(dfg);
+ performCPSRethreading(dfg); // This should usually be a no-op since CSE rarely dethreads, and arguments simplification rarely does anything.
+ performCFA(dfg);
+ performConstantFolding(dfg);
+ performCFGSimplification(dfg);
+
+ dfg.m_fixpointState = FixpointConverged;
+
+ performStoreElimination(dfg);
+ performCPSRethreading(dfg);
+ performDCE(dfg);
performVirtualRegisterAllocation(dfg);
GraphDumpMode modeForFinalValidate = DumpGraph;
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Graph after optimization:\n");
- dfg.dump();
- modeForFinalValidate = DontDumpGraph;
-#endif
- validate(dfg, modeForFinalValidate);
+ if (verboseCompilationEnabled()) {
+ dataLogF("Graph after optimization:\n");
+ dfg.dump();
+ modeForFinalValidate = DontDumpGraph;
+ }
+ if (validationEnabled())
+ validate(dfg, modeForFinalValidate);
JITCompiler dataFlowJIT(dfg);
bool result;
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.h b/Source/JavaScriptCore/dfg/DFGDriver.h
index 1964ec34a..2b504848d 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.h
+++ b/Source/JavaScriptCore/dfg/DFGDriver.h
@@ -33,7 +33,7 @@ namespace JSC {
class CodeBlock;
class JITCode;
-class JSGlobalData;
+class VM;
class MacroAssemblerCodePtr;
namespace DFG {
diff --git a/Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.cpp b/Source/JavaScriptCore/dfg/DFGEdge.cpp
index cfab2bd7b..35d78f80e 100644
--- a/Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.cpp
+++ b/Source/JavaScriptCore/dfg/DFGEdge.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,20 +24,25 @@
*/
#include "config.h"
-#include "DFGCorrectableJumpPoint.h"
+#include "DFGEdge.h"
#if ENABLE(DFG_JIT)
-#include "CodeBlock.h"
+#include "DFGNode.h"
namespace JSC { namespace DFG {
-CodeLocationJump CorrectableJumpPoint::codeLocationForRepatch(CodeBlock* codeBlock) const
+void Edge::dump(PrintStream& out) const
{
- ASSERT(m_mode == CorrectedJump);
- return CodeLocationJump(codeBlock->getJITCode().dataAddressAtOffset(m_codeOffset));
+ if (useKind() != UntypedUse) {
+ if (needsCheck())
+ out.print("Check:");
+ out.print(useKind(), ":");
+ }
+ out.print(node());
}
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGEdge.h b/Source/JavaScriptCore/dfg/DFGEdge.h
index 10988bf39..eb835b050 100644
--- a/Source/JavaScriptCore/dfg/DFGEdge.h
+++ b/Source/JavaScriptCore/dfg/DFGEdge.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
#if ENABLE(DFG_JIT)
#include "DFGCommon.h"
+#include "DFGUseKind.h"
namespace JSC { namespace DFG {
@@ -38,46 +39,90 @@ class AdjacencyList;
class Edge {
public:
- Edge()
- : m_encodedWord(makeWord(NoNode, UntypedUse))
+ explicit Edge(Node* node = 0, UseKind useKind = UntypedUse, ProofStatus proofStatus = NeedsCheck)
+#if USE(JSVALUE64)
+ : m_encodedWord(makeWord(node, useKind, proofStatus))
+#else
+ : m_node(node)
+ , m_encodedWord(makeWord(useKind, proofStatus))
+#endif
{
}
- explicit Edge(NodeIndex nodeIndex)
- : m_encodedWord(makeWord(nodeIndex, UntypedUse))
+#if USE(JSVALUE64)
+ Node* node() const { return bitwise_cast<Node*>(m_encodedWord >> shift()); }
+#else
+ Node* node() const { return m_node; }
+#endif
+
+ Node& operator*() const { return *node(); }
+ Node* operator->() const { return node(); }
+
+ void setNode(Node* node)
{
+#if USE(JSVALUE64)
+ m_encodedWord = makeWord(node, useKind(), proofStatus());
+#else
+ m_node = node;
+#endif
}
- Edge(NodeIndex nodeIndex, UseKind useKind)
- : m_encodedWord(makeWord(nodeIndex, useKind))
+ UseKind useKindUnchecked() const
{
+#if USE(JSVALUE64)
+ unsigned masked = m_encodedWord & (((1 << shift()) - 1));
+ unsigned shifted = masked >> 1;
+#else
+ unsigned shifted = static_cast<UseKind>(m_encodedWord) >> 1;
+#endif
+ ASSERT(shifted < static_cast<unsigned>(LastUseKind));
+ UseKind result = static_cast<UseKind>(shifted);
+ ASSERT(node() || result == UntypedUse);
+ return result;
}
-
- NodeIndex indexUnchecked() const { return m_encodedWord >> shift(); }
- NodeIndex index() const
+ UseKind useKind() const
{
- ASSERT(isSet());
- return m_encodedWord >> shift();
+ ASSERT(node());
+ return useKindUnchecked();
}
- void setIndex(NodeIndex nodeIndex)
+ void setUseKind(UseKind useKind)
{
- m_encodedWord = makeWord(nodeIndex, useKind());
+ ASSERT(node());
+#if USE(JSVALUE64)
+ m_encodedWord = makeWord(node(), useKind, proofStatus());
+#else
+ m_encodedWord = makeWord(useKind, proofStatus());
+#endif
}
- UseKind useKind() const
+ ProofStatus proofStatusUnchecked() const
{
- ASSERT(isSet());
- unsigned masked = m_encodedWord & (((1 << shift()) - 1));
- ASSERT(masked < LastUseKind);
- return static_cast<UseKind>(masked);
+ return proofStatusForIsProved(m_encodedWord & 1);
}
- void setUseKind(UseKind useKind)
+ ProofStatus proofStatus() const
{
- ASSERT(isSet());
- m_encodedWord = makeWord(index(), useKind);
+ ASSERT(node());
+ return proofStatusUnchecked();
+ }
+ void setProofStatus(ProofStatus proofStatus)
+ {
+ ASSERT(node());
+#if USE(JSVALUE64)
+ m_encodedWord = makeWord(node(), useKind(), proofStatus);
+#else
+ m_encodedWord = makeWord(useKind(), proofStatus);
+#endif
+ }
+ bool isProved() const
+ {
+ return proofStatus() == IsProved;
+ }
+ bool needsCheck() const
+ {
+ return proofStatus() == NeedsCheck;
}
- bool isSet() const { return indexUnchecked() != NoNode; }
+ bool isSet() const { return !!node(); }
typedef void* Edge::*UnspecifiedBoolType;
operator UnspecifiedBoolType*() const { return reinterpret_cast<UnspecifiedBoolType*>(isSet()); }
@@ -86,44 +131,64 @@ public:
bool operator==(Edge other) const
{
+#if USE(JSVALUE64)
return m_encodedWord == other.m_encodedWord;
+#else
+ return m_node == other.m_node && m_encodedWord == other.m_encodedWord;
+#endif
}
bool operator!=(Edge other) const
{
- return m_encodedWord != other.m_encodedWord;
+ return !(*this == other);
}
+
+ void dump(PrintStream&) const;
private:
friend class AdjacencyList;
- static uint32_t shift() { return 4; }
+#if USE(JSVALUE64)
+ static uint32_t shift() { return 6; }
- static int32_t makeWord(NodeIndex nodeIndex, UseKind useKind)
+ static uintptr_t makeWord(Node* node, UseKind useKind, ProofStatus proofStatus)
{
- ASSERT(static_cast<uint32_t>(((static_cast<int32_t>(nodeIndex) << shift()) >> shift())) == nodeIndex);
+ ASSERT(sizeof(node) == 8);
+ uintptr_t shiftedValue = bitwise_cast<uintptr_t>(node) << shift();
+ ASSERT((shiftedValue >> shift()) == bitwise_cast<uintptr_t>(node));
ASSERT(useKind >= 0 && useKind < LastUseKind);
- ASSERT(LastUseKind <= (1 << shift()));
- return (nodeIndex << shift()) | useKind;
+ ASSERT((static_cast<uintptr_t>(LastUseKind) << 1) <= (static_cast<uintptr_t>(1) << shift()));
+ return shiftedValue | (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
+ }
+
+#else
+ static uintptr_t makeWord(UseKind useKind, ProofStatus proofStatus)
+ {
+ return (static_cast<uintptr_t>(useKind) << 1) | DFG::isProved(proofStatus);
}
- int32_t m_encodedWord;
+ Node* m_node;
+#endif
+ // On 64-bit this holds both the pointer and the use kind, while on 32-bit
+ // this just holds the use kind. In both cases this may be hijacked by
+ // AdjacencyList for storing firstChild and numChildren.
+ uintptr_t m_encodedWord;
};
-inline bool operator==(Edge nodeUse, NodeIndex nodeIndex)
+inline bool operator==(Edge edge, Node* node)
{
- return nodeUse.indexUnchecked() == nodeIndex;
+ return edge.node() == node;
}
-inline bool operator==(NodeIndex nodeIndex, Edge nodeUse)
+inline bool operator==(Node* node, Edge edge)
{
- return nodeUse.indexUnchecked() == nodeIndex;
+ return edge.node() == node;
}
-inline bool operator!=(Edge nodeUse, NodeIndex nodeIndex)
+inline bool operator!=(Edge edge, Node* node)
{
- return nodeUse.indexUnchecked() != nodeIndex;
+ return edge.node() != node;
}
-inline bool operator!=(NodeIndex nodeIndex, Edge nodeUse)
+inline bool operator!=(Node* node, Edge edge)
{
- return nodeUse.indexUnchecked() != nodeIndex;
+ return edge.node() != node;
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGFPRInfo.h b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
index 6f968e282..27cbaf33d 100644
--- a/Source/JavaScriptCore/dfg/DFGFPRInfo.h
+++ b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
@@ -28,8 +28,8 @@
#if ENABLE(DFG_JIT)
-#include <assembler/MacroAssembler.h>
-#include <dfg/DFGRegisterBank.h>
+#include "DFGRegisterBank.h"
+#include "MacroAssembler.h"
namespace JSC { namespace DFG {
@@ -147,15 +147,15 @@ public:
static const char* debugName(FPRReg reg)
{
ASSERT(reg != InvalidFPRReg);
- ASSERT(reg < 32);
+ ASSERT(static_cast<int>(reg) < 32);
static const char* nameForRegister[32] = {
"d0", "d1", "d2", "d3",
"d4", "d5", "d6", "d7",
"d8", "d9", "d10", "d11",
- "d12", "d13", "d14", "d15"
- "d16", "d17", "d18", "d19"
- "d20", "d21", "d22", "d23"
- "d24", "d25", "d26", "d27"
+ "d12", "d13", "d14", "d15",
+ "d16", "d17", "d18", "d19",
+ "d20", "d21", "d22", "d23",
+ "d24", "d25", "d26", "d27",
"d28", "d29", "d30", "d31"
};
return nameForRegister[reg];
@@ -232,6 +232,69 @@ private:
#endif
+#if CPU(SH4)
+
+class FPRInfo {
+public:
+ typedef FPRReg RegisterType;
+ static const unsigned numberOfRegisters = 6;
+
+ // Temporary registers.
+ static const FPRReg fpRegT0 = SH4Registers::dr0;
+ static const FPRReg fpRegT1 = SH4Registers::dr2;
+ static const FPRReg fpRegT2 = SH4Registers::dr4;
+ static const FPRReg fpRegT3 = SH4Registers::dr6;
+ static const FPRReg fpRegT4 = SH4Registers::dr8;
+ static const FPRReg fpRegT5 = SH4Registers::dr10;
+
+ static const FPRReg returnValueFPR = SH4Registers::dr0;
+
+ static const FPRReg argumentFPR0 = SH4Registers::dr4;
+ static const FPRReg argumentFPR1 = SH4Registers::dr6;
+
+ static FPRReg toRegister(unsigned index)
+ {
+ static const FPRReg registerForIndex[numberOfRegisters] = {
+ fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
+
+ ASSERT(index < numberOfRegisters);
+ return registerForIndex[index];
+ }
+
+ static unsigned toIndex(FPRReg reg)
+ {
+ ASSERT(reg != InvalidFPRReg);
+ ASSERT(reg < 16);
+ static const unsigned indexForRegister[16] = {
+ 0, InvalidIndex, 1, InvalidIndex,
+ 2, InvalidIndex, 3, InvalidIndex,
+ 4, InvalidIndex, 5, InvalidIndex,
+ InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex
+ };
+ unsigned result = indexForRegister[reg];
+ ASSERT(result != InvalidIndex);
+ return result;
+ }
+
+ static const char* debugName(FPRReg reg)
+ {
+ ASSERT(reg != InvalidFPRReg);
+ ASSERT(reg < 16);
+ static const char* nameForRegister[16] = {
+ "dr0", "fr1", "dr2", "fr3",
+ "dr4", "fr5", "dr6", "fr7",
+ "dr8", "fr9", "dr10", "fr11",
+ "dr12", "fr13", "dr14", "fr15"
+ };
+ return nameForRegister[reg];
+ }
+
+private:
+ static const unsigned InvalidIndex = 0xffffffff;
+};
+
+#endif
+
typedef RegisterBank<FPRInfo>::iterator fpr_iterator;
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index b98d824f5..ac2842322 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +31,9 @@
#include "DFGGraph.h"
#include "DFGInsertionSet.h"
#include "DFGPhase.h"
+#include "DFGPredictionPropagationPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
@@ -38,13 +41,29 @@ class FixupPhase : public Phase {
public:
FixupPhase(Graph& graph)
: Phase(graph, "fixup")
+ , m_insertionSet(graph)
{
}
bool run()
{
+ ASSERT(m_graph.m_fixpointState == BeforeFixpoint);
+ ASSERT(m_graph.m_form == ThreadedCPS);
+
+ m_profitabilityChanged = false;
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
fixupBlock(m_graph.m_blocks[blockIndex].get());
+
+ while (m_profitabilityChanged) {
+ m_profitabilityChanged = false;
+
+ for (unsigned i = m_graph.m_argumentPositions.size(); i--;)
+ m_graph.m_argumentPositions[i].mergeArgumentUnboxingAwareness();
+
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
+ fixupSetLocalsInBlock(m_graph.m_blocks[blockIndex].get());
+ }
+
return true;
}
@@ -54,104 +73,418 @@ private:
if (!block)
return;
ASSERT(block->isReachable);
+ m_block = block;
for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
- m_compileIndex = block->at(m_indexInBlock);
- fixupNode(m_graph[m_compileIndex]);
+ m_currentNode = block->at(m_indexInBlock);
+ fixupNode(m_currentNode);
}
- m_insertionSet.execute(*block);
+ m_insertionSet.execute(block);
}
- void fixupNode(Node& node)
+ void fixupNode(Node* node)
{
- if (!node.shouldGenerate())
- return;
-
- NodeType op = node.op();
+ NodeType op = node->op();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" %s @%u: ", Graph::opName(op), m_compileIndex);
+ dataLogF(" %s @%u: ", Graph::opName(op), node->index());
#endif
switch (op) {
- case GetById: {
- if (m_graph.m_fixpointState > BeforeFixpoint)
+ case SetLocal: {
+ // This gets handled by fixupSetLocalsInBlock().
+ break;
+ }
+
+ case BitAnd:
+ case BitOr:
+ case BitXor:
+ case BitRShift:
+ case BitLShift:
+ case BitURShift:
+ case ArithIMul: {
+ fixIntEdge(node->child1());
+ fixIntEdge(node->child2());
+ break;
+ }
+
+ case UInt32ToNumber: {
+ setUseKindAndUnboxIfProfitable<KnownInt32Use>(node->child1());
+ break;
+ }
+
+ case DoubleAsInt32: {
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+
+ case ValueToInt32: {
+ if (node->child1()->shouldSpeculateInteger()) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ break;
+ }
+
+ if (node->child1()->shouldSpeculateNumber()) {
+ setUseKindAndUnboxIfProfitable<NumberUse>(node->child1());
break;
+ }
+
+ if (node->child1()->shouldSpeculateBoolean()) {
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
+ break;
+ }
- Node* nodePtr = &node;
+ setUseKindAndUnboxIfProfitable<NotCellUse>(node->child1());
+ break;
+ }
+
+ case Int32ToDouble: {
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
- if (!isInt32Speculation(m_graph[m_compileIndex].prediction()))
+ case ValueAdd: {
+ if (attemptToMakeIntegerAdd(node))
break;
- if (codeBlock()->identifier(nodePtr->identifierNumber()) != globalData().propertyNames->length)
+ if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
- ArrayProfile* arrayProfile =
- m_graph.baselineCodeBlockFor(nodePtr->codeOrigin)->getArrayProfile(
- nodePtr->codeOrigin.bytecodeIndex);
- ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
- if (arrayProfile) {
- arrayProfile->computeUpdatedPrediction(m_graph.baselineCodeBlockFor(node.codeOrigin));
- arrayMode = ArrayMode::fromObserved(arrayProfile, Array::Read, false);
- arrayMode = arrayMode.refine(
- m_graph[node.child1()].prediction(),
- m_graph[m_compileIndex].prediction());
- if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure()) {
- m_graph.ref(nodePtr->child1());
- Node checkStructure(CheckStructure, nodePtr->codeOrigin, OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())), nodePtr->child1().index());
- checkStructure.ref();
- NodeIndex checkStructureIndex = m_graph.size();
- m_graph.append(checkStructure);
- m_insertionSet.append(m_indexInBlock, checkStructureIndex);
- nodePtr = &m_graph[m_compileIndex];
+ }
+
+ // FIXME: Optimize for the case where one of the operands is the
+ // empty string. Also consider optimizing for the case where we don't
+ // believe either side is the emtpy string. Both of these things should
+ // be easy.
+
+ if (node->child1()->shouldSpeculateString()
+ && attemptToMakeFastStringAdd<StringUse>(node, node->child1(), node->child2()))
+ break;
+ if (node->child2()->shouldSpeculateString()
+ && attemptToMakeFastStringAdd<StringUse>(node, node->child2(), node->child1()))
+ break;
+ if (node->child1()->shouldSpeculateStringObject()
+ && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child1(), node->child2()))
+ break;
+ if (node->child2()->shouldSpeculateStringObject()
+ && attemptToMakeFastStringAdd<StringObjectUse>(node, node->child2(), node->child1()))
+ break;
+ if (node->child1()->shouldSpeculateStringOrStringObject()
+ && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child1(), node->child2()))
+ break;
+ if (node->child2()->shouldSpeculateStringOrStringObject()
+ && attemptToMakeFastStringAdd<StringOrStringObjectUse>(node, node->child2(), node->child1()))
+ break;
+ break;
+ }
+
+ case MakeRope: {
+ fixupMakeRope(node);
+ break;
+ }
+
+ case ArithAdd:
+ case ArithSub: {
+ if (attemptToMakeIntegerAdd(node))
+ break;
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
+ break;
+ }
+
+ case ArithNegate: {
+ if (m_graph.negateShouldSpeculateInteger(node)) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ break;
+ }
+ fixDoubleEdge<NumberUse>(node->child1());
+ break;
+ }
+
+ case ArithMul: {
+ if (m_graph.mulShouldSpeculateInteger(node)) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
+ }
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
+ break;
+ }
+
+ case ArithDiv: {
+ if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
+ && node->canSpeculateInteger()) {
+ if (isX86() || isARMv7s()) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
}
- } else {
- arrayMode = arrayMode.refine(
- m_graph[node.child1()].prediction(),
- m_graph[m_compileIndex].prediction());
+ injectInt32ToDoubleNode(node->child1());
+ injectInt32ToDoubleNode(node->child2());
+
+ // We don't need to do ref'ing on the children because we're stealing them from
+ // the original division.
+ Node* newDivision = m_insertionSet.insertNode(
+ m_indexInBlock, SpecDouble, *node);
+
+ node->setOp(DoubleAsInt32);
+ node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
+ break;
}
- if (!arrayMode.supportsLength())
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
+ break;
+ }
+
+ case ArithMin:
+ case ArithMax:
+ case ArithMod: {
+ if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
+ && node->canSpeculateInteger()) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
- nodePtr->setOp(GetArrayLength);
- ASSERT(nodePtr->flags() & NodeMustGenerate);
- nodePtr->clearFlags(NodeMustGenerate | NodeClobbersWorld);
- m_graph.deref(m_compileIndex);
- nodePtr->setArrayMode(arrayMode);
+ }
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
+ break;
+ }
- NodeIndex storage = checkArray(arrayMode, nodePtr->codeOrigin, nodePtr->child1().index(), NoNode, lengthNeedsStorage, nodePtr->shouldGenerate());
- if (storage == NoNode)
+ case ArithAbs: {
+ if (node->child1()->shouldSpeculateIntegerForArithmetic()
+ && node->canSpeculateInteger()) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
+ }
+ fixDoubleEdge<NumberUse>(node->child1());
+ break;
+ }
+
+ case ArithSqrt: {
+ fixDoubleEdge<NumberUse>(node->child1());
+ break;
+ }
+
+ case LogicalNot: {
+ if (node->child1()->shouldSpeculateBoolean())
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
+ else if (node->child1()->shouldSpeculateObjectOrOther())
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
+ else if (node->child1()->shouldSpeculateInteger())
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ else if (node->child1()->shouldSpeculateNumber())
+ fixDoubleEdge<NumberUse>(node->child1());
+ break;
+ }
- nodePtr = &m_graph[m_compileIndex];
- nodePtr->children.child2() = Edge(storage);
+ case TypeOf: {
+ if (node->child1()->shouldSpeculateString())
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
+ else if (node->child1()->shouldSpeculateCell())
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
- case GetIndexedPropertyStorage: {
- ASSERT(node.arrayMode().canCSEStorage());
+
+ case CompareEqConstant: {
break;
}
+
+ case CompareEq:
+ case CompareLess:
+ case CompareLessEq:
+ case CompareGreater:
+ case CompareGreaterEq: {
+ if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
+ }
+ if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
+ break;
+ }
+ if (node->op() != CompareEq)
+ break;
+ if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child2());
+ break;
+ }
+ if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child2());
+ break;
+ }
+ if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
+ break;
+ }
+ if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child2());
+ break;
+ }
+ if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
+ break;
+ }
+ break;
+ }
+
+ case CompareStrictEqConstant: {
+ break;
+ }
+
+ case CompareStrictEq: {
+ if (Node::shouldSpeculateBoolean(node->child1().node(), node->child2().node())) {
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child2());
+ break;
+ }
+ if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
+ }
+ if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
+ break;
+ }
+ if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString() && GPRInfo::numberOfRegisters >= 7) {
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child2());
+ break;
+ }
+ if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
+ break;
+ }
+ break;
+ }
+
+ case StringFromCharCode:
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ break;
+
+ case StringCharAt:
+ case StringCharCodeAt: {
+ // Currently we have no good way of refining these.
+ ASSERT(node->arrayMode() == ArrayMode(Array::String));
+ blessArrayOperation(node->child1(), node->child2(), node->child3());
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
+ }
+
case GetByVal: {
- node.setArrayMode(
- node.arrayMode().refine(
- m_graph[node.child1()].prediction(),
- m_graph[node.child2()].prediction()));
+ node->setArrayMode(
+ node->arrayMode().refine(
+ node->child1()->prediction(),
+ node->child2()->prediction(),
+ SpecNone, node->flags()));
- blessArrayOperation(node.child1(), node.child2(), 2);
+ blessArrayOperation(node->child1(), node->child2(), node->child3());
- Node* nodePtr = &m_graph[m_compileIndex];
- ArrayMode arrayMode = nodePtr->arrayMode();
+ ArrayMode arrayMode = node->arrayMode();
if (arrayMode.type() == Array::Double
&& arrayMode.arrayClass() == Array::OriginalArray
&& arrayMode.speculation() == Array::InBounds
&& arrayMode.conversion() == Array::AsIs
- && m_graph.globalObjectFor(nodePtr->codeOrigin)->arrayPrototypeChainIsSane()
- && !(nodePtr->flags() & NodeUsedAsOther))
- nodePtr->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
+ && m_graph.globalObjectFor(node->codeOrigin)->arrayPrototypeChainIsSane()
+ && !(node->flags() & NodeUsedAsOther))
+ node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
+
+ switch (node->arrayMode().type()) {
+ case Array::SelectUsingPredictions:
+ case Array::Unprofiled:
+ case Array::Undecided:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ case Array::Generic:
+#if USE(JSVALUE32_64)
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
+#endif
+ break;
+ case Array::ForceExit:
+ break;
+ default:
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
+ }
break;
}
- case StringCharAt:
- case StringCharCodeAt: {
- // Currently we have no good way of refining these.
- ASSERT(node.arrayMode() == ArrayMode(Array::String));
- blessArrayOperation(node.child1(), node.child2(), 2);
+
+ case PutByVal:
+ case PutByValAlias: {
+ Edge& child1 = m_graph.varArgChild(node, 0);
+ Edge& child2 = m_graph.varArgChild(node, 1);
+ Edge& child3 = m_graph.varArgChild(node, 2);
+
+ node->setArrayMode(
+ node->arrayMode().refine(
+ child1->prediction(),
+ child2->prediction(),
+ child3->prediction()));
+
+ blessArrayOperation(child1, child2, m_graph.varArgChild(node, 3));
+
+ switch (node->arrayMode().modeForPut().type()) {
+ case Array::SelectUsingPredictions:
+ case Array::Unprofiled:
+ case Array::Undecided:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ case Array::ForceExit:
+ case Array::Generic:
+#if USE(JSVALUE32_64)
+ // Due to register pressure on 32-bit, we speculate cell and
+ // ignore the base-is-not-cell case entirely by letting the
+ // baseline JIT handle it.
+ setUseKindAndUnboxIfProfitable<CellUse>(child1);
+#endif
+ break;
+ case Array::Int32:
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child3);
+ break;
+ case Array::Double:
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ fixDoubleEdge<RealNumberUse>(child3);
+ break;
+ case Array::Int8Array:
+ case Array::Int16Array:
+ case Array::Int32Array:
+ case Array::Uint8Array:
+ case Array::Uint8ClampedArray:
+ case Array::Uint16Array:
+ case Array::Uint32Array:
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ if (child3->shouldSpeculateInteger())
+ setUseKindAndUnboxIfProfitable<Int32Use>(child3);
+ else
+ fixDoubleEdge<NumberUse>(child3);
+ break;
+ case Array::Float32Array:
+ case Array::Float64Array:
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ fixDoubleEdge<NumberUse>(child3);
+ break;
+ default:
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ break;
+ }
break;
}
@@ -165,17 +498,20 @@ private:
// ignored. That's because ArrayPush can't handle any array modes that aren't
// array-related - so if refine() turned this into a "Generic" ArrayPush then
// that would break things.
- node.setArrayMode(
- node.arrayMode().refine(
- m_graph[node.child1()].prediction() & SpecCell,
+ node->setArrayMode(
+ node->arrayMode().refine(
+ node->child1()->prediction() & SpecCell,
SpecInt32,
- m_graph[node.child2()].prediction()));
- blessArrayOperation(node.child1(), node.child2(), 2);
+ node->child2()->prediction()));
+ blessArrayOperation(node->child1(), Edge(), node->child3());
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
- Node* nodePtr = &m_graph[m_compileIndex];
- switch (nodePtr->arrayMode().type()) {
+ switch (node->arrayMode().type()) {
+ case Array::Int32:
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
case Array::Double:
- fixDoubleEdge(1);
+ fixDoubleEdge<RealNumberUse>(node->child2());
break;
default:
break;
@@ -184,398 +520,909 @@ private:
}
case ArrayPop: {
- blessArrayOperation(node.child1(), node.child2(), 1);
+ blessArrayOperation(node->child1(), Edge(), node->child2());
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
break;
}
- case ValueToInt32: {
- if (m_graph[node.child1()].shouldSpeculateNumber()
- && node.mustGenerate()) {
- node.clearFlags(NodeMustGenerate);
- m_graph.deref(m_compileIndex);
+ case RegExpExec:
+ case RegExpTest: {
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
+ break;
+ }
+
+ case Branch: {
+ if (node->child1()->shouldSpeculateBoolean())
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
+ else if (node->child1()->shouldSpeculateObjectOrOther())
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
+ else if (node->child1()->shouldSpeculateInteger())
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ else if (node->child1()->shouldSpeculateNumber())
+ fixDoubleEdge<NumberUse>(node->child1());
+
+ Node* logicalNot = node->child1().node();
+ if (logicalNot->op() == LogicalNot) {
+
+ // Make sure that OSR exit can't observe the LogicalNot. If it can,
+ // then we must compute it and cannot peephole around it.
+ bool found = false;
+ bool ok = true;
+ for (unsigned i = m_indexInBlock; i--;) {
+ Node* candidate = m_block->at(i);
+ if (candidate == logicalNot) {
+ found = true;
+ break;
+ }
+ if (candidate->canExit()) {
+ ok = false;
+ found = true;
+ break;
+ }
+ }
+ ASSERT_UNUSED(found, found);
+
+ if (ok) {
+ Edge newChildEdge = logicalNot->child1();
+ if (newChildEdge->hasBooleanResult()) {
+ node->children.setChild1(newChildEdge);
+
+ BlockIndex toBeTaken = node->notTakenBlockIndex();
+ BlockIndex toBeNotTaken = node->takenBlockIndex();
+ node->setTakenBlockIndex(toBeTaken);
+ node->setNotTakenBlockIndex(toBeNotTaken);
+ }
+ }
}
break;
}
- case BitAnd:
- case BitOr:
- case BitXor:
- case BitRShift:
- case BitLShift:
- case BitURShift: {
- fixIntEdge(node.children.child1());
- fixIntEdge(node.children.child2());
+ case ToPrimitive: {
+ fixupToPrimitive(node);
break;
}
- case CompareEq:
- case CompareLess:
- case CompareLessEq:
- case CompareGreater:
- case CompareGreaterEq:
- case CompareStrictEq: {
- if (Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child2()]))
- break;
- if (!Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()]))
- break;
- fixDoubleEdge(0);
- fixDoubleEdge(1);
+ case ToString: {
+ fixupToString(node);
break;
}
- case LogicalNot: {
- if (m_graph[node.child1()].shouldSpeculateInteger())
- break;
- if (!m_graph[node.child1()].shouldSpeculateNumber())
- break;
- fixDoubleEdge(0);
+ case NewStringObject: {
+ setUseKindAndUnboxIfProfitable<KnownStringUse>(node->child1());
break;
}
- case Branch: {
- if (!m_graph[node.child1()].shouldSpeculateInteger()
- && m_graph[node.child1()].shouldSpeculateNumber())
- fixDoubleEdge(0);
-
- Node& myNode = m_graph[m_compileIndex]; // reload because the graph may have changed
- Edge logicalNotEdge = myNode.child1();
- Node& logicalNot = m_graph[logicalNotEdge];
- if (logicalNot.op() == LogicalNot
- && logicalNot.adjustedRefCount() == 1) {
- Edge newChildEdge = logicalNot.child1();
- if (m_graph[newChildEdge].hasBooleanResult()) {
- m_graph.ref(newChildEdge);
- m_graph.deref(logicalNotEdge);
- myNode.children.setChild1(newChildEdge);
-
- BlockIndex toBeTaken = myNode.notTakenBlockIndex();
- BlockIndex toBeNotTaken = myNode.takenBlockIndex();
- myNode.setTakenBlockIndex(toBeTaken);
- myNode.setNotTakenBlockIndex(toBeNotTaken);
+ case NewArray: {
+ for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
+ node->setIndexingType(
+ leastUpperBoundOfIndexingTypeAndType(
+ node->indexingType(), m_graph.varArgChild(node, i)->prediction()));
+ }
+ switch (node->indexingType()) {
+ case ALL_BLANK_INDEXING_TYPES:
+ CRASH();
+ break;
+ case ALL_UNDECIDED_INDEXING_TYPES:
+ if (node->numChildren()) {
+ // This will only happen if the children have no type predictions. We
+ // would have already exited by now, but insert a forced exit just to
+ // be safe.
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, ForceOSRExit, node->codeOrigin);
}
+ break;
+ case ALL_INT32_INDEXING_TYPES:
+ for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
+ setUseKindAndUnboxIfProfitable<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
+ break;
+ case ALL_DOUBLE_INDEXING_TYPES:
+ for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
+ setUseKindAndUnboxIfProfitable<RealNumberUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
+ break;
+ case ALL_CONTIGUOUS_INDEXING_TYPES:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
+ break;
+ default:
+ CRASH();
+ break;
}
break;
}
- case SetLocal: {
- if (node.variableAccessData()->isCaptured())
- break;
- if (!node.variableAccessData()->shouldUseDoubleFormat())
- break;
- fixDoubleEdge(0);
+ case NewArrayWithSize: {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
- case ArithAdd:
- case ValueAdd: {
- if (m_graph.addShouldSpeculateInteger(node))
+ case ConvertThis: {
+ if (isOtherSpeculation(node->child1()->prediction())) {
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, Phantom, node->codeOrigin,
+ Edge(node->child1().node(), OtherUse));
+ observeUseKindOnNode<OtherUse>(node->child1().node());
+ node->convertToWeakConstant(m_graph.globalThisObjectFor(node->codeOrigin));
break;
- if (!Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()]))
+ }
+
+ if (isObjectSpeculation(node->child1()->prediction())) {
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ node->convertToIdentity();
break;
- fixDoubleEdge(0);
- fixDoubleEdge(1);
+ }
+
break;
}
- case ArithSub: {
- if (m_graph.addShouldSpeculateInteger(node)
- && node.canSpeculateInteger())
- break;
- fixDoubleEdge(0);
- fixDoubleEdge(1);
+ case CreateThis: {
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
- case ArithNegate: {
- if (m_graph.negateShouldSpeculateInteger(node))
- break;
- fixDoubleEdge(0);
+ case GetMyArgumentByVal:
+ case GetMyArgumentByValSafe: {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
- case ArithMin:
- case ArithMax:
- case ArithMod: {
- if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
- && node.canSpeculateInteger())
- break;
- fixDoubleEdge(0);
- fixDoubleEdge(1);
+ case GetScopeRegisters:
+ case PutScopedVar:
+ case SkipTopScope:
+ case SkipScope:
+ case SetCallee:
+ case SetMyScope:
+ case PutStructure:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
+ case GetScope:
+ case GetButterfly: {
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
break;
}
- case ArithMul: {
- if (m_graph.mulShouldSpeculateInteger(node))
+ case GetById: {
+ if (!node->child1()->shouldSpeculateCell())
break;
- fixDoubleEdge(0);
- fixDoubleEdge(1);
- break;
- }
-
- case ArithDiv: {
- if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
- && node.canSpeculateInteger()) {
- if (isX86())
- break;
- injectInt32ToDoubleNode(0);
- injectInt32ToDoubleNode(1);
-
- Node& oldDivision = m_graph[m_compileIndex];
-
- Node newDivision = oldDivision;
- newDivision.setRefCount(2);
- newDivision.predict(SpecDouble);
- NodeIndex newDivisionIndex = m_graph.size();
-
- oldDivision.setOp(DoubleAsInt32);
- oldDivision.children.initialize(Edge(newDivisionIndex, DoubleUse), Edge(), Edge());
-
- m_graph.append(newDivision);
- m_insertionSet.append(m_indexInBlock, newDivisionIndex);
-
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ if (!isInt32Speculation(node->prediction()))
break;
+ if (codeBlock()->identifier(node->identifierNumber()) != vm().propertyNames->length)
+ break;
+ ArrayProfile* arrayProfile =
+ m_graph.baselineCodeBlockFor(node->codeOrigin)->getArrayProfile(
+ node->codeOrigin.bytecodeIndex);
+ ArrayMode arrayMode = ArrayMode(Array::SelectUsingPredictions);
+ if (arrayProfile) {
+ arrayProfile->computeUpdatedPrediction(m_graph.baselineCodeBlockFor(node->codeOrigin));
+ arrayMode = ArrayMode::fromObserved(arrayProfile, Array::Read, false);
+ arrayMode = arrayMode.refine(
+ node->child1()->prediction(), node->prediction());
+ if (arrayMode.supportsLength() && arrayProfile->hasDefiniteStructure()) {
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, CheckStructure, node->codeOrigin,
+ OpInfo(m_graph.addStructureSet(arrayProfile->expectedStructure())),
+ node->child1());
+ }
+ } else
+ arrayMode = arrayMode.refine(node->child1()->prediction(), node->prediction());
+
+ if (arrayMode.type() == Array::Generic) {
+ // Check if the input is something that we can't get array length for, but for which we
+ // could insert some conversions in order to transform it into something that we can do it
+ // for.
+ if (node->child1()->shouldSpeculateStringObject())
+ attemptToForceStringArrayModeByToStringConversion<StringObjectUse>(arrayMode, node);
+ else if (node->child1()->shouldSpeculateStringOrStringObject())
+ attemptToForceStringArrayModeByToStringConversion<StringOrStringObjectUse>(arrayMode, node);
}
- fixDoubleEdge(0);
- fixDoubleEdge(1);
- break;
- }
- case ArithAbs: {
- if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic()
- && node.canSpeculateInteger())
+ if (!arrayMode.supportsLength())
break;
- fixDoubleEdge(0);
+ node->setOp(GetArrayLength);
+ ASSERT(node->flags() & NodeMustGenerate);
+ node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ node->setArrayMode(arrayMode);
+
+ Node* storage = checkArray(arrayMode, node->codeOrigin, node->child1().node(), 0, lengthNeedsStorage);
+ if (!storage)
+ break;
+
+ node->child2() = Edge(storage);
break;
}
- case ArithSqrt: {
- fixDoubleEdge(0);
+ case GetByIdFlush: {
+ if (node->child1()->shouldSpeculateCell())
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
- case PutByVal:
- case PutByValAlias: {
- Edge child1 = m_graph.varArgChild(node, 0);
- Edge child2 = m_graph.varArgChild(node, 1);
- Edge child3 = m_graph.varArgChild(node, 2);
-
- node.setArrayMode(
- node.arrayMode().refine(
- m_graph[child1].prediction(),
- m_graph[child2].prediction(),
- m_graph[child3].prediction()));
-
- blessArrayOperation(child1, child2, 3);
-
- Node* nodePtr = &m_graph[m_compileIndex];
+ case CheckExecutable:
+ case CheckStructure:
+ case ForwardCheckStructure:
+ case StructureTransitionWatchpoint:
+ case ForwardStructureTransitionWatchpoint:
+ case CheckFunction:
+ case PutById:
+ case PutByIdDirect:
+ case CheckHasInstance: {
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ break;
+ }
- switch (nodePtr->arrayMode().modeForPut().type()) {
- case Array::Double:
- fixDoubleEdge(2);
- break;
- case Array::Int8Array:
- case Array::Int16Array:
- case Array::Int32Array:
- case Array::Uint8Array:
- case Array::Uint8ClampedArray:
- case Array::Uint16Array:
- case Array::Uint32Array:
- if (!m_graph[child3].shouldSpeculateInteger())
- fixDoubleEdge(2);
- break;
- case Array::Float32Array:
- case Array::Float64Array:
- fixDoubleEdge(2);
+ case CheckArray: {
+ switch (node->arrayMode().type()) {
+ case Array::String:
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
break;
default:
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
break;
}
- case NewArray: {
- for (unsigned i = m_graph.varArgNumChildren(node); i--;) {
- node.setIndexingType(
- leastUpperBoundOfIndexingTypeAndType(
- node.indexingType(), m_graph[m_graph.varArgChild(node, i)].prediction()));
- }
- if (node.indexingType() == ArrayWithDouble) {
- for (unsigned i = m_graph.varArgNumChildren(node); i--;)
- fixDoubleEdge(i);
- }
+ case Arrayify:
+ case ArrayifyToStructure: {
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ if (node->child2())
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ break;
+ }
+
+ case GetByOffset: {
+ if (!node->child1()->hasStorageResult())
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
break;
}
+ case PutByOffset: {
+ if (!node->child1()->hasStorageResult())
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child2());
+ break;
+ }
+
+ case InstanceOf: {
+ // FIXME: This appears broken: CheckHasInstance already does an unconditional cell
+ // check. https://bugs.webkit.org/show_bug.cgi?id=107479
+ if (!(node->child1()->prediction() & ~SpecCell))
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
+ break;
+ }
+
+ case Phantom:
+ case Identity: {
+ switch (node->child1().useKind()) {
+ case NumberUse:
+ if (node->child1()->shouldSpeculateIntegerForArithmetic())
+ node->child1().setUseKind(Int32Use);
+ break;
+ default:
+ break;
+ }
+ observeUseKindOnEdge(node->child1());
+ break;
+ }
+
+ case GetArrayLength:
+ case Nop:
+ case Phi:
+ case ForwardInt32ToDouble:
+ case PhantomPutStructure:
+ case GetIndexedPropertyStorage:
+ case LastNodeType:
+ case MovHint:
+ case MovHintAndCheck:
+ case ZombieHint:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
+#if !ASSERT_DISABLED
+ // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
+ case SetArgument:
+ case JSConstant:
+ case WeakJSConstant:
+ case GetLocal:
+ case GetCallee:
+ case Flush:
+ case PhantomLocal:
+ case GetLocalUnlinked:
+ case InlineStart:
+ case GetMyScope:
+ case GetScopedVar:
+ case GetGlobalVar:
+ case PutGlobalVar:
+ case GlobalVarWatchpoint:
+ case PutGlobalVarCheck:
+ case AllocationProfileWatchpoint:
+ case Call:
+ case Construct:
+ case NewObject:
+ case NewArrayBuffer:
+ case NewRegexp:
+ case Resolve:
+ case ResolveBase:
+ case ResolveBaseStrictPut:
+ case ResolveGlobal:
+ case Breakpoint:
+ case IsUndefined:
+ case IsBoolean:
+ case IsNumber:
+ case IsString:
+ case IsObject:
+ case IsFunction:
+ case CreateActivation:
+ case TearOffActivation:
+ case CreateArguments:
+ case PhantomArguments:
+ case TearOffArguments:
+ case GetMyArgumentsLength:
+ case GetMyArgumentsLengthSafe:
+ case CheckArgumentsNotCreated:
+ case NewFunction:
+ case NewFunctionNoCheck:
+ case NewFunctionExpression:
+ case Jump:
+ case Return:
+ case Throw:
+ case ThrowReferenceError:
+ case GarbageValue:
+ case CountExecution:
+ case ForceOSRExit:
+ case CheckWatchdogTimer:
+ break;
+#else
default:
break;
+#endif
}
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- if (!(node.flags() & NodeHasVarArgs)) {
+ if (!(node->flags() & NodeHasVarArgs)) {
dataLogF("new children: ");
- node.dumpChildren(WTF::dataFile());
+ node->dumpChildren(WTF::dataFile());
}
dataLogF("\n");
#endif
}
- NodeIndex addNode(const Node& node, bool shouldGenerate)
+ template<UseKind useKind>
+ void createToString(Node* node, Edge& edge)
+ {
+ edge.setNode(m_insertionSet.insertNode(
+ m_indexInBlock, SpecString, ToString, node->codeOrigin,
+ Edge(edge.node(), useKind)));
+ }
+
+ template<UseKind useKind>
+ void attemptToForceStringArrayModeByToStringConversion(ArrayMode& arrayMode, Node* node)
{
- NodeIndex nodeIndex = m_graph.size();
- m_graph.append(node);
- m_insertionSet.append(m_indexInBlock, nodeIndex);
- if (shouldGenerate)
- m_graph[nodeIndex].ref();
- return nodeIndex;
+ ASSERT(arrayMode == ArrayMode(Array::Generic));
+
+ if (!canOptimizeStringObjectAccess(node->codeOrigin))
+ return;
+
+ createToString<useKind>(node, node->child1());
+ arrayMode = ArrayMode(Array::String);
}
- NodeIndex checkArray(ArrayMode arrayMode, CodeOrigin codeOrigin, NodeIndex array, NodeIndex index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage, bool shouldGenerate = true)
+ template<UseKind useKind>
+ bool isStringObjectUse()
+ {
+ switch (useKind) {
+ case StringObjectUse:
+ case StringOrStringObjectUse:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ template<UseKind useKind>
+ void convertStringAddUse(Node* node, Edge& edge)
+ {
+ if (useKind == StringUse) {
+ // This preserves the binaryUseKind() invariant ot ValueAdd: ValueAdd's
+ // two edges will always have identical use kinds, which makes the
+ // decision process much easier.
+ observeUseKindOnNode<StringUse>(edge.node());
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, Phantom, node->codeOrigin,
+ Edge(edge.node(), StringUse));
+ edge.setUseKind(KnownStringUse);
+ return;
+ }
+
+ // FIXME: We ought to be able to have a ToPrimitiveToString node.
+
+ observeUseKindOnNode<useKind>(edge.node());
+ createToString<useKind>(node, edge);
+ }
+
+ void convertToMakeRope(Node* node)
+ {
+ node->setOpAndDefaultFlags(MakeRope);
+ fixupMakeRope(node);
+ }
+
+ void fixupMakeRope(Node* node)
+ {
+ for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
+ Edge& edge = node->children.child(i);
+ if (!edge)
+ break;
+ edge.setUseKind(KnownStringUse);
+ if (!m_graph.isConstant(edge.node()))
+ continue;
+ JSString* string = jsCast<JSString*>(m_graph.valueOfJSConstant(edge.node()).asCell());
+ if (string->length())
+ continue;
+
+ // Don't allow the MakeRope to have zero children.
+ if (!i && !node->child2())
+ break;
+
+ node->children.removeEdge(i--);
+ }
+
+ if (!node->child2()) {
+ ASSERT(!node->child3());
+ node->convertToIdentity();
+ }
+ }
+
+ void fixupToPrimitive(Node* node)
+ {
+ if (node->child1()->shouldSpeculateInteger()) {
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ node->convertToIdentity();
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateString()) {
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
+ node->convertToIdentity();
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateStringObject()
+ && canOptimizeStringObjectAccess(node->codeOrigin)) {
+ setUseKindAndUnboxIfProfitable<StringObjectUse>(node->child1());
+ node->convertToToString();
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateStringOrStringObject()
+ && canOptimizeStringObjectAccess(node->codeOrigin)) {
+ setUseKindAndUnboxIfProfitable<StringOrStringObjectUse>(node->child1());
+ node->convertToToString();
+ return;
+ }
+ }
+
+ void fixupToString(Node* node)
+ {
+ if (node->child1()->shouldSpeculateString()) {
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
+ node->convertToIdentity();
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateStringObject()
+ && canOptimizeStringObjectAccess(node->codeOrigin)) {
+ setUseKindAndUnboxIfProfitable<StringObjectUse>(node->child1());
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateStringOrStringObject()
+ && canOptimizeStringObjectAccess(node->codeOrigin)) {
+ setUseKindAndUnboxIfProfitable<StringOrStringObjectUse>(node->child1());
+ return;
+ }
+
+ if (node->child1()->shouldSpeculateCell()) {
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ return;
+ }
+ }
+
+ template<UseKind leftUseKind>
+ bool attemptToMakeFastStringAdd(Node* node, Edge& left, Edge& right)
+ {
+ Node* originalLeft = left.node();
+ Node* originalRight = right.node();
+
+ ASSERT(leftUseKind == StringUse || leftUseKind == StringObjectUse || leftUseKind == StringOrStringObjectUse);
+
+ if (isStringObjectUse<leftUseKind>() && !canOptimizeStringObjectAccess(node->codeOrigin))
+ return false;
+
+ convertStringAddUse<leftUseKind>(node, left);
+
+ if (right->shouldSpeculateString())
+ convertStringAddUse<StringUse>(node, right);
+ else if (right->shouldSpeculateStringObject() && canOptimizeStringObjectAccess(node->codeOrigin))
+ convertStringAddUse<StringObjectUse>(node, right);
+ else if (right->shouldSpeculateStringOrStringObject() && canOptimizeStringObjectAccess(node->codeOrigin))
+ convertStringAddUse<StringOrStringObjectUse>(node, right);
+ else {
+ // At this point we know that the other operand is something weird. The semantically correct
+ // way of dealing with this is:
+ //
+ // MakeRope(@left, ToString(ToPrimitive(@right)))
+ //
+ // So that's what we emit. NB, we need to do all relevant type checks on @left before we do
+ // anything to @right, since ToPrimitive may be effectful.
+
+ Node* toPrimitive = m_insertionSet.insertNode(
+ m_indexInBlock, resultOfToPrimitive(right->prediction()), ToPrimitive, node->codeOrigin,
+ Edge(right.node()));
+ Node* toString = m_insertionSet.insertNode(
+ m_indexInBlock, SpecString, ToString, node->codeOrigin, Edge(toPrimitive));
+
+ fixupToPrimitive(toPrimitive);
+ fixupToString(toString);
+
+ right.setNode(toString);
+ }
+
+ // We're doing checks up there, so we need to make sure that the
+ // *original* inputs to the addition are live up to here.
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, Phantom, node->codeOrigin,
+ Edge(originalLeft), Edge(originalRight));
+
+ convertToMakeRope(node);
+ return true;
+ }
+
+ bool isStringPrototypeMethodSane(Structure* stringPrototypeStructure, const Identifier& ident)
+ {
+ unsigned attributesUnused;
+ JSCell* specificValue;
+ PropertyOffset offset = stringPrototypeStructure->get(
+ vm(), ident, attributesUnused, specificValue);
+ if (!isValidOffset(offset))
+ return false;
+
+ if (!specificValue)
+ return false;
+
+ if (!specificValue->inherits(&JSFunction::s_info))
+ return false;
+
+ JSFunction* function = jsCast<JSFunction*>(specificValue);
+ if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)
+ return false;
+
+ return true;
+ }
+
+ bool canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin)
+ {
+ if (m_graph.hasExitSite(codeOrigin, NotStringObject))
+ return false;
+
+ Structure* stringObjectStructure = m_graph.globalObjectFor(codeOrigin)->stringObjectStructure();
+ ASSERT(stringObjectStructure->storedPrototype().isObject());
+ ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == &StringPrototype::s_info);
+
+ JSObject* stringPrototypeObject = asObject(stringObjectStructure->storedPrototype());
+ Structure* stringPrototypeStructure = stringPrototypeObject->structure();
+ if (stringPrototypeStructure->transitionWatchpointSetHasBeenInvalidated())
+ return false;
+
+ if (stringPrototypeStructure->isDictionary())
+ return false;
+
+ // We're being conservative here. We want DFG's ToString on StringObject to be
+ // used in both numeric contexts (that would call valueOf()) and string contexts
+ // (that would call toString()). We don't want the DFG to have to distinguish
+ // between the two, just because that seems like it would get confusing. So we
+ // just require both methods to be sane.
+ if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->valueOf))
+ return false;
+ if (!isStringPrototypeMethodSane(stringPrototypeStructure, vm().propertyNames->toString))
+ return false;
+
+ return true;
+ }
+
+ void fixupSetLocalsInBlock(BasicBlock* block)
+ {
+ if (!block)
+ return;
+ ASSERT(block->isReachable);
+ m_block = block;
+ for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
+ Node* node = m_currentNode = block->at(m_indexInBlock);
+ if (node->op() != SetLocal)
+ continue;
+
+ VariableAccessData* variable = node->variableAccessData();
+
+ if (!variable->shouldUnboxIfPossible())
+ continue;
+
+ if (variable->shouldUseDoubleFormat()) {
+ fixDoubleEdge<NumberUse>(node->child1(), ForwardSpeculation);
+ continue;
+ }
+
+ SpeculatedType predictedType = variable->argumentAwarePrediction();
+ if (isInt32Speculation(predictedType))
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ else if (isCellSpeculation(predictedType))
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ else if (isBooleanSpeculation(predictedType))
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
+ }
+ m_insertionSet.execute(block);
+ }
+
+ void findAndRemoveUnnecessaryStructureCheck(Node* array, const CodeOrigin& codeOrigin)
+ {
+ for (unsigned index = m_indexInBlock; index--;) {
+ Node* previousNode = m_block->at(index);
+ if (previousNode->codeOrigin != codeOrigin)
+ return;
+
+ if (previousNode->op() != CheckStructure)
+ continue;
+
+ if (previousNode->child1() != array)
+ continue;
+
+ previousNode->child1() = Edge();
+ previousNode->convertToPhantom();
+ return; // Assume we were smart enough to only insert one CheckStructure on the array.
+ }
+ }
+
+ Node* checkArray(ArrayMode arrayMode, const CodeOrigin& codeOrigin, Node* array, Node* index, bool (*storageCheck)(const ArrayMode&) = canCSEStorage)
{
ASSERT(arrayMode.isSpecific());
- m_graph.ref(array);
-
Structure* structure = arrayMode.originalArrayStructure(m_graph, codeOrigin);
+ Edge indexEdge = index ? Edge(index, Int32Use) : Edge();
+
if (arrayMode.doesConversion()) {
- if (index != NoNode)
- m_graph.ref(index);
-
if (structure) {
- Node arrayify(ArrayifyToStructure, codeOrigin, OpInfo(structure), OpInfo(arrayMode.asWord()), array, index);
- arrayify.ref();
- NodeIndex arrayifyIndex = m_graph.size();
- m_graph.append(arrayify);
- m_insertionSet.append(m_indexInBlock, arrayifyIndex);
+ if (m_indexInBlock > 0) {
+ // If the previous node was a CheckStructure inserted because of stuff
+ // that the array profile told us, then remove it, since we're going to be
+ // doing arrayification instead.
+ findAndRemoveUnnecessaryStructureCheck(array, codeOrigin);
+ }
+
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, ArrayifyToStructure, codeOrigin,
+ OpInfo(structure), OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
} else {
- Node arrayify(Arrayify, codeOrigin, OpInfo(arrayMode.asWord()), array, index);
- arrayify.ref();
- NodeIndex arrayifyIndex = m_graph.size();
- m_graph.append(arrayify);
- m_insertionSet.append(m_indexInBlock, arrayifyIndex);
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, Arrayify, codeOrigin,
+ OpInfo(arrayMode.asWord()), Edge(array, CellUse), indexEdge);
}
} else {
if (structure) {
- Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(structure)), array);
- checkStructure.ref();
- NodeIndex checkStructureIndex = m_graph.size();
- m_graph.append(checkStructure);
- m_insertionSet.append(m_indexInBlock, checkStructureIndex);
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, CheckStructure, codeOrigin,
+ OpInfo(m_graph.addStructureSet(structure)), Edge(array, CellUse));
} else {
- Node checkArray(CheckArray, codeOrigin, OpInfo(arrayMode.asWord()), array);
- checkArray.ref();
- NodeIndex checkArrayIndex = m_graph.size();
- m_graph.append(checkArray);
- m_insertionSet.append(m_indexInBlock, checkArrayIndex);
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, CheckArray, codeOrigin,
+ OpInfo(arrayMode.asWord()), Edge(array, CellUse));
}
}
if (!storageCheck(arrayMode))
- return NoNode;
-
- if (shouldGenerate)
- m_graph.ref(array);
+ return 0;
- if (arrayMode.usesButterfly())
- return addNode(Node(GetButterfly, codeOrigin, array), shouldGenerate);
+ if (arrayMode.usesButterfly()) {
+ return m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, GetButterfly, codeOrigin, Edge(array, KnownCellUse));
+ }
- return addNode(Node(GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode.asWord()), array), shouldGenerate);
+ return m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, GetIndexedPropertyStorage, codeOrigin,
+ OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
}
- void blessArrayOperation(Edge base, Edge index, unsigned storageChildIdx)
+ void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
{
- if (m_graph.m_fixpointState > BeforeFixpoint)
- return;
-
- Node* nodePtr = &m_graph[m_compileIndex];
+ Node* node = m_currentNode;
- switch (nodePtr->arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::ForceExit: {
- Node forceExit(ForceOSRExit, nodePtr->codeOrigin);
- forceExit.ref();
- NodeIndex forceExitIndex = m_graph.size();
- m_graph.append(forceExit);
- m_insertionSet.append(m_indexInBlock, forceExitIndex);
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, ForceOSRExit, node->codeOrigin);
return;
}
case Array::SelectUsingPredictions:
case Array::Unprofiled:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return;
case Array::Generic:
+ findAndRemoveUnnecessaryStructureCheck(base.node(), node->codeOrigin);
return;
default: {
- NodeIndex storage = checkArray(nodePtr->arrayMode(), nodePtr->codeOrigin, base.index(), index.indexUnchecked());
- if (storage == NoNode)
+ Node* storage = checkArray(node->arrayMode(), node->codeOrigin, base.node(), index.node());
+ if (!storage)
return;
- m_graph.child(m_graph[m_compileIndex], storageChildIdx) = Edge(storage);
+ storageChild = Edge(storage);
return;
} }
}
- void fixIntEdge(Edge& edge)
+ bool alwaysUnboxSimplePrimitives()
{
- Node& node = m_graph[edge];
- if (node.op() != ValueToInt32)
+#if USE(JSVALUE64)
+ return false;
+#else
+ // Any boolean, int, or cell value is profitable to unbox on 32-bit because it
+ // reduces traffic.
+ return true;
+#endif
+ }
+
+ template<UseKind useKind>
+ void observeUseKindOnNode(Node* node)
+ {
+ observeUseKindOnNode(node, useKind);
+ }
+
+ void observeUseKindOnEdge(Edge edge)
+ {
+ observeUseKindOnNode(edge.node(), edge.useKind());
+ }
+
+ void observeUseKindOnNode(Node* node, UseKind useKind)
+ {
+ if (node->op() != GetLocal)
return;
- if (!m_graph[node.child1()].shouldSpeculateInteger())
+ VariableAccessData* variable = node->variableAccessData();
+ switch (useKind) {
+ case Int32Use:
+ if (alwaysUnboxSimplePrimitives()
+ || isInt32Speculation(variable->prediction()))
+ m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
+ break;
+ case NumberUse:
+ case RealNumberUse:
+ if (variable->doubleFormatState() == UsingDoubleFormat)
+ m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
+ break;
+ case BooleanUse:
+ if (alwaysUnboxSimplePrimitives()
+ || isBooleanSpeculation(variable->prediction()))
+ m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
+ break;
+ case CellUse:
+ case ObjectUse:
+ case StringUse:
+ case KnownStringUse:
+ case StringObjectUse:
+ case StringOrStringObjectUse:
+ if (alwaysUnboxSimplePrimitives()
+ || isCellSpeculation(variable->prediction()))
+ m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Set the use kind of the edge. In the future (https://bugs.webkit.org/show_bug.cgi?id=110433),
+ // this can be used to notify the GetLocal that the variable is profitable to unbox.
+ template<UseKind useKind>
+ void setUseKindAndUnboxIfProfitable(Edge& edge)
+ {
+ observeUseKindOnNode<useKind>(edge.node());
+ edge.setUseKind(useKind);
+ }
+
+ void fixIntEdge(Edge& edge)
+ {
+ Node* node = edge.node();
+ if (node->op() != ValueToInt32) {
+ setUseKindAndUnboxIfProfitable<KnownInt32Use>(edge);
return;
+ }
- Edge oldEdge = edge;
- Edge newEdge = node.child1();
+ Edge newEdge = node->child1();
- m_graph.ref(newEdge);
- m_graph.deref(oldEdge);
+ if (newEdge.useKind() != Int32Use) {
+ edge.setUseKind(KnownInt32Use);
+ return;
+ }
+ ASSERT(newEdge->shouldSpeculateInteger());
edge = newEdge;
}
- void fixDoubleEdge(unsigned childIndex)
+ template<UseKind useKind>
+ void fixDoubleEdge(Edge& edge, SpeculationDirection direction = BackwardSpeculation)
{
- Node& source = m_graph[m_compileIndex];
- Edge& edge = m_graph.child(source, childIndex);
+ ASSERT(useKind == NumberUse || useKind == KnownNumberUse || useKind == RealNumberUse);
- if (m_graph[edge].prediction() & SpecDouble) {
- edge.setUseKind(DoubleUse);
+ if (edge->prediction() & SpecDouble) {
+ setUseKindAndUnboxIfProfitable<useKind>(edge);
return;
}
- injectInt32ToDoubleNode(childIndex);
+ injectInt32ToDoubleNode(edge, useKind, direction);
}
- void injectInt32ToDoubleNode(unsigned childIndex)
+ void injectInt32ToDoubleNode(Edge& edge, UseKind useKind = NumberUse, SpeculationDirection direction = BackwardSpeculation)
{
- Node& source = m_graph[m_compileIndex];
- Edge& edge = m_graph.child(source, childIndex);
-
- NodeIndex resultIndex = (NodeIndex)m_graph.size();
+ Node* result = m_insertionSet.insertNode(
+ m_indexInBlock, SpecDouble,
+ direction == BackwardSpeculation ? Int32ToDouble : ForwardInt32ToDouble,
+ m_currentNode->codeOrigin, Edge(edge.node(), NumberUse));
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("(replacing @%u->@%u with @%u->@%u) ",
- m_compileIndex, edge.index(), m_compileIndex, resultIndex);
+ dataLogF(
+ "(replacing @%u->@%u with @%u->@%u) ",
+ m_currentNode->index(), edge->index(), m_currentNode->index(), result->index());
#endif
-
- // Fix the edge up here because it's a reference that will be clobbered by
- // the append() below.
- NodeIndex oldIndex = edge.index();
- edge = Edge(resultIndex, DoubleUse);
- m_graph.append(Node(Int32ToDouble, source.codeOrigin, oldIndex));
- m_insertionSet.append(m_indexInBlock, resultIndex);
+ edge = Edge(result, useKind);
+ }
+
+ void truncateConstantToInt32(Edge& edge)
+ {
+ Node* oldNode = edge.node();
+
+ ASSERT(oldNode->hasConstant());
+ JSValue value = m_graph.valueOfJSConstant(oldNode);
+ if (value.isInt32())
+ return;
- Node& int32ToDouble = m_graph[resultIndex];
- int32ToDouble.predict(SpecDouble);
- int32ToDouble.ref();
+ value = jsNumber(JSC::toInt32(value.asNumber()));
+ ASSERT(value.isInt32());
+ edge.setNode(m_insertionSet.insertNode(
+ m_indexInBlock, SpecInt32, JSConstant, m_currentNode->codeOrigin,
+ OpInfo(codeBlock()->addOrFindConstant(value))));
}
+ void truncateConstantsIfNecessary(Node* node, AddSpeculationMode mode)
+ {
+ if (mode != SpeculateIntegerAndTruncateConstants)
+ return;
+
+ ASSERT(node->child1()->hasConstant() || node->child2()->hasConstant());
+ if (node->child1()->hasConstant())
+ truncateConstantToInt32(node->child1());
+ else
+ truncateConstantToInt32(node->child2());
+ }
+
+ bool attemptToMakeIntegerAdd(Node* node)
+ {
+ AddSpeculationMode mode = m_graph.addSpeculationMode(node);
+ if (mode == DontSpeculateInteger)
+ return false;
+
+ truncateConstantsIfNecessary(node, mode);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
+ return true;
+ }
+
+ BasicBlock* m_block;
unsigned m_indexInBlock;
- NodeIndex m_compileIndex;
- InsertionSet<NodeIndex> m_insertionSet;
+ Node* m_currentNode;
+ InsertionSet m_insertionSet;
+ bool m_profitabilityChanged;
};
bool performFixup(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGGPRInfo.h b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
index aa634cd15..d889cf513 100644
--- a/Source/JavaScriptCore/dfg/DFGGPRInfo.h
+++ b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
@@ -324,7 +324,6 @@ public:
// These registers match the baseline JIT.
static const GPRReg cachedResultRegister = X86Registers::eax;
- static const GPRReg timeoutCheckRegister = X86Registers::r12;
static const GPRReg callFrameRegister = X86Registers::r13;
static const GPRReg tagTypeNumberRegister = X86Registers::r14;
static const GPRReg tagMaskRegister = X86Registers::r15;
@@ -434,8 +433,8 @@ public:
static unsigned toIndex(GPRReg reg)
{
- ASSERT(reg != InvalidGPRReg);
- ASSERT(reg < 16);
+ ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg);
+ ASSERT(static_cast<unsigned>(reg) < 16);
static const unsigned indexForRegister[16] = { 0, 1, 2, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
unsigned result = indexForRegister[reg];
ASSERT(result != InvalidIndex);
@@ -444,8 +443,8 @@ public:
static const char* debugName(GPRReg reg)
{
- ASSERT(reg != InvalidGPRReg);
- ASSERT(reg < 16);
+ ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg);
+ ASSERT(static_cast<unsigned>(reg) < 16);
static const char* nameForRegister[16] = {
"r0", "r1", "r2", "r3",
"r4", "r5", "r6", "r7",
@@ -528,6 +527,75 @@ private:
#endif
+#if CPU(SH4)
+#define NUMBER_OF_ARGUMENT_REGISTERS 4
+
+class GPRInfo {
+public:
+ typedef GPRReg RegisterType;
+ static const unsigned numberOfRegisters = 10;
+
+ // Temporary registers.
+ static const GPRReg regT0 = SH4Registers::r0;
+ static const GPRReg regT1 = SH4Registers::r1;
+ static const GPRReg regT2 = SH4Registers::r2;
+ static const GPRReg regT3 = SH4Registers::r10;
+ static const GPRReg regT4 = SH4Registers::r4;
+ static const GPRReg regT5 = SH4Registers::r5;
+ static const GPRReg regT6 = SH4Registers::r6;
+ static const GPRReg regT7 = SH4Registers::r7;
+ static const GPRReg regT8 = SH4Registers::r8;
+ static const GPRReg regT9 = SH4Registers::r9;
+ // These registers match the baseline JIT.
+ static const GPRReg cachedResultRegister = regT0;
+ static const GPRReg cachedResultRegister2 = regT1;
+ static const GPRReg callFrameRegister = SH4Registers::fp;
+ // These constants provide the names for the general purpose argument & return value registers.
+ static const GPRReg argumentGPR0 = regT4;
+ static const GPRReg argumentGPR1 = regT5;
+ static const GPRReg argumentGPR2 = regT6;
+ static const GPRReg argumentGPR3 = regT7;
+ static const GPRReg nonArgGPR0 = regT3;
+ static const GPRReg nonArgGPR1 = regT8;
+ static const GPRReg nonArgGPR2 = regT9;
+ static const GPRReg returnValueGPR = regT0;
+ static const GPRReg returnValueGPR2 = regT1;
+ static const GPRReg nonPreservedNonReturnGPR = regT2;
+
+ static GPRReg toRegister(unsigned index)
+ {
+ ASSERT(index < numberOfRegisters);
+ static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8, regT9 };
+ return registerForIndex[index];
+ }
+
+ static unsigned toIndex(GPRReg reg)
+ {
+ ASSERT(reg != InvalidGPRReg);
+ ASSERT(reg < 14);
+ static const unsigned indexForRegister[14] = { 0, 1, 2, InvalidIndex, 4, 5, 6, 7, 8, 9, 3, InvalidIndex, InvalidIndex, InvalidIndex };
+ unsigned result = indexForRegister[reg];
+ ASSERT(result != InvalidIndex);
+ return result;
+ }
+
+ static const char* debugName(GPRReg reg)
+ {
+ ASSERT(reg != InvalidGPRReg);
+ ASSERT(reg < 16);
+ static const char* nameForRegister[16] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+ };
+ return nameForRegister[reg];
+ }
+
+private:
+ static const unsigned InvalidIndex = 0xffffffff;
+};
+
+#endif
+
typedef RegisterBank<GPRInfo>::iterator gpr_iterator;
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGGenerationInfo.h b/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
index 227433e0e..964543c1b 100644
--- a/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
+++ b/Source/JavaScriptCore/dfg/DFGGenerationInfo.h
@@ -1,6 +1,5 @@
-
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +29,7 @@
#if ENABLE(DFG_JIT)
#include "DFGJITCompiler.h"
+#include "DFGMinifiedID.h"
#include "DFGVariableEvent.h"
#include "DFGVariableEventStream.h"
#include "DataFormat.h"
@@ -48,56 +48,60 @@ namespace JSC { namespace DFG {
class GenerationInfo {
public:
GenerationInfo()
- : m_nodeIndex(NoNode)
+ : m_node(0)
, m_useCount(0)
, m_registerFormat(DataFormatNone)
, m_spillFormat(DataFormatNone)
, m_canFill(false)
, m_bornForOSR(false)
+ , m_isConstant(false)
{
}
- void initConstant(NodeIndex nodeIndex, uint32_t useCount)
+ void initConstant(Node* node, uint32_t useCount)
{
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = DataFormatNone;
m_spillFormat = DataFormatNone;
m_canFill = true;
m_bornForOSR = false;
+ m_isConstant = true;
ASSERT(m_useCount);
}
- void initInteger(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
+ void initInteger(Node* node, uint32_t useCount, GPRReg gpr)
{
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = DataFormatInteger;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
#if USE(JSVALUE64)
- void initJSValue(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS)
+ void initJSValue(Node* node, uint32_t useCount, GPRReg gpr, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = format;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
#elif USE(JSVALUE32_64)
- void initJSValue(NodeIndex nodeIndex, uint32_t useCount, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
+ void initJSValue(Node* node, uint32_t useCount, GPRReg tagGPR, GPRReg payloadGPR, DataFormat format = DataFormatJS)
{
ASSERT(format & DataFormatJS);
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = format;
m_spillFormat = DataFormatNone;
@@ -105,61 +109,68 @@ public:
u.v.tagGPR = tagGPR;
u.v.payloadGPR = payloadGPR;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
#endif
- void initCell(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
+ void initCell(Node* node, uint32_t useCount, GPRReg gpr)
{
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = DataFormatCell;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
- void initBoolean(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
+ void initBoolean(Node* node, uint32_t useCount, GPRReg gpr)
{
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = DataFormatBoolean;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
- void initDouble(NodeIndex nodeIndex, uint32_t useCount, FPRReg fpr)
+ void initDouble(Node* node, uint32_t useCount, FPRReg fpr)
{
ASSERT(fpr != InvalidFPRReg);
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = DataFormatDouble;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.fpr = fpr;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
- void initStorage(NodeIndex nodeIndex, uint32_t useCount, GPRReg gpr)
+ void initStorage(Node* node, uint32_t useCount, GPRReg gpr)
{
- m_nodeIndex = nodeIndex;
+ m_node = node;
m_useCount = useCount;
m_registerFormat = DataFormatStorage;
m_spillFormat = DataFormatNone;
m_canFill = false;
u.gpr = gpr;
m_bornForOSR = false;
+ m_isConstant = false;
ASSERT(m_useCount);
}
- // Get the index of the node that produced this value.
- NodeIndex nodeIndex() { return m_nodeIndex; }
+ // Get the node that produced this value.
+ Node* node() { return m_node; }
- void noticeOSRBirth(VariableEventStream& stream, NodeIndex nodeIndex, VirtualRegister virtualRegister)
+ void noticeOSRBirth(VariableEventStream& stream, Node* node, VirtualRegister virtualRegister)
{
- if (m_nodeIndex != nodeIndex)
+ if (m_isConstant)
+ return;
+ if (m_node != node)
return;
if (!alive())
return;
@@ -183,8 +194,8 @@ public:
bool result = !--m_useCount;
if (result && m_bornForOSR) {
- ASSERT(m_nodeIndex != NoNode);
- stream.appendAndLog(VariableEvent::death(m_nodeIndex));
+ ASSERT(m_node);
+ stream.appendAndLog(VariableEvent::death(MinifiedID(m_node)));
}
return result;
@@ -368,31 +379,34 @@ public:
private:
void appendFill(VariableEventKind kind, VariableEventStream& stream)
{
+ ASSERT(m_bornForOSR);
+
if (m_registerFormat == DataFormatDouble) {
- stream.appendAndLog(VariableEvent::fillFPR(kind, m_nodeIndex, u.fpr));
+ stream.appendAndLog(VariableEvent::fillFPR(kind, MinifiedID(m_node), u.fpr));
return;
}
#if USE(JSVALUE32_64)
if (m_registerFormat & DataFormatJS) {
- stream.appendAndLog(VariableEvent::fillPair(kind, m_nodeIndex, u.v.tagGPR, u.v.payloadGPR));
+ stream.appendAndLog(VariableEvent::fillPair(kind, MinifiedID(m_node), u.v.tagGPR, u.v.payloadGPR));
return;
}
#endif
- stream.appendAndLog(VariableEvent::fillGPR(kind, m_nodeIndex, u.gpr, m_registerFormat));
+ stream.appendAndLog(VariableEvent::fillGPR(kind, MinifiedID(m_node), u.gpr, m_registerFormat));
}
void appendSpill(VariableEventKind kind, VariableEventStream& stream, VirtualRegister virtualRegister)
{
- stream.appendAndLog(VariableEvent::spill(kind, m_nodeIndex, virtualRegister, m_spillFormat));
+ stream.appendAndLog(VariableEvent::spill(kind, MinifiedID(m_node), virtualRegister, m_spillFormat));
}
- // The index of the node whose result is stored in this virtual register.
- NodeIndex m_nodeIndex;
+ // The node whose result is stored in this virtual register.
+ Node* m_node;
uint32_t m_useCount;
DataFormat m_registerFormat;
DataFormat m_spillFormat;
bool m_canFill;
bool m_bornForOSR;
+ bool m_isConstant;
union {
GPRReg gpr;
FPRReg fpr;
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index c8008230a..612f6f0e5 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -27,7 +27,11 @@
#include "DFGGraph.h"
#include "CodeBlock.h"
+#include "CodeBlockWithJITType.h"
#include "DFGVariableAccessDataDump.h"
+#include "FunctionExecutableDump.h"
+#include "Operations.h"
+#include <wtf/CommaPrinter.h>
#if ENABLE(DFG_JIT)
@@ -40,18 +44,28 @@ static const char* dfgOpNames[] = {
#undef STRINGIZE_DFG_OP_ENUM
};
-Graph::Graph(JSGlobalData& globalData, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues)
- : m_globalData(globalData)
+Graph::Graph(VM& vm, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues)
+ : m_vm(vm)
, m_codeBlock(codeBlock)
+ , m_compilation(vm.m_perBytecodeProfiler ? vm.m_perBytecodeProfiler->newCompilation(codeBlock, Profiler::DFG) : 0)
, m_profiledBlock(codeBlock->alternative())
+ , m_allocator(vm.m_dfgState->m_allocator)
, m_hasArguments(false)
, m_osrEntryBytecodeIndex(osrEntryBytecodeIndex)
, m_mustHandleValues(mustHandleValues)
, m_fixpointState(BeforeFixpoint)
+ , m_form(LoadStore)
+ , m_unificationState(LocallyUnified)
+ , m_refCountState(EverythingIsLive)
{
ASSERT(m_profiledBlock);
}
+Graph::~Graph()
+{
+ m_allocator.freeAll();
+}
+
const char *Graph::opName(NodeType op)
{
return dfgOpNames[op];
@@ -63,18 +77,16 @@ static void printWhiteSpace(PrintStream& out, unsigned amount)
out.print(" ");
}
-void Graph::dumpCodeOrigin(PrintStream& out, const char* prefix, NodeIndex prevNodeIndex, NodeIndex nodeIndex)
+bool Graph::dumpCodeOrigin(PrintStream& out, const char* prefix, Node* previousNode, Node* currentNode)
{
- if (prevNodeIndex == NoNode)
- return;
+ if (!previousNode)
+ return false;
- Node& currentNode = at(nodeIndex);
- Node& previousNode = at(prevNodeIndex);
- if (previousNode.codeOrigin.inlineCallFrame == currentNode.codeOrigin.inlineCallFrame)
- return;
+ if (previousNode->codeOrigin.inlineCallFrame == currentNode->codeOrigin.inlineCallFrame)
+ return false;
- Vector<CodeOrigin> previousInlineStack = previousNode.codeOrigin.inlineStack();
- Vector<CodeOrigin> currentInlineStack = currentNode.codeOrigin.inlineStack();
+ Vector<CodeOrigin> previousInlineStack = previousNode->codeOrigin.inlineStack();
+ Vector<CodeOrigin> currentInlineStack = currentNode->codeOrigin.inlineStack();
unsigned commonSize = std::min(previousInlineStack.size(), currentInlineStack.size());
unsigned indexOfDivergence = commonSize;
for (unsigned i = 0; i < commonSize; ++i) {
@@ -84,47 +96,44 @@ void Graph::dumpCodeOrigin(PrintStream& out, const char* prefix, NodeIndex prevN
}
}
+ bool hasPrinted = false;
+
// Print the pops.
for (unsigned i = previousInlineStack.size(); i-- > indexOfDivergence;) {
out.print(prefix);
printWhiteSpace(out, i * 2);
- out.print("<-- #", previousInlineStack[i].inlineCallFrame->hash(), "\n");
+ out.print("<-- ", *previousInlineStack[i].inlineCallFrame, "\n");
+ hasPrinted = true;
}
// Print the pushes.
for (unsigned i = indexOfDivergence; i < currentInlineStack.size(); ++i) {
out.print(prefix);
printWhiteSpace(out, i * 2);
- out.print("--> #", currentInlineStack[i].inlineCallFrame->hash(), "\n");
+ out.print("--> ", *currentInlineStack[i].inlineCallFrame, "\n");
+ hasPrinted = true;
}
+
+ return hasPrinted;
}
-int Graph::amountOfNodeWhiteSpace(Node& node)
+int Graph::amountOfNodeWhiteSpace(Node* node)
{
- return (node.codeOrigin.inlineDepth() - 1) * 2;
+ return (node->codeOrigin.inlineDepth() - 1) * 2;
}
-void Graph::printNodeWhiteSpace(PrintStream& out, Node& node)
+void Graph::printNodeWhiteSpace(PrintStream& out, Node* node)
{
printWhiteSpace(out, amountOfNodeWhiteSpace(node));
}
-void Graph::dump(PrintStream& out, Edge edge)
+void Graph::dump(PrintStream& out, const char* prefix, Node* node)
{
- out.print(
- useKindToString(edge.useKind()),
- "@", edge.index(),
- AbbreviatedSpeculationDump(at(edge).prediction()));
-}
+ NodeType op = node->op();
-void Graph::dump(PrintStream& out, const char* prefix, NodeIndex nodeIndex)
-{
- Node& node = at(nodeIndex);
- NodeType op = node.op();
-
- unsigned refCount = node.refCount();
+ unsigned refCount = node->refCount();
bool skipped = !refCount;
- bool mustGenerate = node.mustGenerate();
+ bool mustGenerate = node->mustGenerate();
if (mustGenerate)
--refCount;
@@ -148,143 +157,118 @@ void Graph::dump(PrintStream& out, const char* prefix, NodeIndex nodeIndex)
// $# - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }.
// id# - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
// var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
- out.printf("% 4d:%s<%c%u:", (int)nodeIndex, skipped ? " skipped " : " ", mustGenerate ? '!' : ' ', refCount);
- if (node.hasResult() && !skipped && node.hasVirtualRegister())
- out.print(node.virtualRegister());
+ out.printf("% 4d:%s<%c%u:", (int)node->index(), skipped ? " skipped " : " ", mustGenerate ? '!' : ' ', refCount);
+ if (node->hasResult() && !skipped && node->hasVirtualRegister())
+ out.print(node->virtualRegister());
else
out.print("-");
out.print(">\t", opName(op), "(");
- bool hasPrinted = false;
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) {
- if (hasPrinted)
- out.print(", ");
- else
- hasPrinted = true;
+ CommaPrinter comma;
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
if (!m_varArgChildren[childIdx])
continue;
- dump(out, m_varArgChildren[childIdx]);
+ out.print(comma, m_varArgChildren[childIdx]);
}
} else {
- if (!!node.child1()) {
- dump(out, node.child1());
- hasPrinted = true;
- }
- if (!!node.child2()) {
- out.print(", "); // Whether or not there is a first child, we print a comma to ensure that we see a blank entry if there wasn't one.
- dump(out, node.child2());
- hasPrinted = true;
- }
- if (!!node.child3()) {
- if (!node.child1() && !node.child2())
- out.print(", "); // If the third child is the first non-empty one then make sure we have two blanks preceding it.
- out.print(", ");
- dump(out, node.child3());
- hasPrinted = true;
- }
+ if (!!node->child1() || !!node->child2() || !!node->child3())
+ out.print(comma, node->child1());
+ if (!!node->child2() || !!node->child3())
+ out.print(comma, node->child2());
+ if (!!node->child3())
+ out.print(comma, node->child3());
}
- if (strlen(nodeFlagsAsString(node.flags()))) {
- out.print(hasPrinted ? ", " : "", nodeFlagsAsString(node.flags()));
- hasPrinted = true;
- }
- if (node.hasArrayMode()) {
- out.print(hasPrinted ? ", " : "", node.arrayMode().toString());
- hasPrinted = true;
- }
- if (node.hasVarNumber()) {
- out.print(hasPrinted ? ", " : "", "var", node.varNumber());
- hasPrinted = true;
+ if (toCString(NodeFlagsDump(node->flags())) != "<empty>")
+ out.print(comma, NodeFlagsDump(node->flags()));
+ if (node->hasArrayMode())
+ out.print(comma, node->arrayMode());
+ if (node->hasVarNumber())
+ out.print(comma, node->varNumber());
+ if (node->hasRegisterPointer())
+ out.print(comma, "global", globalObjectFor(node->codeOrigin)->findRegisterIndex(node->registerPointer()), "(", RawPointer(node->registerPointer()), ")");
+ if (node->hasIdentifier())
+ out.print(comma, "id", node->identifierNumber(), "{", m_codeBlock->identifier(node->identifierNumber()).string(), "}");
+ if (node->hasStructureSet()) {
+ for (size_t i = 0; i < node->structureSet().size(); ++i)
+ out.print(comma, "struct(", RawPointer(node->structureSet()[i]), ": ", IndexingTypeDump(node->structureSet()[i]->indexingType()), ")");
}
- if (node.hasRegisterPointer()) {
- out.print(hasPrinted ? ", " : "", "global", globalObjectFor(node.codeOrigin)->findRegisterIndex(node.registerPointer()), "(", RawPointer(node.registerPointer()), ")");
- hasPrinted = true;
- }
- if (node.hasIdentifier()) {
- out.print(hasPrinted ? ", " : "", "id", node.identifierNumber(), "{", m_codeBlock->identifier(node.identifierNumber()).string(), "}");
- hasPrinted = true;
- }
- if (node.hasStructureSet()) {
- for (size_t i = 0; i < node.structureSet().size(); ++i) {
- out.print(hasPrinted ? ", " : "", "struct(", RawPointer(node.structureSet()[i]), ": ", indexingTypeToString(node.structureSet()[i]->indexingType()), ")");
- hasPrinted = true;
- }
+ if (node->hasStructure())
+ out.print(comma, "struct(", RawPointer(node->structure()), ": ", IndexingTypeDump(node->structure()->indexingType()), ")");
+ if (node->hasStructureTransitionData())
+ out.print(comma, "struct(", RawPointer(node->structureTransitionData().previousStructure), " -> ", RawPointer(node->structureTransitionData().newStructure), ")");
+ if (node->hasFunction()) {
+ out.print(comma, "function(", RawPointer(node->function()), ", ");
+ if (node->function()->inherits(&JSFunction::s_info)) {
+ JSFunction* function = jsCast<JSFunction*>(node->function());
+ if (function->isHostFunction())
+ out.print("<host function>");
+ else
+ out.print(FunctionExecutableDump(function->jsExecutable()));
+ } else
+ out.print("<not JSFunction>");
+ out.print(")");
}
- if (node.hasStructure()) {
- out.print(hasPrinted ? ", " : "", "struct(", RawPointer(node.structure()), ": ", indexingTypeToString(node.structure()->indexingType()), ")");
- hasPrinted = true;
+ if (node->hasExecutable()) {
+ if (node->executable()->inherits(&FunctionExecutable::s_info))
+ out.print(comma, "executable(", FunctionExecutableDump(jsCast<FunctionExecutable*>(node->executable())), ")");
+ else
+ out.print(comma, "executable(not function: ", RawPointer(node->executable()), ")");
}
- if (node.hasStructureTransitionData()) {
- out.print(hasPrinted ? ", " : "", "struct(", RawPointer(node.structureTransitionData().previousStructure), " -> ", RawPointer(node.structureTransitionData().newStructure), ")");
- hasPrinted = true;
+ if (node->hasFunctionDeclIndex()) {
+ FunctionExecutable* executable = m_codeBlock->functionDecl(node->functionDeclIndex());
+ out.print(comma, executable->inferredName().string(), "#", executable->hashFor(CodeForCall));
}
- if (node.hasFunction()) {
- out.print(hasPrinted ? ", " : "", RawPointer(node.function()));
- hasPrinted = true;
+ if (node->hasFunctionExprIndex()) {
+ FunctionExecutable* executable = m_codeBlock->functionExpr(node->functionExprIndex());
+ out.print(comma, executable->inferredName().string(), "#", executable->hashFor(CodeForCall));
}
- if (node.hasStorageAccessData()) {
- StorageAccessData& storageAccessData = m_storageAccessData[node.storageAccessDataIndex()];
- out.print(hasPrinted ? ", " : "", "id", storageAccessData.identifierNumber, "{", m_codeBlock->identifier(storageAccessData.identifierNumber).string(), "}");
+ if (node->hasStorageAccessData()) {
+ StorageAccessData& storageAccessData = m_storageAccessData[node->storageAccessDataIndex()];
+ out.print(comma, "id", storageAccessData.identifierNumber, "{", m_codeBlock->identifier(storageAccessData.identifierNumber).string(), "}");
out.print(", ", static_cast<ptrdiff_t>(storageAccessData.offset));
- hasPrinted = true;
}
- ASSERT(node.hasVariableAccessData() == node.hasLocal());
- if (node.hasVariableAccessData()) {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ ASSERT(node->hasVariableAccessData() == node->hasLocal());
+ if (node->hasVariableAccessData()) {
+ VariableAccessData* variableAccessData = node->variableAccessData();
int operand = variableAccessData->operand();
if (operandIsArgument(operand))
- out.print(hasPrinted ? ", " : "", "arg", operandToArgument(operand), "(", VariableAccessDataDump(*this, variableAccessData), ")");
+ out.print(comma, "arg", operandToArgument(operand), "(", VariableAccessDataDump(*this, variableAccessData), ")");
else
- out.print(hasPrinted ? ", " : "", "r", operand, "(", VariableAccessDataDump(*this, variableAccessData), ")");
- hasPrinted = true;
+ out.print(comma, "r", operand, "(", VariableAccessDataDump(*this, variableAccessData), ")");
}
- if (node.hasConstantBuffer()) {
- if (hasPrinted)
- out.print(", ");
- out.print(node.startConstant(), ":[");
- for (unsigned i = 0; i < node.numConstants(); ++i) {
- if (i)
- out.print(", ");
- out.print(m_codeBlock->constantBuffer(node.startConstant())[i].description());
- }
+ if (node->hasConstantBuffer()) {
+ out.print(comma);
+ out.print(node->startConstant(), ":[");
+ CommaPrinter anotherComma;
+ for (unsigned i = 0; i < node->numConstants(); ++i)
+ out.print(anotherComma, m_codeBlock->constantBuffer(node->startConstant())[i]);
out.print("]");
- hasPrinted = true;
- }
- if (node.hasIndexingType()) {
- if (hasPrinted)
- out.print(", ");
- out.print(indexingTypeToString(node.indexingType()));
}
+ if (node->hasIndexingType())
+ out.print(comma, IndexingTypeDump(node->indexingType()));
+ if (node->hasExecutionCounter())
+ out.print(comma, RawPointer(node->executionCounter()));
if (op == JSConstant) {
- out.print(hasPrinted ? ", " : "", "$", node.constantNumber());
- JSValue value = valueOfJSConstant(nodeIndex);
- out.print(" = ", value.description());
- hasPrinted = true;
- }
- if (op == WeakJSConstant) {
- out.print(hasPrinted ? ", " : "", RawPointer(node.weakConstant()));
- hasPrinted = true;
- }
- if (node.isBranch() || node.isJump()) {
- out.print(hasPrinted ? ", " : "", "T:#", node.takenBlockIndex());
- hasPrinted = true;
- }
- if (node.isBranch()) {
- out.print(hasPrinted ? ", " : "", "F:#", node.notTakenBlockIndex());
- hasPrinted = true;
+ out.print(comma, "$", node->constantNumber());
+ JSValue value = valueOfJSConstant(node);
+ out.print(" = ", value);
}
- out.print(hasPrinted ? ", " : "", "bc#", node.codeOrigin.bytecodeIndex);
- hasPrinted = true;
-
- (void)hasPrinted;
+ if (op == WeakJSConstant)
+ out.print(comma, RawPointer(node->weakConstant()));
+ if (node->isBranch() || node->isJump())
+ out.print(comma, "T:#", node->takenBlockIndex());
+ if (node->isBranch())
+ out.print(comma, "F:#", node->notTakenBlockIndex());
+ out.print(comma, "bc#", node->codeOrigin.bytecodeIndex);
out.print(")");
if (!skipped) {
- if (node.hasVariableAccessData())
- out.print(" predicting ", SpeculationDump(node.variableAccessData()->prediction()), node.variableAccessData()->shouldUseDoubleFormat() ? ", forcing double" : "");
- else if (node.hasHeapPrediction())
- out.print(" predicting ", SpeculationDump(node.getHeapPrediction()));
+ if (node->hasVariableAccessData())
+ out.print(" predicting ", SpeculationDump(node->variableAccessData()->prediction()), node->variableAccessData()->shouldUseDoubleFormat() ? ", forcing double" : "");
+ else if (node->hasHeapPrediction())
+ out.print(" predicting ", SpeculationDump(node->getHeapPrediction()));
}
out.print("\n");
@@ -294,7 +278,7 @@ void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BlockIndex blo
{
BasicBlock* block = m_blocks[blockIndex].get();
- out.print(prefix, "Block #", blockIndex, " (bc#", block->bytecodeBegin, "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
+ out.print(prefix, "Block #", blockIndex, " (", block->at(0)->codeOrigin, "): ", block->isReachable ? "" : "(skipped)", block->isOSRTarget ? " (OSR target)" : "", "\n");
out.print(prefix, " Predecessors:");
for (size_t i = 0; i < block->m_predecessors.size(); ++i)
out.print(" #", block->m_predecessors[i]);
@@ -317,17 +301,16 @@ void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BlockIndex blo
}
out.print(prefix, " Phi Nodes:");
for (size_t i = 0; i < block->phis.size(); ++i) {
- NodeIndex phiNodeIndex = block->phis[i];
- Node& phiNode = at(phiNodeIndex);
- if (!phiNode.shouldGenerate() && phiNodeDumpMode == DumpLivePhisOnly)
+ Node* phiNode = block->phis[i];
+ if (!phiNode->shouldGenerate() && phiNodeDumpMode == DumpLivePhisOnly)
continue;
- out.print(" @", phiNodeIndex, "->(");
- if (phiNode.child1()) {
- out.print("@", phiNode.child1().index());
- if (phiNode.child2()) {
- out.print(", @", phiNode.child2().index());
- if (phiNode.child3())
- out.print(", @", phiNode.child3().index());
+ out.print(" @", phiNode->index(), "<", phiNode->refCount(), ">->(");
+ if (phiNode->child1()) {
+ out.print("@", phiNode->child1()->index());
+ if (phiNode->child2()) {
+ out.print(", @", phiNode->child2()->index());
+ if (phiNode->child3())
+ out.print(", @", phiNode->child3()->index());
}
}
out.print(")", i + 1 < block->phis.size() ? "," : "");
@@ -337,7 +320,17 @@ void Graph::dumpBlockHeader(PrintStream& out, const char* prefix, BlockIndex blo
void Graph::dump(PrintStream& out)
{
- NodeIndex lastNodeIndex = NoNode;
+ dataLog("DFG for ", CodeBlockWithJITType(m_codeBlock, JITCode::DFGJIT), ":\n");
+ dataLog(" Fixpoint state: ", m_fixpointState, "; Form: ", m_form, "; Unification state: ", m_unificationState, "; Ref count state: ", m_refCountState, "\n");
+
+ out.print(" ArgumentPosition size: ", m_argumentPositions.size(), "\n");
+ for (size_t i = 0; i < m_argumentPositions.size(); ++i) {
+ out.print(" #", i, ": ");
+ ArgumentPosition& arguments = m_argumentPositions[i];
+ arguments.dump(out, this);
+ }
+
+ Node* lastNode = 0;
for (size_t b = 0; b < m_blocks.size(); ++b) {
BasicBlock* block = m_blocks[b].get();
if (!block)
@@ -353,9 +346,9 @@ void Graph::dump(PrintStream& out)
dumpOperands(block->variablesAtHead, out);
out.print("\n");
for (size_t i = 0; i < block->size(); ++i) {
- dumpCodeOrigin(out, "", lastNodeIndex, block->at(i));
+ dumpCodeOrigin(out, "", lastNode, block->at(i));
dump(out, "", block->at(i));
- lastNodeIndex = block->at(i);
+ lastNode = block->at(i);
}
out.print(" vars after: ");
if (block->cfaHasVisited)
@@ -369,62 +362,27 @@ void Graph::dump(PrintStream& out)
}
}
-// FIXME: Convert this to be iterative, not recursive.
-#define DO_TO_CHILDREN(node, thingToDo) do { \
- Node& _node = (node); \
- if (_node.flags() & NodeHasVarArgs) { \
- for (unsigned _childIdx = _node.firstChild(); \
- _childIdx < _node.firstChild() + _node.numChildren(); \
- _childIdx++) { \
- if (!!m_varArgChildren[_childIdx]) \
- thingToDo(m_varArgChildren[_childIdx]); \
- } \
- } else { \
- if (!_node.child1()) { \
- ASSERT(!_node.child2() \
- && !_node.child3()); \
- break; \
- } \
- thingToDo(_node.child1()); \
- \
- if (!_node.child2()) { \
- ASSERT(!_node.child3()); \
- break; \
- } \
- thingToDo(_node.child2()); \
- \
- if (!_node.child3()) \
- break; \
- thingToDo(_node.child3()); \
- } \
- } while (false)
-
-void Graph::refChildren(NodeIndex op)
-{
- DO_TO_CHILDREN(at(op), ref);
-}
-
-void Graph::derefChildren(NodeIndex op)
-{
- DO_TO_CHILDREN(at(op), deref);
-}
-
-void Graph::predictArgumentTypes()
+void Graph::dethread()
{
- ASSERT(m_codeBlock->numParameters() >= 1);
- for (size_t arg = 0; arg < static_cast<size_t>(m_codeBlock->numParameters()); ++arg) {
- ValueProfile* profile = m_profiledBlock->valueProfileForArgument(arg);
- if (!profile)
+ if (m_form == LoadStore)
+ return;
+
+ if (logCompilationChanges())
+ dataLog("Dethreading DFG graph.\n");
+
+ SamplingRegion samplingRegion("DFG Dethreading");
+
+ for (BlockIndex blockIndex = m_blocks.size(); blockIndex--;) {
+ BasicBlock* block = m_blocks[blockIndex].get();
+ if (!block)
continue;
-
- at(m_arguments[arg]).variableAccessData()->predict(profile->computeUpdatedPrediction());
-
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog(
- "Argument [", arg, "] prediction: ",
- SpeculationDump(at(m_arguments[arg]).variableAccessData()->prediction()), "\n");
-#endif
+ for (unsigned phiIndex = block->phis.size(); phiIndex--;) {
+ Node* phi = block->phis[phiIndex];
+ phi->children.reset();
+ }
}
+
+ m_form = LoadStore;
}
void Graph::handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex)
@@ -438,60 +396,6 @@ void Graph::handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIn
successor->m_predecessors.append(blockIndex);
}
-void Graph::collectGarbage()
-{
- // First reset the counts to 0 for all nodes.
- for (unsigned i = size(); i--;)
- at(i).setRefCount(0);
-
- // Now find the roots: the nodes that are must-generate. Set their ref counts to
- // 1 and put them on the worklist.
- Vector<NodeIndex, 128> worklist;
- for (BlockIndex blockIndex = 0; blockIndex < m_blocks.size(); ++blockIndex) {
- BasicBlock* block = m_blocks[blockIndex].get();
- if (!block)
- continue;
- for (unsigned indexInBlock = block->size(); indexInBlock--;) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = at(nodeIndex);
- if (!(node.flags() & NodeMustGenerate))
- continue;
- node.setRefCount(1);
- worklist.append(nodeIndex);
- }
- }
-
- while (!worklist.isEmpty()) {
- NodeIndex nodeIndex = worklist.last();
- worklist.removeLast();
- Node& node = at(nodeIndex);
- ASSERT(node.shouldGenerate()); // It should not be on the worklist unless it's ref'ed.
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- ++childIdx) {
- if (!m_varArgChildren[childIdx])
- continue;
- NodeIndex childNodeIndex = m_varArgChildren[childIdx].index();
- if (!at(childNodeIndex).ref())
- continue;
- worklist.append(childNodeIndex);
- }
- } else if (node.child1()) {
- if (at(node.child1()).ref())
- worklist.append(node.child1().index());
- if (node.child2()) {
- if (at(node.child2()).ref())
- worklist.append(node.child2().index());
- if (node.child3()) {
- if (at(node.child3()).ref())
- worklist.append(node.child3().index());
- }
- }
- }
- }
-}
-
void Graph::determineReachability()
{
Vector<BlockIndex, 16> worklist;
@@ -504,14 +408,14 @@ void Graph::determineReachability()
BasicBlock* block = m_blocks[index].get();
ASSERT(block->isLinked);
- Node& node = at(block->last());
- ASSERT(node.isTerminal());
+ Node* node = block->last();
+ ASSERT(node->isTerminal());
- if (node.isJump())
- handleSuccessor(worklist, index, node.takenBlockIndex());
- else if (node.isBranch()) {
- handleSuccessor(worklist, index, node.takenBlockIndex());
- handleSuccessor(worklist, index, node.notTakenBlockIndex());
+ if (node->isJump())
+ handleSuccessor(worklist, index, node->takenBlockIndex());
+ else if (node->isBranch()) {
+ handleSuccessor(worklist, index, node->takenBlockIndex());
+ handleSuccessor(worklist, index, node->notTakenBlockIndex());
}
}
}
@@ -531,8 +435,13 @@ void Graph::resetReachability()
void Graph::resetExitStates()
{
- for (unsigned i = size(); i--;)
- at(i).setCanExit(true);
+ for (BlockIndex blockIndex = 0; blockIndex < m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = block->size(); indexInBlock--;)
+ block->at(indexInBlock)->setCanExit(true);
+ }
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index b39845968..3e4e4b5bc 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,7 +35,10 @@
#include "DFGAssemblyHelpers.h"
#include "DFGBasicBlock.h"
#include "DFGDominators.h"
+#include "DFGLongLivedState.h"
#include "DFGNode.h"
+#include "DFGNodeAllocator.h"
+#include "DFGVariadicFunction.h"
#include "JSStack.h"
#include "MethodOfGettingAValueProfile.h"
#include <wtf/BitVector.h>
@@ -57,142 +60,126 @@ struct StorageAccessData {
struct ResolveGlobalData {
unsigned identifierNumber;
- unsigned resolveOperationsIndex;
- unsigned putToBaseOperationIndex;
+ ResolveOperations* resolveOperations;
+ PutToBaseOperation* putToBaseOperation;
unsigned resolvePropertyIndex;
};
struct ResolveOperationData {
unsigned identifierNumber;
- unsigned resolveOperationsIndex;
- unsigned putToBaseOperationIndex;
+ ResolveOperations* resolveOperations;
+ PutToBaseOperation* putToBaseOperation;
};
struct PutToBaseOperationData {
- unsigned putToBaseOperationIndex;
+ PutToBaseOperation* putToBaseOperation;
};
enum AddSpeculationMode {
DontSpeculateInteger,
- SpeculateIntegerButAlwaysWatchOverflow,
+ SpeculateIntegerAndTruncateConstants,
SpeculateInteger
};
-
+
//
// === Graph ===
//
-// The dataflow graph is an ordered vector of nodes.
// The order may be significant for nodes with side-effects (property accesses, value conversions).
// Nodes that are 'dead' remain in the vector with refCount 0.
-class Graph : public Vector<Node, 64> {
+class Graph {
public:
- Graph(JSGlobalData&, CodeBlock*, unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues);
-
- using Vector<Node, 64>::operator[];
- using Vector<Node, 64>::at;
-
- Node& operator[](Edge nodeUse) { return at(nodeUse.index()); }
- const Node& operator[](Edge nodeUse) const { return at(nodeUse.index()); }
-
- Node& at(Edge nodeUse) { return at(nodeUse.index()); }
- const Node& at(Edge nodeUse) const { return at(nodeUse.index()); }
-
- // Mark a node as being referenced.
- void ref(NodeIndex nodeIndex)
- {
- Node& node = at(nodeIndex);
- // If the value (before incrementing) was at refCount zero then we need to ref its children.
- if (node.ref())
- refChildren(nodeIndex);
- }
- void ref(Edge nodeUse)
- {
- ref(nodeUse.index());
- }
+ Graph(VM&, CodeBlock*, unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues);
+ ~Graph();
- void deref(NodeIndex nodeIndex)
- {
- if (!at(nodeIndex).refCount())
- dump();
- if (at(nodeIndex).deref())
- derefChildren(nodeIndex);
- }
- void deref(Edge nodeUse)
+ void changeChild(Edge& edge, Node* newNode)
{
- deref(nodeUse.index());
+ edge.setNode(newNode);
}
- void changeIndex(Edge& edge, NodeIndex newIndex, bool changeRef = true)
+ void changeEdge(Edge& edge, Edge newEdge)
{
- if (changeRef) {
- ref(newIndex);
- deref(edge.index());
- }
- edge.setIndex(newIndex);
- }
-
- void changeEdge(Edge& edge, Edge newEdge, bool changeRef = true)
- {
- if (changeRef) {
- ref(newEdge);
- deref(edge);
- }
edge = newEdge;
}
- void compareAndSwap(Edge& edge, NodeIndex oldIndex, NodeIndex newIndex, bool changeRef)
+ void compareAndSwap(Edge& edge, Node* oldNode, Node* newNode)
{
- if (edge.index() != oldIndex)
+ if (edge.node() != oldNode)
return;
- changeIndex(edge, newIndex, changeRef);
+ changeChild(edge, newNode);
}
- void compareAndSwap(Edge& edge, Edge oldEdge, Edge newEdge, bool changeRef)
+ void compareAndSwap(Edge& edge, Edge oldEdge, Edge newEdge)
{
if (edge != oldEdge)
return;
- changeEdge(edge, newEdge, changeRef);
+ changeEdge(edge, newEdge);
}
- void clearAndDerefChild1(Node& node)
+ void clearAndDerefChild(Node* node, unsigned index)
{
- if (!node.child1())
+ if (!node->children.child(index))
return;
- deref(node.child1());
- node.children.child1() = Edge();
+ node->children.setChild(index, Edge());
}
-
- void clearAndDerefChild2(Node& node)
+ void clearAndDerefChild1(Node* node) { clearAndDerefChild(node, 0); }
+ void clearAndDerefChild2(Node* node) { clearAndDerefChild(node, 1); }
+ void clearAndDerefChild3(Node* node) { clearAndDerefChild(node, 2); }
+
+ void performSubstitution(Node* node)
{
- if (!node.child2())
- return;
- deref(node.child2());
- node.children.child2() = Edge();
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
+ performSubstitutionForEdge(m_varArgChildren[childIdx]);
+ } else {
+ performSubstitutionForEdge(node->child1());
+ performSubstitutionForEdge(node->child2());
+ performSubstitutionForEdge(node->child3());
+ }
}
-
- void clearAndDerefChild3(Node& node)
+
+ void performSubstitutionForEdge(Edge& child)
{
- if (!node.child3())
+ // Check if this operand is actually unused.
+ if (!child)
return;
- deref(node.child3());
- node.children.child3() = Edge();
+
+ // Check if there is any replacement.
+ Node* replacement = child->replacement;
+ if (!replacement)
+ return;
+
+ child.setNode(replacement);
+
+ // There is definitely a replacement. Assert that the replacement does not
+ // have a replacement.
+ ASSERT(!child->replacement);
}
- // Call this if you've modified the reference counts of nodes that deal with
- // local variables. This is necessary because local variable references can form
- // cycles, and hence reference counting is not enough. This will reset the
- // reference counts according to reachability.
- void collectGarbage();
+#define DFG_DEFINE_ADD_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
+ templatePre typeParams templatePost Node* addNode(SpeculatedType type valueParamsComma valueParams) \
+ { \
+ Node* node = new (m_allocator) Node(valueArgs); \
+ node->predict(type); \
+ return node; \
+ }
+ DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_ADD_NODE)
+#undef DFG_DEFINE_ADD_NODE
+
+ void dethread();
- void convertToConstant(NodeIndex nodeIndex, unsigned constantNumber)
+ void convertToConstant(Node* node, unsigned constantNumber)
{
- at(nodeIndex).convertToConstant(constantNumber);
+ if (node->op() == GetLocal)
+ dethread();
+ else
+ ASSERT(!node->hasVariableAccessData());
+ node->convertToConstant(constantNumber);
}
- void convertToConstant(NodeIndex nodeIndex, JSValue value)
+ void convertToConstant(Node* node, JSValue value)
{
- convertToConstant(nodeIndex, m_codeBlock->addOrFindConstant(value));
+ convertToConstant(node, m_codeBlock->addOrFindConstant(value));
}
// CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
@@ -200,107 +187,120 @@ public:
enum PhiNodeDumpMode { DumpLivePhisOnly, DumpAllPhis };
void dumpBlockHeader(PrintStream&, const char* prefix, BlockIndex, PhiNodeDumpMode);
void dump(PrintStream&, Edge);
- void dump(PrintStream&, const char* prefix, NodeIndex);
- static int amountOfNodeWhiteSpace(Node&);
- static void printNodeWhiteSpace(PrintStream&, Node&);
+ void dump(PrintStream&, const char* prefix, Node*);
+ static int amountOfNodeWhiteSpace(Node*);
+ static void printNodeWhiteSpace(PrintStream&, Node*);
// Dump the code origin of the given node as a diff from the code origin of the
- // preceding node.
- void dumpCodeOrigin(PrintStream&, const char* prefix, NodeIndex, NodeIndex);
+ // preceding node. Returns true if anything was printed.
+ bool dumpCodeOrigin(PrintStream&, const char* prefix, Node* previousNode, Node* currentNode);
BlockIndex blockIndexForBytecodeOffset(Vector<BlockIndex>& blocks, unsigned bytecodeBegin);
- SpeculatedType getJSConstantSpeculation(Node& node)
+ SpeculatedType getJSConstantSpeculation(Node* node)
{
- return speculationFromValue(node.valueOfJSConstant(m_codeBlock));
+ return speculationFromValue(node->valueOfJSConstant(m_codeBlock));
}
- AddSpeculationMode addSpeculationMode(Node& add)
+ AddSpeculationMode addSpeculationMode(Node* add, bool leftShouldSpeculateInteger, bool rightShouldSpeculateInteger)
{
- ASSERT(add.op() == ValueAdd || add.op() == ArithAdd || add.op() == ArithSub);
+ ASSERT(add->op() == ValueAdd || add->op() == ArithAdd || add->op() == ArithSub);
- Node& left = at(add.child1());
- Node& right = at(add.child2());
+ Node* left = add->child1().node();
+ Node* right = add->child2().node();
- if (left.hasConstant())
- return addImmediateShouldSpeculateInteger(add, right, left);
- if (right.hasConstant())
- return addImmediateShouldSpeculateInteger(add, left, right);
+ if (left->hasConstant())
+ return addImmediateShouldSpeculateInteger(add, rightShouldSpeculateInteger, left);
+ if (right->hasConstant())
+ return addImmediateShouldSpeculateInteger(add, leftShouldSpeculateInteger, right);
- return (Node::shouldSpeculateIntegerExpectingDefined(left, right) && add.canSpeculateInteger()) ? SpeculateInteger : DontSpeculateInteger;
+ return (leftShouldSpeculateInteger && rightShouldSpeculateInteger && add->canSpeculateInteger()) ? SpeculateInteger : DontSpeculateInteger;
}
- bool addShouldSpeculateInteger(Node& add)
+ AddSpeculationMode valueAddSpeculationMode(Node* add)
{
- return addSpeculationMode(add) != DontSpeculateInteger;
+ return addSpeculationMode(add, add->child1()->shouldSpeculateIntegerExpectingDefined(), add->child2()->shouldSpeculateIntegerExpectingDefined());
}
- bool mulShouldSpeculateInteger(Node& mul)
+ AddSpeculationMode arithAddSpeculationMode(Node* add)
{
- ASSERT(mul.op() == ArithMul);
-
- Node& left = at(mul.child1());
- Node& right = at(mul.child2());
+ return addSpeculationMode(add, add->child1()->shouldSpeculateIntegerForArithmetic(), add->child2()->shouldSpeculateIntegerForArithmetic());
+ }
+
+ AddSpeculationMode addSpeculationMode(Node* add)
+ {
+ if (add->op() == ValueAdd)
+ return valueAddSpeculationMode(add);
- return Node::shouldSpeculateIntegerForArithmetic(left, right) && mul.canSpeculateInteger();
+ return arithAddSpeculationMode(add);
+ }
+
+ bool addShouldSpeculateInteger(Node* add)
+ {
+ return addSpeculationMode(add) != DontSpeculateInteger;
}
- bool negateShouldSpeculateInteger(Node& negate)
+ bool mulShouldSpeculateInteger(Node* mul)
{
- ASSERT(negate.op() == ArithNegate);
- return at(negate.child1()).shouldSpeculateIntegerForArithmetic() && negate.canSpeculateInteger();
+ ASSERT(mul->op() == ArithMul);
+
+ Node* left = mul->child1().node();
+ Node* right = mul->child2().node();
+
+ return Node::shouldSpeculateIntegerForArithmetic(left, right) && mul->canSpeculateInteger();
}
- bool addShouldSpeculateInteger(NodeIndex nodeIndex)
+ bool negateShouldSpeculateInteger(Node* negate)
{
- return addShouldSpeculateInteger(at(nodeIndex));
+ ASSERT(negate->op() == ArithNegate);
+ return negate->child1()->shouldSpeculateIntegerForArithmetic() && negate->canSpeculateInteger();
}
// Helper methods to check nodes for constants.
- bool isConstant(NodeIndex nodeIndex)
+ bool isConstant(Node* node)
{
- return at(nodeIndex).hasConstant();
+ return node->hasConstant();
}
- bool isJSConstant(NodeIndex nodeIndex)
+ bool isJSConstant(Node* node)
{
- return at(nodeIndex).hasConstant();
+ return node->hasConstant();
}
- bool isInt32Constant(NodeIndex nodeIndex)
+ bool isInt32Constant(Node* node)
{
- return at(nodeIndex).isInt32Constant(m_codeBlock);
+ return node->isInt32Constant(m_codeBlock);
}
- bool isDoubleConstant(NodeIndex nodeIndex)
+ bool isDoubleConstant(Node* node)
{
- return at(nodeIndex).isDoubleConstant(m_codeBlock);
+ return node->isDoubleConstant(m_codeBlock);
}
- bool isNumberConstant(NodeIndex nodeIndex)
+ bool isNumberConstant(Node* node)
{
- return at(nodeIndex).isNumberConstant(m_codeBlock);
+ return node->isNumberConstant(m_codeBlock);
}
- bool isBooleanConstant(NodeIndex nodeIndex)
+ bool isBooleanConstant(Node* node)
{
- return at(nodeIndex).isBooleanConstant(m_codeBlock);
+ return node->isBooleanConstant(m_codeBlock);
}
- bool isCellConstant(NodeIndex nodeIndex)
+ bool isCellConstant(Node* node)
{
- if (!isJSConstant(nodeIndex))
+ if (!isJSConstant(node))
return false;
- JSValue value = valueOfJSConstant(nodeIndex);
+ JSValue value = valueOfJSConstant(node);
return value.isCell() && !!value;
}
- bool isFunctionConstant(NodeIndex nodeIndex)
+ bool isFunctionConstant(Node* node)
{
- if (!isJSConstant(nodeIndex))
+ if (!isJSConstant(node))
return false;
- if (!getJSFunction(valueOfJSConstant(nodeIndex)))
+ if (!getJSFunction(valueOfJSConstant(node)))
return false;
return true;
}
- bool isInternalFunctionConstant(NodeIndex nodeIndex)
+ bool isInternalFunctionConstant(Node* node)
{
- if (!isJSConstant(nodeIndex))
+ if (!isJSConstant(node))
return false;
- JSValue value = valueOfJSConstant(nodeIndex);
+ JSValue value = valueOfJSConstant(node);
if (!value.isCell() || !value)
return false;
JSCell* cell = value.asCell();
@@ -309,37 +309,31 @@ public:
return true;
}
// Helper methods get constant values from nodes.
- JSValue valueOfJSConstant(NodeIndex nodeIndex)
+ JSValue valueOfJSConstant(Node* node)
{
- return at(nodeIndex).valueOfJSConstant(m_codeBlock);
+ return node->valueOfJSConstant(m_codeBlock);
}
- int32_t valueOfInt32Constant(NodeIndex nodeIndex)
+ int32_t valueOfInt32Constant(Node* node)
{
- return valueOfJSConstant(nodeIndex).asInt32();
+ return valueOfJSConstant(node).asInt32();
}
- double valueOfNumberConstant(NodeIndex nodeIndex)
+ double valueOfNumberConstant(Node* node)
{
- return valueOfJSConstant(nodeIndex).asNumber();
+ return valueOfJSConstant(node).asNumber();
}
- bool valueOfBooleanConstant(NodeIndex nodeIndex)
+ bool valueOfBooleanConstant(Node* node)
{
- return valueOfJSConstant(nodeIndex).asBoolean();
+ return valueOfJSConstant(node).asBoolean();
}
- JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex)
+ JSFunction* valueOfFunctionConstant(Node* node)
{
- JSCell* function = getJSFunction(valueOfJSConstant(nodeIndex));
+ JSCell* function = getJSFunction(valueOfJSConstant(node));
ASSERT(function);
return jsCast<JSFunction*>(function);
}
- InternalFunction* valueOfInternalFunctionConstant(NodeIndex nodeIndex)
- {
- return jsCast<InternalFunction*>(valueOfJSConstant(nodeIndex).asCell());
- }
static const char *opName(NodeType);
- void predictArgumentTypes();
-
StructureSet* addStructureSet(const StructureSet& structureSet)
{
ASSERT(structureSet.size());
@@ -358,6 +352,12 @@ public:
return m_codeBlock->globalObjectFor(codeOrigin);
}
+ JSObject* globalThisObjectFor(CodeOrigin codeOrigin)
+ {
+ JSGlobalObject* object = globalObjectFor(codeOrigin);
+ return object->methodTable()->toThisObject(object, 0);
+ }
+
ExecutableBase* executableFor(InlineCallFrame* inlineCallFrame)
{
if (!inlineCallFrame)
@@ -376,6 +376,16 @@ public:
return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);
}
+ bool hasGlobalExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
+ {
+ return baselineCodeBlockFor(codeOrigin)->hasExitSite(FrequentExitSite(exitKind));
+ }
+
+ bool hasExitSite(const CodeOrigin& codeOrigin, ExitKind exitKind)
+ {
+ return baselineCodeBlockFor(codeOrigin)->hasExitSite(FrequentExitSite(codeOrigin.bytecodeIndex, exitKind));
+ }
+
int argumentsRegisterFor(const CodeOrigin& codeOrigin)
{
if (!codeOrigin.inlineCallFrame)
@@ -400,51 +410,54 @@ public:
codeOrigin.inlineCallFrame->stackOffset;
}
- int uncheckedActivationRegisterFor(const CodeOrigin& codeOrigin)
+ int uncheckedActivationRegisterFor(const CodeOrigin&)
{
- ASSERT_UNUSED(codeOrigin, !codeOrigin.inlineCallFrame);
+ // This will ignore CodeOrigin because we don't inline code that uses activations.
+ // Hence for inlined call frames it will return the outermost code block's
+ // activation register. This method is only used to compare the result to a local
+ // to see if we're mucking with the activation register. Hence if we return the
+ // "wrong" activation register for the frame then it will compare false, which is
+ // what we wanted.
return m_codeBlock->uncheckedActivationRegister();
}
- ValueProfile* valueProfileFor(NodeIndex nodeIndex)
+ ValueProfile* valueProfileFor(Node* node)
{
- if (nodeIndex == NoNode)
+ if (!node)
return 0;
- Node& node = at(nodeIndex);
- CodeBlock* profiledBlock = baselineCodeBlockFor(node.codeOrigin);
+ CodeBlock* profiledBlock = baselineCodeBlockFor(node->codeOrigin);
- if (node.hasLocal()) {
- if (!operandIsArgument(node.local()))
+ if (node->hasLocal()) {
+ if (!operandIsArgument(node->local()))
return 0;
- int argument = operandToArgument(node.local());
- if (node.variableAccessData() != at(m_arguments[argument]).variableAccessData())
+ int argument = operandToArgument(node->local());
+ if (node->variableAccessData() != m_arguments[argument]->variableAccessData())
return 0;
return profiledBlock->valueProfileForArgument(argument);
}
- if (node.hasHeapPrediction())
- return profiledBlock->valueProfileForBytecodeOffset(node.codeOrigin.bytecodeIndexForValueProfile());
+ if (node->hasHeapPrediction())
+ return profiledBlock->valueProfileForBytecodeOffset(node->codeOrigin.bytecodeIndexForValueProfile());
return 0;
}
- MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(NodeIndex nodeIndex)
+ MethodOfGettingAValueProfile methodOfGettingAValueProfileFor(Node* node)
{
- if (nodeIndex == NoNode)
+ if (!node)
return MethodOfGettingAValueProfile();
- Node& node = at(nodeIndex);
- CodeBlock* profiledBlock = baselineCodeBlockFor(node.codeOrigin);
+ CodeBlock* profiledBlock = baselineCodeBlockFor(node->codeOrigin);
- if (node.op() == GetLocal) {
+ if (node->op() == GetLocal) {
return MethodOfGettingAValueProfile::fromLazyOperand(
profiledBlock,
LazyOperandValueProfileKey(
- node.codeOrigin.bytecodeIndex, node.local()));
+ node->codeOrigin.bytecodeIndex, node->local()));
}
- return MethodOfGettingAValueProfile(valueProfileFor(nodeIndex));
+ return MethodOfGettingAValueProfile(valueProfileFor(node));
}
bool needsActivation() const
@@ -457,33 +470,22 @@ public:
return m_codeBlock->usesArguments();
}
- bool isCreatedThisArgument(int operand)
- {
- if (!operandIsArgument(operand))
- return false;
- if (operandToArgument(operand))
- return false;
- return m_codeBlock->specializationKind() == CodeForConstruct;
- }
-
unsigned numSuccessors(BasicBlock* block)
{
- return at(block->last()).numSuccessors();
+ return block->last()->numSuccessors();
}
BlockIndex successor(BasicBlock* block, unsigned index)
{
- return at(block->last()).successor(index);
+ return block->last()->successor(index);
}
BlockIndex successorForCondition(BasicBlock* block, bool condition)
{
- return at(block->last()).successorForCondition(condition);
+ return block->last()->successorForCondition(condition);
}
- bool isPredictedNumerical(Node& node)
+ bool isPredictedNumerical(Node* node)
{
- SpeculatedType left = at(node.child1()).prediction();
- SpeculatedType right = at(node.child2()).prediction();
- return isNumberSpeculation(left) && isNumberSpeculation(right);
+ return isNumerical(node->child1().useKind()) && isNumerical(node->child2().useKind());
}
// Note that a 'true' return does not actually mean that the ByVal access clobbers nothing.
@@ -492,23 +494,23 @@ public:
// - PutByVal definitely changes the array it stores to, and may even change its length.
// - PutByOffset definitely changes the object it stores to.
// - and so on.
- bool byValIsPure(Node& node)
+ bool byValIsPure(Node* node)
{
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::Generic:
return false;
case Array::Int32:
case Array::Double:
case Array::Contiguous:
case Array::ArrayStorage:
- return !node.arrayMode().isOutOfBounds();
+ return !node->arrayMode().isOutOfBounds();
case Array::SlowPutArrayStorage:
- return !node.arrayMode().mayStoreToHole();
+ return !node->arrayMode().mayStoreToHole();
case Array::String:
- return node.op() == GetByVal;
+ return node->op() == GetByVal;
#if USE(JSVALUE32_64)
case Array::Arguments:
- if (node.op() == GetByVal)
+ if (node->op() == GetByVal)
return true;
return false;
#endif // USE(JSVALUE32_64)
@@ -517,13 +519,13 @@ public:
}
}
- bool clobbersWorld(Node& node)
+ bool clobbersWorld(Node* node)
{
- if (node.flags() & NodeClobbersWorld)
+ if (node->flags() & NodeClobbersWorld)
return true;
- if (!(node.flags() & NodeMightClobber))
+ if (!(node->flags() & NodeMightClobber))
return false;
- switch (node.op()) {
+ switch (node->op()) {
case ValueAdd:
case CompareLess:
case CompareLessEq:
@@ -535,108 +537,119 @@ public:
case PutByVal:
case PutByValAlias:
return !byValIsPure(node);
+ case ToString:
+ switch (node->child1().useKind()) {
+ case StringObjectUse:
+ case StringOrStringObjectUse:
+ return false;
+ case CellUse:
+ case UntypedUse:
+ return true;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return true;
+ }
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return true; // If by some oddity we hit this case in release build it's safer to have CSE assume the worst.
}
}
- bool clobbersWorld(NodeIndex nodeIndex)
- {
- return clobbersWorld(at(nodeIndex));
- }
-
void determineReachability();
void resetReachability();
void resetExitStates();
- unsigned varArgNumChildren(Node& node)
+ unsigned varArgNumChildren(Node* node)
{
- ASSERT(node.flags() & NodeHasVarArgs);
- return node.numChildren();
+ ASSERT(node->flags() & NodeHasVarArgs);
+ return node->numChildren();
}
- unsigned numChildren(Node& node)
+ unsigned numChildren(Node* node)
{
- if (node.flags() & NodeHasVarArgs)
+ if (node->flags() & NodeHasVarArgs)
return varArgNumChildren(node);
return AdjacencyList::Size;
}
- Edge& varArgChild(Node& node, unsigned index)
+ Edge& varArgChild(Node* node, unsigned index)
{
- ASSERT(node.flags() & NodeHasVarArgs);
- return m_varArgChildren[node.firstChild() + index];
+ ASSERT(node->flags() & NodeHasVarArgs);
+ return m_varArgChildren[node->firstChild() + index];
}
- Edge& child(Node& node, unsigned index)
+ Edge& child(Node* node, unsigned index)
{
- if (node.flags() & NodeHasVarArgs)
+ if (node->flags() & NodeHasVarArgs)
return varArgChild(node, index);
- return node.children.child(index);
+ return node->children.child(index);
}
- void vote(Edge edge, unsigned ballot)
+ void voteNode(Node* node, unsigned ballot)
{
- switch (at(edge).op()) {
+ switch (node->op()) {
case ValueToInt32:
case UInt32ToNumber:
- edge = at(edge).child1();
+ node = node->child1().node();
break;
default:
break;
}
- if (at(edge).op() == GetLocal)
- at(edge).variableAccessData()->vote(ballot);
+ if (node->op() == GetLocal)
+ node->variableAccessData()->vote(ballot);
+ }
+
+ void voteNode(Edge edge, unsigned ballot)
+ {
+ voteNode(edge.node(), ballot);
}
- void vote(Node& node, unsigned ballot)
+ void voteChildren(Node* node, unsigned ballot)
{
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- childIdx++) {
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild();
+ childIdx < node->firstChild() + node->numChildren();
+ childIdx++) {
if (!!m_varArgChildren[childIdx])
- vote(m_varArgChildren[childIdx], ballot);
+ voteNode(m_varArgChildren[childIdx], ballot);
}
return;
}
- if (!node.child1())
+ if (!node->child1())
return;
- vote(node.child1(), ballot);
- if (!node.child2())
+ voteNode(node->child1(), ballot);
+ if (!node->child2())
return;
- vote(node.child2(), ballot);
- if (!node.child3())
+ voteNode(node->child2(), ballot);
+ if (!node->child3())
return;
- vote(node.child3(), ballot);
+ voteNode(node->child3(), ballot);
}
- template<typename T> // T = NodeIndex or Edge
+ template<typename T> // T = Node* or Edge
void substitute(BasicBlock& block, unsigned startIndexInBlock, T oldThing, T newThing)
{
for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
- NodeIndex nodeIndex = block[indexInBlock];
- Node& node = at(nodeIndex);
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); ++childIdx) {
+ Node* node = block[indexInBlock];
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); ++childIdx) {
if (!!m_varArgChildren[childIdx])
- compareAndSwap(m_varArgChildren[childIdx], oldThing, newThing, node.shouldGenerate());
+ compareAndSwap(m_varArgChildren[childIdx], oldThing, newThing);
}
continue;
}
- if (!node.child1())
+ if (!node->child1())
continue;
- compareAndSwap(node.children.child1(), oldThing, newThing, node.shouldGenerate());
- if (!node.child2())
+ compareAndSwap(node->children.child1(), oldThing, newThing);
+ if (!node->child2())
continue;
- compareAndSwap(node.children.child2(), oldThing, newThing, node.shouldGenerate());
- if (!node.child3())
+ compareAndSwap(node->children.child2(), oldThing, newThing);
+ if (!node->child3())
continue;
- compareAndSwap(node.children.child3(), oldThing, newThing, node.shouldGenerate());
+ compareAndSwap(node->children.child3(), oldThing, newThing);
}
}
@@ -644,29 +657,28 @@ public:
// any GetLocals in the basic block.
// FIXME: it may be appropriate, in the future, to generalize this to handle GetLocals
// introduced anywhere in the basic block.
- void substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, NodeIndex newGetLocal)
+ void substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal)
{
if (variableAccessData->isCaptured()) {
// Let CSE worry about this one.
return;
}
for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
- NodeIndex nodeIndex = block[indexInBlock];
- Node& node = at(nodeIndex);
+ Node* node = block[indexInBlock];
bool shouldContinue = true;
- switch (node.op()) {
+ switch (node->op()) {
case SetLocal: {
- if (node.local() == variableAccessData->local())
+ if (node->local() == variableAccessData->local())
shouldContinue = false;
break;
}
case GetLocal: {
- if (node.variableAccessData() != variableAccessData)
+ if (node->variableAccessData() != variableAccessData)
continue;
- substitute(block, indexInBlock, nodeIndex, newGetLocal);
- NodeIndex oldTailIndex = block.variablesAtTail.operand(variableAccessData->local());
- if (oldTailIndex == nodeIndex)
+ substitute(block, indexInBlock, node, newGetLocal);
+ Node* oldTailNode = block.variablesAtTail.operand(variableAccessData->local());
+ if (oldTailNode == node)
block.variablesAtTail.operand(variableAccessData->local()) = newGetLocal;
shouldContinue = false;
break;
@@ -680,9 +692,12 @@ public:
}
}
- JSGlobalData& m_globalData;
+ VM& m_vm;
CodeBlock* m_codeBlock;
+ RefPtr<Profiler::Compilation> m_compilation;
CodeBlock* m_profiledBlock;
+
+ NodeAllocator& m_allocator;
Vector< OwnPtr<BasicBlock> , 8> m_blocks;
Vector<Edge, 16> m_varArgChildren;
@@ -690,7 +705,7 @@ public:
Vector<ResolveGlobalData> m_resolveGlobalData;
Vector<ResolveOperationData> m_resolveOperationsData;
Vector<PutToBaseOperationData> m_putToBaseOperationData;
- Vector<NodeIndex, 8> m_arguments;
+ Vector<Node*, 8> m_arguments;
SegmentedVector<VariableAccessData, 16> m_variableAccessData;
SegmentedVector<ArgumentPosition, 8> m_argumentPositions;
SegmentedVector<StructureSet, 16> m_structureSet;
@@ -706,41 +721,44 @@ public:
Operands<JSValue> m_mustHandleValues;
OptimizationFixpointState m_fixpointState;
+ GraphForm m_form;
+ UnificationState m_unificationState;
+ RefCountState m_refCountState;
private:
void handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex);
- AddSpeculationMode addImmediateShouldSpeculateInteger(Node& add, Node& variable, Node& immediate)
+ AddSpeculationMode addImmediateShouldSpeculateInteger(Node* add, bool variableShouldSpeculateInteger, Node* immediate)
{
- ASSERT(immediate.hasConstant());
+ ASSERT(immediate->hasConstant());
- JSValue immediateValue = immediate.valueOfJSConstant(m_codeBlock);
+ JSValue immediateValue = immediate->valueOfJSConstant(m_codeBlock);
if (!immediateValue.isNumber())
return DontSpeculateInteger;
- if (!variable.shouldSpeculateIntegerExpectingDefined())
+ if (!variableShouldSpeculateInteger)
return DontSpeculateInteger;
if (immediateValue.isInt32())
- return add.canSpeculateInteger() ? SpeculateInteger : DontSpeculateInteger;
+ return add->canSpeculateInteger() ? SpeculateInteger : DontSpeculateInteger;
double doubleImmediate = immediateValue.asDouble();
const double twoToThe48 = 281474976710656.0;
if (doubleImmediate < -twoToThe48 || doubleImmediate > twoToThe48)
return DontSpeculateInteger;
- return nodeCanTruncateInteger(add.arithNodeFlags()) ? SpeculateIntegerButAlwaysWatchOverflow : DontSpeculateInteger;
+ return nodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateIntegerAndTruncateConstants : DontSpeculateInteger;
}
- bool mulImmediateShouldSpeculateInteger(Node& mul, Node& variable, Node& immediate)
+ bool mulImmediateShouldSpeculateInteger(Node* mul, Node* variable, Node* immediate)
{
- ASSERT(immediate.hasConstant());
+ ASSERT(immediate->hasConstant());
- JSValue immediateValue = immediate.valueOfJSConstant(m_codeBlock);
+ JSValue immediateValue = immediate->valueOfJSConstant(m_codeBlock);
if (!immediateValue.isInt32())
return false;
- if (!variable.shouldSpeculateIntegerForArithmetic())
+ if (!variable->shouldSpeculateIntegerForArithmetic())
return false;
int32_t intImmediate = immediateValue.asInt32();
@@ -751,14 +769,10 @@ private:
// canSpeculateInteger() implies).
const int32_t twoToThe22 = 1 << 22;
if (intImmediate <= -twoToThe22 || intImmediate >= twoToThe22)
- return mul.canSpeculateInteger() && !nodeMayOverflow(mul.arithNodeFlags());
+ return mul->canSpeculateInteger() && !nodeMayOverflow(mul->arithNodeFlags());
- return mul.canSpeculateInteger();
+ return mul->canSpeculateInteger();
}
-
- // When a node's refCount goes from 0 to 1, it must (logically) recursively ref all of its children, and vice versa.
- void refChildren(NodeIndex);
- void derefChildren(NodeIndex);
};
class GetBytecodeBeginForBlock {
@@ -779,9 +793,39 @@ private:
inline BlockIndex Graph::blockIndexForBytecodeOffset(Vector<BlockIndex>& linkingTargets, unsigned bytecodeBegin)
{
- return *WTF::binarySearchWithFunctor<BlockIndex, unsigned>(linkingTargets.begin(), linkingTargets.size(), bytecodeBegin, WTF::KeyMustBePresentInArray, GetBytecodeBeginForBlock(*this));
+ return *binarySearch<BlockIndex, unsigned>(linkingTargets, linkingTargets.size(), bytecodeBegin, GetBytecodeBeginForBlock(*this));
}
+#define DFG_NODE_DO_TO_CHILDREN(graph, node, thingToDo) do { \
+ Node* _node = (node); \
+ if (_node->flags() & NodeHasVarArgs) { \
+ for (unsigned _childIdx = _node->firstChild(); \
+ _childIdx < _node->firstChild() + _node->numChildren(); \
+ _childIdx++) { \
+ if (!!(graph).m_varArgChildren[_childIdx]) \
+ thingToDo(_node, (graph).m_varArgChildren[_childIdx]); \
+ } \
+ } else { \
+ if (!_node->child1()) { \
+ ASSERT( \
+ !_node->child2() \
+ && !_node->child3()); \
+ break; \
+ } \
+ thingToDo(_node, _node->child1()); \
+ \
+ if (!_node->child2()) { \
+ ASSERT(!_node->child3()); \
+ break; \
+ } \
+ thingToDo(_node, _node->child2()); \
+ \
+ if (!_node->child3()) \
+ break; \
+ thingToDo(_node, _node->child3()); \
+ } \
+ } while (false)
+
} } // namespace JSC::DFG
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGInsertionSet.h b/Source/JavaScriptCore/dfg/DFGInsertionSet.h
index d458683fe..19c1da4a6 100644
--- a/Source/JavaScriptCore/dfg/DFGInsertionSet.h
+++ b/Source/JavaScriptCore/dfg/DFGInsertionSet.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,64 +30,75 @@
#if ENABLE(DFG_JIT)
+#include "DFGGraph.h"
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
-template<typename ElementType>
class Insertion {
public:
Insertion() { }
- Insertion(size_t index, const ElementType& element)
+ Insertion(size_t index, Node* element)
: m_index(index)
, m_element(element)
{
}
size_t index() const { return m_index; }
- const ElementType& element() const { return m_element; }
+ Node* element() const { return m_element; }
private:
size_t m_index;
- ElementType m_element;
+ Node* m_element;
};
-template<typename ElementType>
class InsertionSet {
public:
- InsertionSet() { }
+ InsertionSet(Graph& graph)
+ : m_graph(graph)
+ {
+ }
- void append(const Insertion<ElementType>& insertion)
+ Node* insert(const Insertion& insertion)
{
ASSERT(!m_insertions.size() || m_insertions.last().index() <= insertion.index());
m_insertions.append(insertion);
+ return insertion.element();
}
- void append(size_t index, const ElementType& element)
+ Node* insert(size_t index, Node* element)
{
- append(Insertion<ElementType>(index, element));
+ return insert(Insertion(index, element));
+ }
+
+#define DFG_DEFINE_INSERT_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
+ templatePre typeParams templatePost Node* insertNode(size_t index, SpeculatedType type valueParamsComma valueParams) \
+ { \
+ return insert(index, m_graph.addNode(type valueParamsComma valueArgs)); \
}
+ DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_INSERT_NODE)
+#undef DFG_DEFINE_INSERT_NODE
- template<typename CollectionType>
- void execute(CollectionType& collection)
+ void execute(BasicBlock* block)
{
if (!m_insertions.size())
return;
- collection.grow(collection.size() + m_insertions.size());
- size_t lastIndex = collection.size();
+ block->grow(block->size() + m_insertions.size());
+ size_t lastIndex = block->size();
for (size_t indexInInsertions = m_insertions.size(); indexInInsertions--;) {
- Insertion<ElementType>& insertion = m_insertions[indexInInsertions];
+ Insertion& insertion = m_insertions[indexInInsertions];
size_t firstIndex = insertion.index() + indexInInsertions;
size_t indexOffset = indexInInsertions + 1;
for (size_t i = lastIndex; --i > firstIndex;)
- collection[i] = collection[i - indexOffset];
- collection[firstIndex] = insertion.element();
+ block->at(i) = block->at(i - indexOffset);
+ block->at(firstIndex) = insertion.element();
lastIndex = firstIndex;
}
m_insertions.resize(0);
}
private:
- Vector<Insertion<ElementType>, 8> m_insertions;
+ Graph& m_graph;
+ Vector<Insertion, 8> m_insertions;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
index 191aa7fe5..2ba9ea709 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,32 +35,49 @@
#include "DFGSlowPathGenerator.h"
#include "DFGSpeculativeJIT.h"
#include "DFGThunks.h"
-#include "JSGlobalData.h"
+#include "JSCJSValueInlines.h"
+#include "VM.h"
#include "LinkBuffer.h"
namespace JSC { namespace DFG {
JITCompiler::JITCompiler(Graph& dfg)
- : CCallHelpers(&dfg.m_globalData, dfg.m_codeBlock)
+ : CCallHelpers(&dfg.m_vm, dfg.m_codeBlock)
, m_graph(dfg)
, m_currentCodeOriginIndex(0)
{
- if (shouldShowDisassembly())
+ if (shouldShowDisassembly() || m_graph.m_vm.m_perBytecodeProfiler)
m_disassembler = adoptPtr(new Disassembler(dfg));
}
void JITCompiler::linkOSRExits()
{
+ ASSERT(codeBlock()->numberOfOSRExits() == m_exitCompilationInfo.size());
+ if (m_graph.m_compilation) {
+ for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
+ OSRExit& exit = codeBlock()->osrExit(i);
+ Vector<Label> labels;
+ if (exit.m_watchpointIndex == std::numeric_limits<unsigned>::max()) {
+ OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
+ for (unsigned j = 0; j < info.m_failureJumps.jumps().size(); ++j)
+ labels.append(info.m_failureJumps.jumps()[j].label());
+ } else
+ labels.append(codeBlock()->watchpoint(exit.m_watchpointIndex).sourceLabel());
+ m_exitSiteLabels.append(labels);
+ }
+ }
+
for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
OSRExit& exit = codeBlock()->osrExit(i);
- ASSERT(!exit.m_check.isSet() == (exit.m_watchpointIndex != std::numeric_limits<unsigned>::max()));
+ JumpList& failureJumps = m_exitCompilationInfo[i].m_failureJumps;
+ ASSERT(failureJumps.empty() == (exit.m_watchpointIndex != std::numeric_limits<unsigned>::max()));
if (exit.m_watchpointIndex == std::numeric_limits<unsigned>::max())
- exit.m_check.initialJump().link(this);
+ failureJumps.link(this);
else
codeBlock()->watchpoint(exit.m_watchpointIndex).setDestination(label());
jitAssertHasValidCallFrame();
- store32(TrustedImm32(i), &globalData()->osrExitIndex);
- exit.m_check.switchToLateJump(patchableJump());
+ store32(TrustedImm32(i), &vm()->osrExitIndex);
+ exit.setPatchableCodeOffset(patchableJump());
}
}
@@ -145,7 +162,7 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
}
- Vector<CodeOriginAtCallReturnOffset>& codeOrigins = m_codeBlock->codeOrigins();
+ Vector<CodeOriginAtCallReturnOffset, 0, UnsafeVectorOverflow>& codeOrigins = m_codeBlock->codeOrigins();
codeOrigins.resize(m_exceptionChecks.size());
for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
@@ -189,25 +206,36 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
info.callType = m_jsCalls[i].m_callType;
info.isDFG = true;
info.codeOrigin = m_jsCalls[i].m_codeOrigin;
- linkBuffer.link(m_jsCalls[i].m_slowCall, FunctionPtr((m_globalData->getCTIStub(info.callType == CallLinkInfo::Construct ? linkConstructThunkGenerator : linkCallThunkGenerator)).code().executableAddress()));
+ linkBuffer.link(m_jsCalls[i].m_slowCall, FunctionPtr((m_vm->getCTIStub(info.callType == CallLinkInfo::Construct ? linkConstructThunkGenerator : linkCallThunkGenerator)).code().executableAddress()));
info.callReturnLocation = linkBuffer.locationOfNearCall(m_jsCalls[i].m_slowCall);
info.hotPathBegin = linkBuffer.locationOf(m_jsCalls[i].m_targetToCheck);
info.hotPathOther = linkBuffer.locationOfNearCall(m_jsCalls[i].m_fastCall);
info.calleeGPR = static_cast<unsigned>(m_jsCalls[i].m_callee);
}
- MacroAssemblerCodeRef osrExitThunk = globalData()->getCTIStub(osrExitGenerationThunkGenerator);
+ MacroAssemblerCodeRef osrExitThunk = vm()->getCTIStub(osrExitGenerationThunkGenerator);
CodeLocationLabel target = CodeLocationLabel(osrExitThunk.code());
for (unsigned i = 0; i < codeBlock()->numberOfOSRExits(); ++i) {
OSRExit& exit = codeBlock()->osrExit(i);
- linkBuffer.link(exit.m_check.lateJump(), target);
- exit.m_check.correctLateJump(linkBuffer);
+ linkBuffer.link(exit.getPatchableCodeOffsetAsJump(), target);
+ exit.correctJump(linkBuffer);
if (exit.m_watchpointIndex != std::numeric_limits<unsigned>::max())
codeBlock()->watchpoint(exit.m_watchpointIndex).correctLabels(linkBuffer);
}
- codeBlock()->minifiedDFG().setOriginalGraphSize(m_graph.size());
- codeBlock()->shrinkToFit(CodeBlock::LateShrink);
+ if (m_graph.m_compilation) {
+ ASSERT(m_exitSiteLabels.size() == codeBlock()->numberOfOSRExits());
+ for (unsigned i = 0; i < m_exitSiteLabels.size(); ++i) {
+ Vector<Label>& labels = m_exitSiteLabels[i];
+ Vector<const void*> addresses;
+ for (unsigned j = 0; j < labels.size(); ++j)
+ addresses.append(linkBuffer.locationOf(labels[j]).executableAddress());
+ m_graph.m_compilation->addOSRExitSite(addresses);
+ }
+ } else
+ ASSERT(!m_exitSiteLabels.size());
+
+ codeBlock()->saveCompilation(m_graph.m_compilation);
}
bool JITCompiler::compile(JITCode& entry)
@@ -230,14 +258,17 @@ bool JITCompiler::compile(JITCode& entry)
speculative.createOSREntries();
setEndOfCode();
- LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock, JITCompilationCanFail);
+ LinkBuffer linkBuffer(*m_vm, this, m_codeBlock, JITCompilationCanFail);
if (linkBuffer.didFailToAllocate())
return false;
link(linkBuffer);
speculative.linkOSREntries(linkBuffer);
+ codeBlock()->shrinkToFit(CodeBlock::LateShrink);
- if (m_disassembler)
+ if (shouldShowDisassembly())
m_disassembler->dump(linkBuffer);
+ if (m_graph.m_compilation)
+ m_disassembler->reportToProfiler(m_graph.m_compilation.get(), linkBuffer);
entry = JITCode(
linkBuffer.finalizeCodeWithoutDisassembly(),
@@ -260,7 +291,7 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
// Plant a check that sufficient space is available in the JSStack.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=56291
addPtr(TrustedImm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::regT1);
- Jump stackCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), GPRInfo::regT1);
+ Jump stackCheck = branchPtr(Below, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), GPRInfo::regT1);
// Return here after stack check.
Label fromStackCheck = label();
@@ -317,18 +348,21 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi
setEndOfCode();
// === Link ===
- LinkBuffer linkBuffer(*m_globalData, this, m_codeBlock, JITCompilationCanFail);
+ LinkBuffer linkBuffer(*m_vm, this, m_codeBlock, JITCompilationCanFail);
if (linkBuffer.didFailToAllocate())
return false;
link(linkBuffer);
speculative.linkOSREntries(linkBuffer);
+ codeBlock()->shrinkToFit(CodeBlock::LateShrink);
// FIXME: switch the stack check & arity check over to DFGOpertaion style calls, not JIT stubs.
linkBuffer.link(callStackCheck, cti_stack_check);
linkBuffer.link(callArityCheck, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck);
- if (m_disassembler)
+ if (shouldShowDisassembly())
m_disassembler->dump(linkBuffer);
+ if (m_graph.m_compilation)
+ m_disassembler->reportToProfiler(m_graph.m_compilation.get(), linkBuffer);
entryWithArityCheck = linkBuffer.locationOf(arityCheck);
entry = JITCode(
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
index 0bd88b788..85a752ef3 100644
--- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h
+++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#include "DFGFPRInfo.h"
#include "DFGGPRInfo.h"
#include "DFGGraph.h"
+#include "DFGOSRExitCompilationInfo.h"
#include "DFGRegisterBank.h"
#include "DFGRegisterSet.h"
#include "JITCode.h"
@@ -44,12 +45,13 @@ namespace JSC {
class AbstractSamplingCounter;
class CodeBlock;
-class JSGlobalData;
+class VM;
namespace DFG {
class JITCodeGenerator;
class NodeToRegisterMap;
+class OSRExitJumpPlaceholder;
class SlowPathGenerator;
class SpeculativeJIT;
class SpeculationRecovery;
@@ -264,11 +266,11 @@ public:
m_disassembler->setForBlock(blockIndex, labelIgnoringWatchpoints());
}
- void setForNode(NodeIndex nodeIndex)
+ void setForNode(Node* node)
{
if (LIKELY(!m_disassembler))
return;
- m_disassembler->setForNode(nodeIndex, labelIgnoringWatchpoints());
+ m_disassembler->setForNode(node, labelIgnoringWatchpoints());
}
void setEndOfMainPath()
@@ -338,16 +340,18 @@ public:
m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin));
}
- // Helper methods to get predictions
- SpeculatedType getSpeculation(Node& node) { return node.prediction(); }
- SpeculatedType getSpeculation(NodeIndex nodeIndex) { return getSpeculation(graph()[nodeIndex]); }
- SpeculatedType getSpeculation(Edge nodeUse) { return getSpeculation(nodeUse.index()); }
+ void appendExitInfo(MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList())
+ {
+ OSRExitCompilationInfo info;
+ info.m_failureJumps = jumpsToFail;
+ m_exitCompilationInfo.append(info);
+ }
#if USE(JSVALUE32_64)
- void* addressOfDoubleConstant(NodeIndex nodeIndex)
+ void* addressOfDoubleConstant(Node* node)
{
- ASSERT(m_graph.isNumberConstant(nodeIndex));
- unsigned constantIndex = graph()[nodeIndex].constantNumber();
+ ASSERT(m_graph.isNumberConstant(node));
+ unsigned constantIndex = node->constantNumber();
return &(codeBlock()->constantRegister(FirstConstantRegisterIndex + constantIndex));
}
#endif
@@ -401,15 +405,15 @@ 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) {
- NodeIndex nodeIndex = basicBlock.variablesAtHead.argument(argument);
- if (nodeIndex == NoNode || !m_graph[nodeIndex].shouldGenerate())
+ Node* node = basicBlock.variablesAtHead.argument(argument);
+ if (!node || !node->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 || !m_graph[nodeIndex].shouldGenerate())
+ Node* node = basicBlock.variablesAtHead.local(local);
+ if (!node || !node->shouldGenerate())
entry->m_expectedValues.local(local).makeTop();
- else if (m_graph[nodeIndex].variableAccessData()->shouldUseDoubleFormat())
+ else if (node->variableAccessData()->shouldUseDoubleFormat())
entry->m_localsForcedDouble.set(local);
}
#else
@@ -420,6 +424,8 @@ public:
}
private:
+ friend class OSRExitJumpPlaceholder;
+
// Internal implementation to compile.
void compileEntry();
void compileBody(SpeculativeJIT&);
@@ -460,6 +466,8 @@ private:
Vector<PropertyAccessRecord, 4> m_propertyAccesses;
Vector<JSCallRecord, 4> m_jsCalls;
+ Vector<OSRExitCompilationInfo> m_exitCompilationInfo;
+ Vector<Vector<Label> > m_exitSiteLabels;
unsigned m_currentCodeOriginIndex;
};
diff --git a/Source/JavaScriptCore/dfg/DFGLongLivedState.cpp b/Source/JavaScriptCore/dfg/DFGLongLivedState.cpp
new file mode 100644
index 000000000..26dc16c7c
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGLongLivedState.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGLongLivedState.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+LongLivedState::LongLivedState()
+{
+}
+
+LongLivedState::~LongLivedState()
+{
+}
+
+void LongLivedState::shrinkToFit()
+{
+ m_allocator.reset();
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGLongLivedState.h b/Source/JavaScriptCore/dfg/DFGLongLivedState.h
new file mode 100644
index 000000000..277cee886
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGLongLivedState.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGLongLivedState_h
+#define DFGLongLivedState_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNodeAllocator.h"
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC { namespace DFG {
+
+class LongLivedState {
+ WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(LongLivedState);
+public:
+ LongLivedState();
+ ~LongLivedState();
+
+ void shrinkToFit();
+
+ NodeAllocator m_allocator;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGLongLivedState_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedGraph.h b/Source/JavaScriptCore/dfg/DFGMinifiedGraph.h
index b38ef07ed..892a20648 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedGraph.h
@@ -41,16 +41,10 @@ class MinifiedGraph {
public:
MinifiedGraph() { }
- MinifiedNode* at(NodeIndex nodeIndex)
+ MinifiedNode* at(MinifiedID id)
{
- if (!m_list.size())
- return 0;
- MinifiedNode* entry =
- binarySearch<MinifiedNode, NodeIndex, MinifiedNode::getIndex>(
- m_list.begin(), m_list.size(), nodeIndex, WTF::KeyMustNotBePresentInArray);
- if (entry->index() != nodeIndex)
- return 0;
- return entry;
+ return tryBinarySearch<MinifiedNode, MinifiedID>(
+ m_list, m_list.size(), id, MinifiedNode::getID);
}
void append(const MinifiedNode& node)
@@ -64,13 +58,8 @@ public:
m_list.shrinkToFit();
}
- void setOriginalGraphSize(size_t size) { m_size = size; }
-
- size_t originalGraphSize() const { return m_size; }
-
private:
Vector<MinifiedNode> m_list;
- size_t m_size;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedID.h b/Source/JavaScriptCore/dfg/DFGMinifiedID.h
new file mode 100644
index 000000000..369659161
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedID.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGMinifiedID_h
+#define DFGMinifiedID_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+class Graph;
+class MinifiedNode;
+class ValueSource;
+
+class MinifiedID {
+public:
+ MinifiedID() : m_id(invalidID()) { }
+ MinifiedID(WTF::HashTableDeletedValueType) : m_id(otherInvalidID()) { }
+ explicit MinifiedID(Node* node) : m_id(bitwise_cast<uintptr_t>(node)) { }
+
+ bool operator!() const { return m_id == invalidID(); }
+
+ // This takes Graph& to remind you, that you should only be calling this method
+ // when you're in the main compilation pass (i.e. you have a graph) and not later,
+ // like during OSR exit compilation.
+ Node* node(const Graph&) const { return bitwise_cast<Node*>(m_id); }
+
+ bool operator==(const MinifiedID& other) const { return m_id == other.m_id; }
+ bool operator!=(const MinifiedID& other) const { return m_id != other.m_id; }
+ bool operator<(const MinifiedID& other) const { return m_id < other.m_id; }
+ bool operator>(const MinifiedID& other) const { return m_id > other.m_id; }
+ bool operator<=(const MinifiedID& other) const { return m_id <= other.m_id; }
+ bool operator>=(const MinifiedID& other) const { return m_id >= other.m_id; }
+
+ unsigned hash() const { return WTF::IntHash<uintptr_t>::hash(m_id); }
+
+ void dump(PrintStream& out) const { out.print(RawPointer(reinterpret_cast<void*>(m_id))); }
+
+ bool isHashTableDeletedValue() const { return m_id == otherInvalidID(); }
+
+private:
+ friend class MinifiedNode;
+ friend class ValueSource;
+
+ static uintptr_t invalidID() { return static_cast<uintptr_t>(static_cast<intptr_t>(-1)); }
+ static uintptr_t otherInvalidID() { return static_cast<uintptr_t>(static_cast<intptr_t>(-2)); }
+
+ static MinifiedID fromBits(uintptr_t value)
+ {
+ MinifiedID result;
+ result.m_id = value;
+ return result;
+ }
+
+ uintptr_t m_id;
+};
+
+struct MinifiedIDHash {
+ static unsigned hash(const MinifiedID& key) { return key.hash(); }
+ static bool equal(const MinifiedID& a, const MinifiedID& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::DFG::MinifiedID> {
+ typedef JSC::DFG::MinifiedIDHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::DFG::MinifiedID> : SimpleClassHashTraits<JSC::DFG::MinifiedID> { };
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGMinifiedID_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp b/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
index 6362344fb..5fec77198 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,20 +32,20 @@
namespace JSC { namespace DFG {
-MinifiedNode MinifiedNode::fromNode(NodeIndex nodeIndex, Node& node)
+MinifiedNode MinifiedNode::fromNode(Node* node)
{
- ASSERT(belongsInMinifiedGraph(node.op()));
+ ASSERT(belongsInMinifiedGraph(node->op()));
MinifiedNode result;
- result.m_index = nodeIndex;
- result.m_op = node.op();
- if (hasChild(node.op()))
- result.m_childOrInfo = node.child1().index();
- else if (hasConstantNumber(node.op()))
- result.m_childOrInfo = node.constantNumber();
- else if (hasWeakConstant(node.op()))
- result.m_childOrInfo = bitwise_cast<uintptr_t>(node.weakConstant());
+ result.m_id = MinifiedID(node);
+ result.m_op = node->op();
+ if (hasChild(node->op()))
+ result.m_childOrInfo = MinifiedID(node->child1().node()).m_id;
+ else if (hasConstantNumber(node->op()))
+ result.m_childOrInfo = node->constantNumber();
+ else if (hasWeakConstant(node->op()))
+ result.m_childOrInfo = bitwise_cast<uintptr_t>(node->weakConstant());
else {
- ASSERT(node.op() == PhantomArguments);
+ ASSERT(node->op() == PhantomArguments);
result.m_childOrInfo = 0;
}
return result;
diff --git a/Source/JavaScriptCore/dfg/DFGMinifiedNode.h b/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
index b80cbd777..a1702903e 100644
--- a/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
+++ b/Source/JavaScriptCore/dfg/DFGMinifiedNode.h
@@ -31,6 +31,7 @@
#if ENABLE(DFG_JIT)
#include "DFGCommon.h"
+#include "DFGMinifiedID.h"
#include "DFGNodeType.h"
namespace JSC { namespace DFG {
@@ -44,6 +45,7 @@ inline bool belongsInMinifiedGraph(NodeType type)
case WeakJSConstant:
case ValueToInt32:
case Int32ToDouble:
+ case ForwardInt32ToDouble:
case UInt32ToNumber:
case DoubleAsInt32:
case PhantomArguments:
@@ -57,17 +59,17 @@ class MinifiedNode {
public:
MinifiedNode() { }
- static MinifiedNode fromNode(NodeIndex, Node&);
+ static MinifiedNode fromNode(Node*);
- NodeIndex index() const { return m_index; }
+ MinifiedID id() const { return m_id; }
NodeType op() const { return m_op; }
bool hasChild1() const { return hasChild(m_op); }
- NodeIndex child1() const
+ MinifiedID child1() const
{
ASSERT(hasChild(m_op));
- return m_childOrInfo;
+ return MinifiedID::fromBits(m_childOrInfo);
}
bool hasConstant() const { return hasConstantNumber() || hasWeakConstant(); }
@@ -88,10 +90,10 @@ public:
return bitwise_cast<JSCell*>(m_childOrInfo);
}
- static NodeIndex getIndex(MinifiedNode* node) { return node->index(); }
+ static MinifiedID getID(MinifiedNode* node) { return node->id(); }
static bool compareByNodeIndex(const MinifiedNode& a, const MinifiedNode& b)
{
- return a.m_index < b.m_index;
+ return a.m_id < b.m_id;
}
private:
@@ -100,6 +102,7 @@ private:
switch (type) {
case ValueToInt32:
case Int32ToDouble:
+ case ForwardInt32ToDouble:
case UInt32ToNumber:
case DoubleAsInt32:
return true;
@@ -116,9 +119,9 @@ private:
return type == WeakJSConstant;
}
- NodeIndex m_index;
- NodeType m_op;
+ MinifiedID m_id;
uintptr_t m_childOrInfo; // Nodes in the minified graph have only one child each.
+ NodeType m_op;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGNode.cpp b/Source/JavaScriptCore/dfg/DFGNode.cpp
new file mode 100644
index 000000000..51720f8ac
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNode.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGNode.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNodeAllocator.h"
+
+namespace JSC { namespace DFG {
+
+unsigned Node::index() const
+{
+ return NodeAllocator::allocatorOf(this)->indexOf(this);
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::DFG::Node* node)
+{
+ if (!node) {
+ out.print("-");
+ return;
+ }
+ out.print("@", node->index());
+ out.print(JSC::AbbreviatedSpeculationDump(node->prediction()));
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 5f7890a96..f45d3fa68 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,13 +32,15 @@
#include "CodeBlock.h"
#include "CodeOrigin.h"
+#include "DFGAbstractValue.h"
#include "DFGAdjacencyList.h"
#include "DFGArrayMode.h"
#include "DFGCommon.h"
#include "DFGNodeFlags.h"
#include "DFGNodeType.h"
#include "DFGVariableAccessData.h"
-#include "JSValue.h"
+#include "JSCJSValueInlines.h"
+#include "JSCJSValue.h"
#include "Operands.h"
#include "SpeculatedType.h"
#include "StructureSet.h"
@@ -67,7 +69,7 @@ struct NewArrayBufferData {
// This type used in passing an immediate argument to Node constructor;
// distinguishes an immediate value (typically an index into a CodeBlock data structure -
-// a constant index, argument, or identifier) from a NodeIndex.
+// a constant index, argument, or identifier) from a Node*.
struct OpInfo {
explicit OpInfo(int32_t value) : m_value(static_cast<uintptr_t>(value)) { }
explicit OpInfo(uint32_t value) : m_value(static_cast<uintptr_t>(value)) { }
@@ -86,12 +88,22 @@ struct Node {
Node() { }
+ Node(NodeType op, CodeOrigin codeOrigin, const AdjacencyList& children)
+ : codeOrigin(codeOrigin)
+ , children(children)
+ , m_virtualRegister(InvalidVirtualRegister)
+ , m_refCount(1)
+ , m_prediction(SpecNone)
+ {
+ setOpAndDefaultFlags(op);
+ }
+
// 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)
+ Node(NodeType op, CodeOrigin codeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
: codeOrigin(codeOrigin)
, children(AdjacencyList::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
- , m_refCount(0)
+ , m_refCount(1)
, m_prediction(SpecNone)
{
setOpAndDefaultFlags(op);
@@ -99,11 +111,11 @@ struct Node {
}
// 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)
+ Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
: codeOrigin(codeOrigin)
, children(AdjacencyList::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
- , m_refCount(0)
+ , m_refCount(1)
, m_opInfo(imm.m_value)
, m_prediction(SpecNone)
{
@@ -112,11 +124,11 @@ struct Node {
}
// 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)
+ Node(NodeType op, CodeOrigin codeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
: codeOrigin(codeOrigin)
, children(AdjacencyList::Fixed, child1, child2, child3)
, m_virtualRegister(InvalidVirtualRegister)
- , m_refCount(0)
+ , m_refCount(1)
, m_opInfo(imm1.m_value)
, m_opInfo2(safeCast<unsigned>(imm2.m_value))
, m_prediction(SpecNone)
@@ -130,7 +142,7 @@ struct Node {
: codeOrigin(codeOrigin)
, children(AdjacencyList::Variable, firstChild, numChildren)
, m_virtualRegister(InvalidVirtualRegister)
- , m_refCount(0)
+ , m_refCount(1)
, m_opInfo(imm1.m_value)
, m_opInfo2(safeCast<unsigned>(imm2.m_value))
, m_prediction(SpecNone)
@@ -142,6 +154,9 @@ struct Node {
NodeType op() const { return static_cast<NodeType>(m_op); }
NodeFlags flags() const { return m_flags; }
+ // This is not a fast method.
+ unsigned index() const;
+
void setOp(NodeType op)
{
m_op = op;
@@ -183,6 +198,35 @@ struct Node {
m_flags = defaultFlags(op);
}
+ void setOpAndDefaultNonExitFlags(NodeType op)
+ {
+ ASSERT(!(m_flags & NodeHasVarArgs));
+ setOpAndDefaultNonExitFlagsUnchecked(op);
+ }
+
+ void setOpAndDefaultNonExitFlagsUnchecked(NodeType op)
+ {
+ m_op = op;
+ m_flags = (defaultFlags(op) & ~NodeExitsForward) | (m_flags & NodeExitsForward);
+ }
+
+ void convertToPhantom()
+ {
+ setOpAndDefaultNonExitFlags(Phantom);
+ }
+
+ void convertToPhantomUnchecked()
+ {
+ setOpAndDefaultNonExitFlagsUnchecked(Phantom);
+ }
+
+ void convertToIdentity()
+ {
+ RELEASE_ASSERT(child1());
+ RELEASE_ASSERT(!child2());
+ setOpAndDefaultNonExitFlags(Identity);
+ }
+
bool mustGenerate()
{
return m_flags & NodeMustGenerate;
@@ -211,6 +255,16 @@ struct Node {
return op() == WeakJSConstant;
}
+ bool isStronglyProvedConstantIn(InlineCallFrame* inlineCallFrame)
+ {
+ return isConstant() && codeOrigin.inlineCallFrame == inlineCallFrame;
+ }
+
+ bool isStronglyProvedConstantIn(const CodeOrigin& codeOrigin)
+ {
+ return isStronglyProvedConstantIn(codeOrigin.inlineCallFrame);
+ }
+
bool isPhantomArguments()
{
return op() == PhantomArguments;
@@ -237,18 +291,22 @@ struct Node {
void convertToConstant(unsigned constantNumber)
{
m_op = JSConstant;
- if (m_flags & NodeMustGenerate)
- m_refCount--;
m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
m_opInfo = constantNumber;
children.reset();
}
+ void convertToWeakConstant(JSCell* cell)
+ {
+ m_op = WeakJSConstant;
+ m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
+ m_opInfo = bitwise_cast<uintptr_t>(cell);
+ children.reset();
+ }
+
void convertToGetLocalUnlinked(VirtualRegister local)
{
m_op = GetLocalUnlinked;
- if (m_flags & NodeMustGenerate)
- m_refCount--;
m_flags &= ~(NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);
m_opInfo = local;
children.reset();
@@ -269,26 +327,48 @@ struct Node {
convertToStructureTransitionWatchpoint(structureSet().singletonStructure());
}
- void convertToGetByOffset(unsigned storageAccessDataIndex, NodeIndex storage)
+ void convertToGetByOffset(unsigned storageAccessDataIndex, Edge storage)
{
ASSERT(m_op == GetById || m_op == GetByIdFlush);
m_opInfo = storageAccessDataIndex;
- children.setChild1(Edge(storage));
+ children.setChild1(storage);
m_op = GetByOffset;
m_flags &= ~NodeClobbersWorld;
}
- void convertToPutByOffset(unsigned storageAccessDataIndex, NodeIndex storage)
+ void convertToPutByOffset(unsigned storageAccessDataIndex, Edge storage)
{
ASSERT(m_op == PutById || m_op == PutByIdDirect);
m_opInfo = storageAccessDataIndex;
children.setChild3(children.child2());
children.setChild2(children.child1());
- children.setChild1(Edge(storage));
+ children.setChild1(storage);
m_op = PutByOffset;
m_flags &= ~NodeClobbersWorld;
}
+ void convertToPhantomLocal()
+ {
+ ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
+ m_op = PhantomLocal;
+ m_opInfo = child1()->m_opInfo; // Copy the variableAccessData.
+ children.setChild1(Edge());
+ }
+
+ void convertToGetLocal(VariableAccessData* variable, Node* phi)
+ {
+ ASSERT(m_op == GetLocalUnlinked);
+ m_op = GetLocal;
+ m_opInfo = bitwise_cast<uintptr_t>(variable);
+ children.setChild1(Edge(phi));
+ }
+
+ void convertToToString()
+ {
+ ASSERT(m_op == ToPrimitive);
+ m_op = ToString;
+ }
+
JSCell* weakConstant()
{
ASSERT(op() == WeakJSConstant);
@@ -305,7 +385,7 @@ struct Node {
case PhantomArguments:
return JSValue();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return JSValue(); // Have to return something in release mode.
}
}
@@ -335,14 +415,31 @@ struct Node {
return isConstant() && valueOfJSConstant(codeBlock).isBoolean();
}
+ bool containsMovHint()
+ {
+ switch (op()) {
+ case SetLocal:
+ case MovHint:
+ case MovHintAndCheck:
+ case ZombieHint:
+ return true;
+ default:
+ return false;
+ }
+ }
+
bool hasVariableAccessData()
{
switch (op()) {
case GetLocal:
case SetLocal:
+ case MovHint:
+ case MovHintAndCheck:
+ case ZombieHint:
case Phi:
case SetArgument:
case Flush:
+ case PhantomLocal:
return true;
default:
return false;
@@ -427,8 +524,8 @@ struct Node {
// to know if it can speculate on negative zero.
NodeFlags arithNodeFlags()
{
- NodeFlags result = m_flags;
- if (op() == ArithMul || op() == ArithDiv || op() == ArithMod)
+ NodeFlags result = m_flags & NodeArithFlagsMask;
+ if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == DoubleAsInt32)
return result;
return result & ~NodeNeedsNegZero;
}
@@ -474,6 +571,17 @@ struct Node {
return m_opInfo;
}
+ bool hasInlineCapacity()
+ {
+ return op() == CreateThis;
+ }
+
+ unsigned inlineCapacity()
+ {
+ ASSERT(hasInlineCapacity());
+ return m_opInfo;
+ }
+
void setIndexingType(IndexingType indexingType)
{
ASSERT(hasIndexingType());
@@ -523,23 +631,6 @@ struct Node {
return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
}
- bool hasScopeChainDepth()
- {
- return op() == GetScope;
- }
-
- unsigned scopeChainDepth()
- {
- ASSERT(hasScopeChainDepth());
- return m_opInfo;
- }
-
- Edge scope()
- {
- ASSERT(op() == GetScopeRegisters);
- return child1();
- }
-
bool hasResult()
{
return m_flags & NodeResultMask;
@@ -650,7 +741,7 @@ struct Node {
case 1:
return notTakenBlockIndex();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return NoBlock;
}
}
@@ -705,7 +796,7 @@ struct Node {
{
switch (op()) {
case CheckFunction:
- case InheritorIDWatchpoint:
+ case AllocationProfileWatchpoint:
return true;
default:
return false;
@@ -719,6 +810,16 @@ struct Node {
ASSERT(JSValue(result).isFunction());
return result;
}
+
+ bool hasExecutable()
+ {
+ return op() == CheckExecutable;
+ }
+
+ ExecutableBase* executable()
+ {
+ return jsCast<ExecutableBase*>(reinterpret_cast<JSCell*>(m_opInfo));
+ }
bool hasStructureTransitionData()
{
@@ -763,6 +864,7 @@ struct Node {
case ForwardStructureTransitionWatchpoint:
case ArrayifyToStructure:
case NewObject:
+ case NewStringObject:
return true;
default:
return false;
@@ -876,6 +978,16 @@ struct Node {
ASSERT(hasArgumentPositionStart());
return m_opInfo;
}
+
+ bool hasExecutionCounter()
+ {
+ return op() == CountExecution;
+ }
+
+ Profiler::ExecutionCounter* executionCounter()
+ {
+ return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
+ }
bool shouldGenerate()
{
@@ -886,15 +998,20 @@ struct Node {
{
switch (op()) {
case SetLocal:
+ case MovHint:
+ case ZombieHint:
+ case MovHintAndCheck:
case Int32ToDouble:
+ case ForwardInt32ToDouble:
case ValueToInt32:
case UInt32ToNumber:
case DoubleAsInt32:
case PhantomArguments:
return true;
- case Phantom:
case Nop:
return false;
+ case Phantom:
+ return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
default:
return shouldGenerate();
}
@@ -905,10 +1022,9 @@ struct Node {
return m_refCount;
}
- // returns true when ref count passes from 0 to 1.
- bool ref()
+ unsigned postfixRef()
{
- return !m_refCount++;
+ return m_refCount++;
}
unsigned adjustedRefCount()
@@ -921,16 +1037,7 @@ struct Node {
m_refCount = refCount;
}
- // Derefs the node and returns true if the ref count reached zero.
- // In general you don't want to use this directly; use Graph::deref
- // instead.
- bool deref()
- {
- ASSERT(m_refCount);
- return !--m_refCount;
- }
-
- Edge child1()
+ Edge& child1()
{
ASSERT(!(m_flags & NodeHasVarArgs));
return children.child1();
@@ -944,13 +1051,13 @@ struct Node {
return children.child1Unchecked();
}
- Edge child2()
+ Edge& child2()
{
ASSERT(!(m_flags & NodeHasVarArgs));
return children.child2();
}
- Edge child3()
+ Edge& child3()
{
ASSERT(!(m_flags & NodeHasVarArgs));
return children.child3();
@@ -968,6 +1075,17 @@ struct Node {
return children.numChildren();
}
+ UseKind binaryUseKind()
+ {
+ ASSERT(child1().useKind() == child2().useKind());
+ return child1().useKind();
+ }
+
+ bool isBinaryUseKind(UseKind useKind)
+ {
+ return child1().useKind() == useKind && child2().useKind() == useKind;
+ }
+
SpeculatedType prediction()
{
return m_prediction;
@@ -1023,21 +1141,21 @@ struct Node {
return isStringSpeculation(prediction());
}
- bool shouldSpeculateFinalObject()
+ bool shouldSpeculateStringObject()
{
- return isFinalObjectSpeculation(prediction());
+ return isStringObjectSpeculation(prediction());
}
- bool shouldSpeculateNonStringCell()
+ bool shouldSpeculateStringOrStringObject()
{
- return isNonStringCellSpeculation(prediction());
+ return isStringOrStringObjectSpeculation(prediction());
}
-
- bool shouldSpeculateNonStringCellOrOther()
+
+ bool shouldSpeculateFinalObject()
{
- return isNonStringCellOrOtherSpeculation(prediction());
+ return isFinalObjectSpeculation(prediction());
}
-
+
bool shouldSpeculateFinalObjectOrOther()
{
return isFinalObjectOrOtherSpeculation(prediction());
@@ -1108,49 +1226,59 @@ struct Node {
return isObjectSpeculation(prediction());
}
+ bool shouldSpeculateObjectOrOther()
+ {
+ return isObjectOrOtherSpeculation(prediction());
+ }
+
bool shouldSpeculateCell()
{
return isCellSpeculation(prediction());
}
- static bool shouldSpeculateInteger(Node& op1, Node& op2)
+ static bool shouldSpeculateBoolean(Node* op1, Node* op2)
+ {
+ return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
+ }
+
+ static bool shouldSpeculateInteger(Node* op1, Node* op2)
{
- return op1.shouldSpeculateInteger() && op2.shouldSpeculateInteger();
+ return op1->shouldSpeculateInteger() && op2->shouldSpeculateInteger();
}
- static bool shouldSpeculateIntegerForArithmetic(Node& op1, Node& op2)
+ static bool shouldSpeculateIntegerForArithmetic(Node* op1, Node* op2)
{
- return op1.shouldSpeculateIntegerForArithmetic() && op2.shouldSpeculateIntegerForArithmetic();
+ return op1->shouldSpeculateIntegerForArithmetic() && op2->shouldSpeculateIntegerForArithmetic();
}
- static bool shouldSpeculateIntegerExpectingDefined(Node& op1, Node& op2)
+ static bool shouldSpeculateIntegerExpectingDefined(Node* op1, Node* op2)
{
- return op1.shouldSpeculateIntegerExpectingDefined() && op2.shouldSpeculateIntegerExpectingDefined();
+ return op1->shouldSpeculateIntegerExpectingDefined() && op2->shouldSpeculateIntegerExpectingDefined();
}
- static bool shouldSpeculateDoubleForArithmetic(Node& op1, Node& op2)
+ static bool shouldSpeculateDoubleForArithmetic(Node* op1, Node* op2)
{
- return op1.shouldSpeculateDoubleForArithmetic() && op2.shouldSpeculateDoubleForArithmetic();
+ return op1->shouldSpeculateDoubleForArithmetic() && op2->shouldSpeculateDoubleForArithmetic();
}
- static bool shouldSpeculateNumber(Node& op1, Node& op2)
+ static bool shouldSpeculateNumber(Node* op1, Node* op2)
{
- return op1.shouldSpeculateNumber() && op2.shouldSpeculateNumber();
+ return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
}
- static bool shouldSpeculateNumberExpectingDefined(Node& op1, Node& op2)
+ static bool shouldSpeculateNumberExpectingDefined(Node* op1, Node* op2)
{
- return op1.shouldSpeculateNumberExpectingDefined() && op2.shouldSpeculateNumberExpectingDefined();
+ return op1->shouldSpeculateNumberExpectingDefined() && op2->shouldSpeculateNumberExpectingDefined();
}
- static bool shouldSpeculateFinalObject(Node& op1, Node& op2)
+ static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
{
- return op1.shouldSpeculateFinalObject() && op2.shouldSpeculateFinalObject();
+ return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
}
- static bool shouldSpeculateArray(Node& op1, Node& op2)
+ static bool shouldSpeculateArray(Node* op1, Node* op2)
{
- return op1.shouldSpeculateArray() && op2.shouldSpeculateArray();
+ return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
}
bool canSpeculateInteger()
@@ -1162,23 +1290,25 @@ struct Node {
{
if (!child1())
return;
- out.printf("@%u", child1().index());
+ out.printf("@%u", child1()->index());
if (!child2())
return;
- out.printf(", @%u", child2().index());
+ out.printf(", @%u", child2()->index());
if (!child3())
return;
- out.printf(", @%u", child3().index());
+ out.printf(", @%u", child3()->index());
}
+ // NB. This class must have a trivial destructor.
+
// 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.
AdjacencyList children;
private:
- uint16_t m_op; // real type is NodeType
- NodeFlags m_flags;
+ unsigned m_op : 10; // real type is NodeType
+ unsigned m_flags : 22;
// The virtual register number (spill location) associated with this .
VirtualRegister m_virtualRegister;
// The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
@@ -1189,9 +1319,20 @@ private:
unsigned m_opInfo2;
// The prediction ascribed to this node after propagation.
SpeculatedType m_prediction;
+
+public:
+ // Fields used by various analyses.
+ AbstractValue value;
+ Node* replacement;
};
} } // namespace JSC::DFG
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::Node*);
+
+} // namespace WTF
+
#endif
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGNodeAllocator.h b/Source/JavaScriptCore/dfg/DFGNodeAllocator.h
new file mode 100644
index 000000000..afd72e584
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGNodeAllocator.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGNodeAllocator_h
+#define DFGNodeAllocator_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAllocator.h"
+#include "DFGNode.h"
+
+namespace JSC { namespace DFG {
+
+typedef Allocator<Node> NodeAllocator;
+
+} } // namespace JSC::DFG
+
+inline void* operator new (size_t size, JSC::DFG::NodeAllocator& allocator)
+{
+ ASSERT_UNUSED(size, size == sizeof(JSC::DFG::Node));
+ return allocator.allocate();
+}
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGNodeAllocator_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp b/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
index fb83c5a71..c5753d207 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
+++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,132 +28,81 @@
#if ENABLE(DFG_JIT)
-#include <wtf/BoundsCheckedPointer.h>
+#include <wtf/CommaPrinter.h>
namespace JSC { namespace DFG {
-const char* nodeFlagsAsString(NodeFlags flags)
+void dumpNodeFlags(PrintStream& out, NodeFlags flags)
{
- if (!flags)
- return "<empty>";
+ if (!(flags ^ NodeDoesNotExit)) {
+ out.print("<empty>");
+ return;
+ }
- static const int size = 128;
- static char description[size];
- BoundsCheckedPointer<char> ptr(description, size);
-
- bool hasPrinted = false;
+ CommaPrinter comma("|");
if (flags & NodeResultMask) {
switch (flags & NodeResultMask) {
case NodeResultJS:
- ptr.strcat("JS");
+ out.print(comma, "JS");
break;
case NodeResultNumber:
- ptr.strcat("Number");
+ out.print(comma, "Number");
break;
case NodeResultInt32:
- ptr.strcat("Int32");
+ out.print(comma, "Int32");
break;
case NodeResultBoolean:
- ptr.strcat("Boolean");
+ out.print(comma, "Boolean");
break;
case NodeResultStorage:
- ptr.strcat("Storage");
+ out.print(comma, "Storage");
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- hasPrinted = true;
}
- if (flags & NodeMustGenerate) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("MustGen");
- hasPrinted = true;
- }
+ if (flags & NodeMustGenerate)
+ out.print(comma, "MustGen");
- if (flags & NodeHasVarArgs) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("VarArgs");
- hasPrinted = true;
- }
+ if (flags & NodeHasVarArgs)
+ out.print(comma, "VarArgs");
- if (flags & NodeClobbersWorld) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("Clobbers");
- hasPrinted = true;
- }
+ if (flags & NodeClobbersWorld)
+ out.print(comma, "Clobbers");
- if (flags & NodeMightClobber) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("MightClobber");
- hasPrinted = true;
- }
+ if (flags & NodeMightClobber)
+ out.print(comma, "MightClobber");
if (flags & NodeResultMask) {
- if (!(flags & NodeUsedAsNumber) && !(flags & NodeNeedsNegZero)) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("PureInt");
- hasPrinted = true;
- } else if (!(flags & NodeUsedAsNumber)) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("PureInt(w/ neg zero)");
- hasPrinted = true;
- } else if (!(flags & NodeNeedsNegZero)) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("PureNum");
- hasPrinted = true;
- }
- if (flags & NodeUsedAsOther) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("UseAsOther");
- hasPrinted = true;
- }
+ if (!(flags & NodeUsedAsNumber) && !(flags & NodeNeedsNegZero))
+ out.print(comma, "PureInt");
+ else if (!(flags & NodeUsedAsNumber))
+ out.print(comma, "PureInt(w/ neg zero)");
+ else if (!(flags & NodeNeedsNegZero))
+ out.print(comma, "PureNum");
+ if (flags & NodeUsedAsOther)
+ out.print(comma, "UseAsOther");
}
- if (flags & NodeMayOverflow) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("MayOverflow");
- hasPrinted = true;
- }
+ if (flags & NodeMayOverflow)
+ out.print(comma, "MayOverflow");
- if (flags & NodeMayNegZero) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("MayNegZero");
- hasPrinted = true;
- }
+ if (flags & NodeMayNegZero)
+ out.print(comma, "MayNegZero");
- if (flags & NodeUsedAsInt) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("UseAsInt");
- hasPrinted = true;
- }
+ if (flags & NodeUsedAsInt)
+ out.print(comma, "UseAsInt");
- if (!(flags & NodeDoesNotExit)) {
- if (hasPrinted)
- ptr.strcat("|");
- ptr.strcat("CanExit");
- hasPrinted = true;
- }
-
- *ptr++ = 0;
+ if (!(flags & NodeDoesNotExit))
+ out.print(comma, "CanExit");
- return description;
+ if (flags & NodeExitsForward)
+ out.print(comma, "NodeExitsForward");
}
-
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.h b/Source/JavaScriptCore/dfg/DFGNodeFlags.h
index 463451c39..adb34bf66 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeFlags.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,39 +30,46 @@
#if ENABLE(DFG_JIT)
+#include <wtf/PrintStream.h>
#include <wtf/StdLibExtras.h>
namespace JSC { namespace DFG {
// 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 NodeResultMask 0x7
#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 NodeMustGenerate 0x08 // set on nodes that have side effects, and may not trivially be removed by DCE.
+#define NodeHasVarArgs 0x10
+#define NodeClobbersWorld 0x20
+#define NodeMightClobber 0x40
-#define NodeBehaviorMask 0x300
-#define NodeMayOverflow 0x100
-#define NodeMayNegZero 0x200
+#define NodeBehaviorMask 0x180
+#define NodeMayOverflow 0x080
+#define NodeMayNegZero 0x100
-#define NodeBackPropMask 0x3C00
-#define NodeUseBottom 0x000
-#define NodeUsedAsNumber 0x400 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
-#define NodeNeedsNegZero 0x800 // The result of this computation may be used in a context that observes -0.
-#define NodeUsedAsOther 0x1000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
+#define NodeBackPropMask 0x1E00
+#define NodeUseBottom 0x0000
+#define NodeUsedAsNumber 0x0200 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
+#define NodeNeedsNegZero 0x0400 // The result of this computation may be used in a context that observes -0.
+#define NodeUsedAsOther 0x0800 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
#define NodeUsedAsValue (NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther)
-#define NodeUsedAsInt 0x2000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
+#define NodeUsedAsInt 0x1000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
-#define NodeDoesNotExit 0x4000 // This flag is negated to make it natural for the default to be that a node does exit.
+#define NodeArithFlagsMask (NodeBehaviorMask | NodeBackPropMask)
-typedef uint16_t NodeFlags;
+#define NodeDoesNotExit 0x2000 // This flag is negated to make it natural for the default to be that a node does exit.
+
+#define NodeRelevantToOSR 0x4000
+
+#define NodeExitsForward 0x8000
+
+typedef uint32_t NodeFlags;
static inline bool nodeUsedAsNumber(NodeFlags flags)
{
@@ -95,7 +102,8 @@ static inline bool nodeCanSpeculateInteger(NodeFlags flags)
return true;
}
-const char* nodeFlagsAsString(NodeFlags);
+void dumpNodeFlags(PrintStream&, NodeFlags);
+MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags);
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index b3fd78785..9039e3f5f 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -46,22 +46,27 @@ namespace JSC { namespace DFG {
/* Marker to indicate that an operation was optimized entirely and all that is left */\
/* is to make one node alias another. CSE will later usually eliminate this node, */\
/* though it may choose not to if it would corrupt predictions (very rare). */\
- macro(Identity, NodeResultJS | NodeDoesNotExit) \
+ macro(Identity, NodeResultJS) \
\
/* Nodes for handling functions (both as call and as construct). */\
macro(ConvertThis, NodeResultJS) \
macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
macro(GetCallee, NodeResultJS) \
+ macro(SetCallee, NodeMustGenerate) \
\
/* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
/* Any two nodes that are part of the same Phi graph will share the same */\
/* VariableAccessData, and thus will share predictions. */\
macro(GetLocal, NodeResultJS) \
- macro(SetLocal, 0) \
+ macro(SetLocal, NodeExitsForward) \
+ macro(MovHintAndCheck, NodeMustGenerate | NodeExitsForward) \
+ macro(MovHint, NodeDoesNotExit) \
+ macro(ZombieHint, NodeDoesNotExit) \
macro(Phantom, NodeMustGenerate) \
- macro(Nop, 0 | NodeDoesNotExit) \
- macro(Phi, 0 | NodeDoesNotExit) \
+ macro(Nop, NodeDoesNotExit) \
+ macro(Phi, NodeDoesNotExit | NodeRelevantToOSR) \
macro(Flush, NodeMustGenerate | NodeDoesNotExit) \
+ macro(PhantomLocal, NodeMustGenerate | NodeDoesNotExit) \
\
/* Get the value of a local variable, without linking into the VariableAccessData */\
/* network. This is only valid for variable accesses whose predictions originated */\
@@ -74,33 +79,33 @@ namespace JSC { namespace DFG {
/* Hint that inlining begins here. No code is generated for this node. It's only */\
/* used for copying OSR data into inline frame data, to support reification of */\
/* call frames of inlined functions. */\
- macro(InlineStart, 0 | NodeDoesNotExit) \
+ macro(InlineStart, NodeMustGenerate | NodeDoesNotExit) \
\
/* Nodes for bitwise operations. */\
- macro(BitAnd, NodeResultInt32) \
- macro(BitOr, NodeResultInt32) \
- macro(BitXor, NodeResultInt32) \
- macro(BitLShift, NodeResultInt32) \
- macro(BitRShift, NodeResultInt32) \
- macro(BitURShift, NodeResultInt32) \
+ macro(BitAnd, NodeResultInt32 | NodeMustGenerate) \
+ macro(BitOr, NodeResultInt32 | NodeMustGenerate) \
+ macro(BitXor, NodeResultInt32 | NodeMustGenerate) \
+ macro(BitLShift, NodeResultInt32 | NodeMustGenerate) \
+ macro(BitRShift, NodeResultInt32 | NodeMustGenerate) \
+ macro(BitURShift, NodeResultInt32 | NodeMustGenerate) \
/* Bitwise operators call ToInt32 on their operands. */\
- macro(ValueToInt32, NodeResultInt32 | NodeMustGenerate) \
+ macro(ValueToInt32, NodeResultInt32) \
/* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
- macro(UInt32ToNumber, NodeResultNumber) \
+ macro(UInt32ToNumber, NodeResultNumber | NodeExitsForward) \
\
/* Used to cast known integers to doubles, so as to separate the double form */\
/* of the value from the integer form. */\
macro(Int32ToDouble, NodeResultNumber) \
+ macro(ForwardInt32ToDouble, NodeResultNumber | NodeExitsForward) \
/* Used to speculate that a double value is actually an integer. */\
- macro(DoubleAsInt32, NodeResultInt32) \
- /* Used to record places where we must check if a value is a number. */\
- macro(CheckNumber, NodeMustGenerate) \
+ macro(DoubleAsInt32, NodeResultInt32 | NodeExitsForward) \
\
/* Nodes for arithmetic operations. */\
macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
+ macro(ArithIMul, NodeResultInt32 | NodeMustGenerate) \
macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
@@ -124,7 +129,8 @@ namespace JSC { namespace DFG {
macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
macro(CheckStructure, NodeMustGenerate) \
- macro(ForwardCheckStructure, NodeMustGenerate) \
+ macro(CheckExecutable, NodeMustGenerate) \
+ macro(ForwardCheckStructure, NodeMustGenerate | NodeExitsForward) \
/* Transition watchpoints are a contract between the party setting the watchpoint */\
/* and the runtime system, where the party promises that the child object once had */\
/* the structure being watched, and the runtime system in turn promises that the */\
@@ -137,7 +143,7 @@ namespace JSC { namespace DFG {
/* the object's structure does not need to be rechecked due to side-effecting */\
/* (clobbering) operations. */\
macro(StructureTransitionWatchpoint, NodeMustGenerate) \
- macro(ForwardStructureTransitionWatchpoint, NodeMustGenerate) \
+ macro(ForwardStructureTransitionWatchpoint, NodeMustGenerate | NodeExitsForward) \
macro(PutStructure, NodeMustGenerate) \
macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
@@ -151,6 +157,10 @@ namespace JSC { namespace DFG {
macro(PutByOffset, NodeMustGenerate) \
macro(GetArrayLength, NodeResultInt32) \
macro(GetScope, NodeResultJS) \
+ macro(GetMyScope, NodeResultJS) \
+ macro(SetMyScope, NodeMustGenerate) \
+ macro(SkipTopScope, NodeResultJS) \
+ macro(SkipScope, NodeResultJS) \
macro(GetScopeRegisters, NodeResultStorage) \
macro(GetScopedVar, NodeResultJS) \
macro(PutScopedVar, NodeMustGenerate) \
@@ -159,7 +169,7 @@ namespace JSC { namespace DFG {
macro(GlobalVarWatchpoint, NodeMustGenerate) \
macro(PutGlobalVarCheck, NodeMustGenerate) \
macro(CheckFunction, NodeMustGenerate) \
- macro(InheritorIDWatchpoint, NodeMustGenerate) \
+ macro(AllocationProfileWatchpoint, NodeMustGenerate) \
\
/* Optimizations for array mutation. */\
macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
@@ -172,6 +182,7 @@ namespace JSC { namespace DFG {
/* Optimizations for string access */ \
macro(StringCharCodeAt, NodeResultInt32) \
macro(StringCharAt, NodeResultJS) \
+ macro(StringFromCharCode, NodeResultJS) \
\
/* Nodes for comparison operations. */\
macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
@@ -179,7 +190,9 @@ namespace JSC { namespace DFG {
macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
+ macro(CompareEqConstant, NodeResultBoolean | NodeMustGenerate) \
macro(CompareStrictEq, NodeResultBoolean) \
+ macro(CompareStrictEqConstant, NodeResultBoolean) \
\
/* Calls. */\
macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
@@ -208,9 +221,12 @@ namespace JSC { namespace DFG {
macro(IsString, NodeResultBoolean) \
macro(IsObject, NodeResultBoolean) \
macro(IsFunction, NodeResultBoolean) \
+ macro(TypeOf, NodeResultJS) \
macro(LogicalNot, NodeResultBoolean) \
macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
- macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
+ macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
+ macro(NewStringObject, NodeResultJS) \
+ macro(MakeRope, NodeResultJS) \
\
/* Nodes used for activations. Activation support works by having it anchored at */\
/* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
@@ -243,10 +259,17 @@ namespace JSC { namespace DFG {
\
macro(GarbageValue, NodeResultJS | NodeClobbersWorld) \
\
+ /* Count execution. */\
+ macro(CountExecution, 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 */\
/* different compiler. */\
- macro(ForceOSRExit, NodeMustGenerate)
+ macro(ForceOSRExit, NodeMustGenerate) \
+ \
+ /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \
+ /* baseline JIT to redo the watchdog timer check, and service the timer. */ \
+ macro(CheckWatchdogTimer, NodeMustGenerate) \
// 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).
@@ -265,7 +288,7 @@ inline NodeFlags defaultFlags(NodeType op)
FOR_EACH_DFG_OP(DFG_OP_ENUM)
#undef DFG_OP_ENUM
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGOSREntry.cpp b/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
index ed13ed5b5..5739593ee 100644
--- a/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
@@ -32,6 +32,7 @@
#include "CodeBlock.h"
#include "DFGNode.h"
#include "JIT.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
@@ -44,10 +45,10 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
ASSERT(!codeBlock->jitCodeMap());
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("OSR in %p(%p) from bc#%u\n", codeBlock, codeBlock->alternative(), bytecodeIndex);
+ dataLog("OSR in ", *codeBlock->alternative(), " -> ", *codeBlock, " from bc#", bytecodeIndex, "\n");
#endif
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
OSREntryData* entry = codeBlock->dfgOSREntryDataForBytecodeIndex(bytecodeIndex);
if (!entry) {
@@ -101,9 +102,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
if (!entry->m_expectedValues.argument(argument).validate(value)) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF(" OSR failed because argument %zu is %s, expected ", argument, value.description());
- entry->m_expectedValues.argument(argument).dump(WTF::dataFile());
- dataLogF(".\n");
+ dataLog(" OSR failed because argument ", argument, " is ", value, ", expected ", entry->m_expectedValues.argument(argument), ".\n");
#endif
return 0;
}
@@ -113,7 +112,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
if (entry->m_localsForcedDouble.get(local)) {
if (!exec->registers()[local].jsValue().isNumber()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF(" OSR failed because variable %zu is %s, expected number.\n", local, exec->registers()[local].jsValue().description());
+ dataLog(" OSR failed because variable ", local, " is ", exec->registers()[local].jsValue(), ", expected number.\n");
#endif
return 0;
}
@@ -121,9 +120,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
}
if (!entry->m_expectedValues.local(local).validate(exec->registers()[local].jsValue())) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF(" OSR failed because variable %zu is %s, expected ", local, exec->registers()[local].jsValue().description());
- entry->m_expectedValues.local(local).dump(WTF::dataFile());
- dataLogF(".\n");
+ dataLog(" OSR failed because variable ", local, " is ", exec->registers()[local].jsValue(), ", expected ", entry->m_expectedValues.local(local), ".\n");
#endif
return 0;
}
@@ -136,7 +133,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
// it seems silly: you'd be diverting the program to error handling when it
// would have otherwise just kept running albeit less quickly.
- if (!globalData->interpreter->stack().grow(&exec->registers()[codeBlock->m_numCalleeRegisters])) {
+ if (!vm->interpreter->stack().grow(&exec->registers()[codeBlock->m_numCalleeRegisters])) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLogF(" OSR failed because stack growth failed.\n");
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExit.cpp b/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
index b3701722e..ac085ec06 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
@@ -30,14 +30,14 @@
#include "DFGAssemblyHelpers.h"
#include "DFGSpeculativeJIT.h"
+#include "JSCellInlines.h"
namespace JSC { namespace DFG {
-OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAValueProfile valueProfile, MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned streamIndex, unsigned recoveryIndex)
+OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAValueProfile valueProfile, SpeculativeJIT* jit, unsigned streamIndex, unsigned recoveryIndex)
: m_jsValueSource(jsValueSource)
, m_valueProfile(valueProfile)
- , m_check(check)
- , m_nodeIndex(jit->m_compileIndex)
+ , m_patchableCodeOffset(0)
, m_codeOrigin(jit->m_codeOriginForOSR)
, m_codeOriginForExitProfile(m_codeOrigin)
, m_recoveryIndex(recoveryIndex)
@@ -50,11 +50,30 @@ OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAVal
ASSERT(m_codeOrigin.isSet());
}
-bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
+void OSRExit::setPatchableCodeOffset(MacroAssembler::PatchableJump check)
+{
+ m_patchableCodeOffset = check.m_jump.m_label.m_offset;
+}
+
+MacroAssembler::Jump OSRExit::getPatchableCodeOffsetAsJump() const
+{
+ return MacroAssembler::Jump(AssemblerLabel(m_patchableCodeOffset));
+}
+
+CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* dfgCodeBlock) const
+{
+ return CodeLocationJump(dfgCodeBlock->getJITCode().dataAddressAtOffset(m_patchableCodeOffset));
+}
+
+void OSRExit::correctJump(LinkBuffer& linkBuffer)
+{
+ MacroAssembler::Label label;
+ label.m_label.m_offset = m_patchableCodeOffset;
+ m_patchableCodeOffset = linkBuffer.offsetOf(label);
+}
+
+bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock)
{
- if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
- return false;
-
FrequentExitSite exitSite;
if (m_kind == ArgumentsEscaped) {
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExit.h b/Source/JavaScriptCore/dfg/DFGOSRExit.h
index cd2434c11..c7c61686c 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExit.h
+++ b/Source/JavaScriptCore/dfg/DFGOSRExit.h
@@ -32,7 +32,6 @@
#include "CodeOrigin.h"
#include "DFGCommon.h"
-#include "DFGCorrectableJumpPoint.h"
#include "DFGExitProfile.h"
#include "DFGGPRInfo.h"
#include "DFGValueRecoveryOverride.h"
@@ -84,15 +83,14 @@ private:
// This structure describes how to exit the speculative path by
// going into baseline code.
struct OSRExit {
- OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, MacroAssembler::Jump, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = 0);
+ OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = 0);
MacroAssemblerCodeRef m_code;
JSValueSource m_jsValueSource;
MethodOfGettingAValueProfile m_valueProfile;
-
- CorrectableJumpPoint m_check;
- NodeIndex m_nodeIndex;
+
+ unsigned m_patchableCodeOffset;
CodeOrigin m_codeOrigin;
CodeOrigin m_codeOriginForExitProfile;
@@ -102,28 +100,30 @@ struct OSRExit {
ExitKind m_kind;
uint32_t m_count;
- bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
+ bool considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
{
if (!m_count || !exitKindIsCountable(m_kind))
return false;
- return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
+ return considerAddingAsFrequentExitSiteSlow(profiledCodeBlock);
}
-
+
+ void setPatchableCodeOffset(MacroAssembler::PatchableJump);
+ MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
+ CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
+ void correctJump(LinkBuffer&);
+
unsigned m_streamIndex;
int m_lastSetOperand;
RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
private:
- bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
+ bool considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock);
};
-#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
struct SpeculationFailureDebugInfo {
CodeBlock* codeBlock;
- NodeIndex nodeIndex;
};
-#endif
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h b/Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h
new file mode 100644
index 000000000..9679545b4
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h
@@ -0,0 +1,48 @@
+/*
+ * 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 DFGOSRExitCompilationInfo_h
+#define DFGOSRExitCompilationInfo_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "CodeOrigin.h"
+#include "DFGCommon.h"
+#include "MacroAssembler.h"
+
+namespace JSC { namespace DFG {
+
+struct OSRExitCompilationInfo {
+ MacroAssembler::JumpList m_failureJumps;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGOSRExitCompilationInfo_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
index 5d2155cba..b554602a6 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
@@ -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
@@ -31,6 +31,7 @@
#include "CallFrame.h"
#include "DFGCommon.h"
#include "LinkBuffer.h"
+#include "Operations.h"
#include "RepatchBuffer.h"
#include <wtf/StringPrintStream.h>
@@ -47,9 +48,9 @@ void compileOSRExit(ExecState* exec)
ASSERT(codeBlock);
ASSERT(codeBlock->getJITType() == JITCode::DFGJIT);
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
- uint32_t exitIndex = globalData->osrExitIndex;
+ uint32_t exitIndex = vm->osrExitIndex;
OSRExit& exit = codeBlock->osrExit(exitIndex);
// Make sure all code on our inline stack is JIT compiled. This is necessary since
@@ -84,32 +85,44 @@ void compileOSRExit(ExecState* exec)
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog(
"Generating OSR exit #", exitIndex, " (seq#", exit.m_streamIndex,
- ", bc#", exit.m_codeOrigin.bytecodeIndex, ", @", exit.m_nodeIndex, ", ",
- exitKindToString(exit.m_kind), ") for ", *codeBlock, ".\n");
+ ", bc#", exit.m_codeOrigin.bytecodeIndex, ", ",
+ exit.m_kind, ") for ", *codeBlock, ".\n");
#endif
{
- CCallHelpers jit(globalData, codeBlock);
+ CCallHelpers jit(vm, codeBlock);
OSRExitCompiler exitCompiler(jit);
jit.jitAssertHasValidCallFrame();
+
+ if (vm->m_perBytecodeProfiler && codeBlock->compilation()) {
+ Profiler::Database& database = *vm->m_perBytecodeProfiler;
+ Profiler::Compilation* compilation = codeBlock->compilation();
+
+ Profiler::OSRExit* profilerExit = compilation->addOSRExit(
+ exitIndex, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
+ exit.m_kind,
+ exit.m_watchpointIndex != std::numeric_limits<unsigned>::max());
+ jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
+ }
+
exitCompiler.compileExit(exit, operands, recovery);
- LinkBuffer patchBuffer(*globalData, &jit, codeBlock);
+ LinkBuffer patchBuffer(*vm, &jit, codeBlock);
exit.m_code = FINALIZE_CODE_IF(
shouldShowDisassembly(),
patchBuffer,
- ("DFG OSR exit #%u (bc#%u, @%u, %s) from %s",
- exitIndex, exit.m_codeOrigin.bytecodeIndex, exit.m_nodeIndex,
+ ("DFG OSR exit #%u (bc#%u, %s) from %s",
+ exitIndex, exit.m_codeOrigin.bytecodeIndex,
exitKindToString(exit.m_kind), toCString(*codeBlock).data()));
}
{
RepatchBuffer repatchBuffer(codeBlock);
- repatchBuffer.relink(exit.m_check.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code()));
+ repatchBuffer.relink(exit.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code()));
}
- globalData->osrExitJumpDestination = exit.m_code.code().executableAddress();
+ vm->osrExitJumpDestination = exit.m_code.code().executableAddress();
}
} // extern "C"
@@ -142,14 +155,15 @@ void OSRExitCompiler::handleExitCounts(const OSRExit& exit)
tooFewFails.link(&m_jit);
// 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()));
- targetValue = ExecutionCounter::clippedThreshold(m_jit.codeBlock()->globalObject(), targetValue);
- 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()));
+ int32_t activeThreshold =
+ m_jit.baselineCodeBlock()->counterValueForOptimizeAfterLongWarmUp();
+ int32_t targetValue = ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt(
+ activeThreshold, m_jit.baselineCodeBlock());
+ int32_t clippedValue =
+ ExecutionCounter::clippedThreshold(m_jit.codeBlock()->globalObject(), targetValue);
+ m_jit.store32(AssemblyHelpers::TrustedImm32(-clippedValue), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecuteCounter()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(activeThreshold), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionActiveThreshold()));
+ m_jit.store32(AssemblyHelpers::TrustedImm32(ExecutionCounter::formattedTotalCount(clippedValue)), AssemblyHelpers::Address(GPRInfo::regT0, CodeBlock::offsetOfJITExecutionTotalCount()));
doneAdjusting.link(&m_jit);
}
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
index 732e67c30..4c92cc370 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
@@ -29,6 +29,7 @@
#if ENABLE(DFG_JIT) && USE(JSVALUE32_64)
#include "DFGOperations.h"
+#include "Operations.h"
#include <wtf/DataLog.h>
namespace JSC { namespace DFG {
@@ -37,7 +38,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
{
// 1) Pro-forma stuff.
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("OSR exit for Node @%d (", (int)exit.m_nodeIndex);
+ dataLogF("OSR exit (");
for (CodeOrigin codeOrigin = exit.m_codeOrigin; ; codeOrigin = codeOrigin.inlineCallFrame->caller) {
dataLogF("bc#%u", codeOrigin.bytecodeIndex);
if (!codeOrigin.inlineCallFrame)
@@ -47,13 +48,13 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
dataLogF(") at JIT offset 0x%x ", m_jit.debugOffset());
dumpOperands(operands, WTF::dataFile());
#endif
-#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
- SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
- debugInfo->codeBlock = m_jit.codeBlock();
- debugInfo->nodeIndex = exit.m_nodeIndex;
- m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
-#endif
+ if (Options::printEachOSRExit()) {
+ SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
+ debugInfo->codeBlock = m_jit.codeBlock();
+
+ m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
+ }
#if DFG_ENABLE(JIT_BREAK_ON_SPECULATION_FAILURE)
m_jit.breakpoint();
@@ -263,7 +264,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
}
unsigned scratchBufferLengthBeforeUInt32s = numberOfPoisonedVirtualRegisters + ((numberOfDisplacedVirtualRegisters * 2) <= GPRInfo::numberOfRegisters ? 0 : numberOfDisplacedVirtualRegisters);
- ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(sizeof(EncodedJSValue) * (scratchBufferLengthBeforeUInt32s + (haveUInt32s ? 2 : 0)));
+ ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * (scratchBufferLengthBeforeUInt32s + (haveUInt32s ? 2 : 0)));
EncodedJSValue* scratchDataBuffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
// From here on, the code assumes that it is profitable to maximize the distance
@@ -640,7 +641,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
CodeBlock* baselineCodeBlockForCaller = m_jit.baselineCodeBlockFor(inlineCallFrame->caller);
Vector<BytecodeAndMachineOffset>& decodedCodeMap = m_jit.decodedCodeMapFor(baselineCodeBlockForCaller);
unsigned returnBytecodeIndex = inlineCallFrame->caller.bytecodeIndex + OPCODE_LENGTH(op_call);
- BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(decodedCodeMap.begin(), decodedCodeMap.size(), returnBytecodeIndex);
+ BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(decodedCodeMap, decodedCodeMap.size(), returnBytecodeIndex, BytecodeAndMachineOffset::getBytecodeIndex);
ASSERT(mapping);
ASSERT(mapping->m_bytecodeIndex == returnBytecodeIndex);
@@ -656,13 +657,15 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock)));
m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
- m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
+ if (!inlineCallFrame->isClosureCall())
+ m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CallerFrame)));
m_jit.storePtr(callerFrameGPR, AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CallerFrame)));
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ReturnPC)));
m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
- m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
+ if (!inlineCallFrame->isClosureCall())
+ m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
}
// 14) Create arguments if necessary and place them into the appropriate aliased
@@ -749,7 +752,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
CodeBlock* baselineCodeBlock = m_jit.baselineCodeBlockFor(exit.m_codeOrigin);
Vector<BytecodeAndMachineOffset>& decodedCodeMap = m_jit.decodedCodeMapFor(baselineCodeBlock);
- BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(decodedCodeMap.begin(), decodedCodeMap.size(), exit.m_codeOrigin.bytecodeIndex);
+ BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(decodedCodeMap, decodedCodeMap.size(), exit.m_codeOrigin.bytecodeIndex, BytecodeAndMachineOffset::getBytecodeIndex);
ASSERT(mapping);
ASSERT(mapping->m_bytecodeIndex == exit.m_codeOrigin.bytecodeIndex);
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
index 3138daea9..5f0ba1a68 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
#if ENABLE(DFG_JIT) && USE(JSVALUE64)
#include "DFGOperations.h"
+#include "Operations.h"
#include <wtf/DataLog.h>
namespace JSC { namespace DFG {
@@ -37,7 +38,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
{
// 1) Pro-forma stuff.
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("OSR exit for Node @%d (", (int)exit.m_nodeIndex);
+ dataLogF("OSR exit for (");
for (CodeOrigin codeOrigin = exit.m_codeOrigin; ; codeOrigin = codeOrigin.inlineCallFrame->caller) {
dataLogF("bc#%u", codeOrigin.bytecodeIndex);
if (!codeOrigin.inlineCallFrame)
@@ -47,13 +48,13 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
dataLogF(") ");
dumpOperands(operands, WTF::dataFile());
#endif
-#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
- SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
- debugInfo->codeBlock = m_jit.codeBlock();
- debugInfo->nodeIndex = exit.m_nodeIndex;
-
- m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
-#endif
+
+ if (Options::printEachOSRExit()) {
+ SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo;
+ debugInfo->codeBlock = m_jit.codeBlock();
+
+ m_jit.debugCall(debugOperationPrintSpeculationFailure, debugInfo);
+ }
#if DFG_ENABLE(JIT_BREAK_ON_SPECULATION_FAILURE)
m_jit.breakpoint();
@@ -137,10 +138,6 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
if (!!exit.m_valueProfile) {
EncodedJSValue* bucket = exit.m_valueProfile.getSpecFailBucket(0);
-#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
- dataLogF(" (have exit profile, bucket %p) ", bucket);
-#endif
-
if (exit.m_jsValueSource.isAddress()) {
// We can't be sure that we have a spare register. So use the tagTypeNumberRegister,
// since we know how to restore it.
@@ -263,7 +260,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
dataLogF(" ");
#endif
- ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(sizeof(EncodedJSValue) * std::max(haveUInt32s ? 2u : 0u, numberOfPoisonedVirtualRegisters + (numberOfDisplacedVirtualRegisters <= GPRInfo::numberOfRegisters ? 0 : numberOfDisplacedVirtualRegisters)));
+ ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(sizeof(EncodedJSValue) * std::max(haveUInt32s ? 2u : 0u, numberOfPoisonedVirtualRegisters + (numberOfDisplacedVirtualRegisters <= GPRInfo::numberOfRegisters ? 0 : numberOfDisplacedVirtualRegisters)));
EncodedJSValue* scratchDataBuffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
// From here on, the code assumes that it is profitable to maximize the distance
@@ -608,7 +605,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
CodeBlock* baselineCodeBlockForCaller = m_jit.baselineCodeBlockFor(inlineCallFrame->caller);
Vector<BytecodeAndMachineOffset>& decodedCodeMap = m_jit.decodedCodeMapFor(baselineCodeBlockForCaller);
unsigned returnBytecodeIndex = inlineCallFrame->caller.bytecodeIndex + OPCODE_LENGTH(op_call);
- BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(decodedCodeMap.begin(), decodedCodeMap.size(), returnBytecodeIndex);
+ BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(decodedCodeMap, decodedCodeMap.size(), returnBytecodeIndex, BytecodeAndMachineOffset::getBytecodeIndex);
ASSERT(mapping);
ASSERT(mapping->m_bytecodeIndex == returnBytecodeIndex);
@@ -623,11 +620,13 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
callerFrameGPR = GPRInfo::callFrameRegister;
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock)));
- m_jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->callee->scope()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
+ if (!inlineCallFrame->isClosureCall())
+ m_jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->callee->scope()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain)));
m_jit.store64(callerFrameGPR, AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CallerFrame)));
m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ReturnPC)));
m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount)));
- m_jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->callee.get()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
+ if (!inlineCallFrame->isClosureCall())
+ m_jit.store64(AssemblyHelpers::TrustedImm64(JSValue::encode(JSValue(inlineCallFrame->callee.get()))), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee)));
}
// 15) Create arguments if necessary and place them into the appropriate aliased
@@ -696,7 +695,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
CodeBlock* baselineCodeBlock = m_jit.baselineCodeBlockFor(exit.m_codeOrigin);
Vector<BytecodeAndMachineOffset>& decodedCodeMap = m_jit.decodedCodeMapFor(baselineCodeBlock);
- BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(decodedCodeMap.begin(), decodedCodeMap.size(), exit.m_codeOrigin.bytecodeIndex);
+ BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(decodedCodeMap, decodedCodeMap.size(), exit.m_codeOrigin.bytecodeIndex, BytecodeAndMachineOffset::getBytecodeIndex);
ASSERT(mapping);
ASSERT(mapping->m_bytecodeIndex == exit.m_codeOrigin.bytecodeIndex);
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.cpp
new file mode 100644
index 000000000..fec99ec9a
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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 "DFGOSRExitJumpPlaceholder.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGJITCompiler.h"
+#include "DFGSpeculativeJIT.h"
+
+namespace JSC { namespace DFG {
+
+void OSRExitJumpPlaceholder::fill(JITCompiler& jit, const MacroAssembler::JumpList& jumps)
+{
+ if (!*this)
+ return;
+ jit.m_exitCompilationInfo[m_index].m_failureJumps = jumps;
+}
+
+void OSRExitJumpPlaceholder::fill(SpeculativeJIT* jit, const MacroAssembler::JumpList& jumps)
+{
+ fill(jit->m_jit, jumps);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.h b/Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.h
new file mode 100644
index 000000000..4e016a406
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGOSRExitJumpPlaceholder.h
@@ -0,0 +1,71 @@
+/*
+ * 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 DFGOSRExitJumpPlaceholder_h
+#define DFGOSRExitJumpPlaceholder_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "MacroAssembler.h"
+
+namespace JSC { namespace DFG {
+
+class JITCompiler;
+class SpeculativeJIT;
+
+class OSRExitJumpPlaceholder {
+public:
+ OSRExitJumpPlaceholder()
+ : m_index(std::numeric_limits<unsigned>::max())
+ {
+ }
+
+private:
+ friend class SpeculativeJIT;
+
+ OSRExitJumpPlaceholder(unsigned index)
+ : m_index(index)
+ {
+ }
+
+public:
+ bool operator!() const { return m_index == std::numeric_limits<unsigned>::max(); }
+
+ void fill(JITCompiler&, const MacroAssembler::JumpList&);
+ void fill(SpeculativeJIT*, const MacroAssembler::JumpList&);
+
+private:
+ unsigned m_index;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGOSRExitJumpPlaceholder_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index bb9ccc37d..29a0b2b61 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -39,10 +39,12 @@
#include "JIT.h"
#include "JITExceptions.h"
#include "JSActivation.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSNameScope.h"
#include "NameInstance.h"
+#include "ObjectConstructor.h"
#include "Operations.h"
+#include "StringConstructor.h"
#include <wtf/InlineASM.h>
#if ENABLE(JIT)
@@ -259,6 +261,53 @@
"b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
);
+#elif COMPILER(GCC) && CPU(SH4)
+
+#define SH4_SCRATCH_REGISTER "r11"
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
+ asm( \
+ ".text" "\n" \
+ ".globl " SYMBOL_STRING(function) "\n" \
+ HIDE_SYMBOL(function) "\n" \
+ SYMBOL_STRING(function) ":" "\n" \
+ "sts pr, r5" "\n" \
+ "bra " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
+ "nop" "\n" \
+ );
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
+ asm( \
+ ".text" "\n" \
+ ".globl " SYMBOL_STRING(function) "\n" \
+ HIDE_SYMBOL(function) "\n" \
+ SYMBOL_STRING(function) ":" "\n" \
+ "sts pr, r7" "\n" \
+ "mov.l 2f, " SH4_SCRATCH_REGISTER "\n" \
+ "braf " SH4_SCRATCH_REGISTER "\n" \
+ "nop" "\n" \
+ "1: .balign 4" "\n" \
+ "2: .long " LOCAL_REFERENCE(function) "WithReturnAddress-1b" "\n" \
+ );
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset, scratch) \
+ asm( \
+ ".text" "\n" \
+ ".globl " SYMBOL_STRING(function) "\n" \
+ HIDE_SYMBOL(function) "\n" \
+ SYMBOL_STRING(function) ":" "\n" \
+ "sts pr, " scratch "\n" \
+ "mov.l " scratch ", @(" STRINGIZE(offset) ", r15)" "\n" \
+ "mov.l 2f, " scratch "\n" \
+ "braf " scratch "\n" \
+ "nop" "\n" \
+ "1: .balign 4" "\n" \
+ "2: .long " LOCAL_REFERENCE(function) "WithReturnAddress-1b" "\n" \
+ );
+
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 0, SH4_SCRATCH_REGISTER)
+#define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 4, SH4_SCRATCH_REGISTER)
+
#endif
#define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
@@ -282,13 +331,13 @@ namespace JSC { namespace DFG {
template<bool strict>
static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
if (baseValue.isObject()) {
JSObject* object = asObject(baseValue);
if (object->canSetIndexQuickly(index)) {
- object->setIndexQuickly(globalData, index, value);
+ object->setIndexQuickly(vm, index, value);
return;
}
@@ -302,8 +351,8 @@ static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index,
template<bool strict>
ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue baseValue = JSValue::decode(encodedBase);
JSValue property = JSValue::decode(encodedProperty);
@@ -331,7 +380,7 @@ ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exe
// Don't put to an object if toString throws an exception.
Identifier ident(exec, property.toString(exec)->value(exec));
- if (!globalData->exception) {
+ if (!vm->exception) {
PutPropertySlot slot(strict);
baseValue.put(exec, ident, value, slot);
}
@@ -341,37 +390,37 @@ extern "C" {
EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
}
-JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* constructor)
+JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
#if !ASSERT_DISABLED
ConstructData constructData;
ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
#endif
- return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->cachedInheritorID(exec));
+ return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
}
JSCell* DFG_OPERATION operationNewObject(ExecState* exec, Structure* structure)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return constructEmptyObject(exec, structure);
}
EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue op1 = JSValue::decode(encodedOp1);
JSValue op2 = JSValue::decode(encodedOp2);
@@ -381,8 +430,8 @@ EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue e
EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue op1 = JSValue::decode(encodedOp1);
JSValue op2 = JSValue::decode(encodedOp2);
@@ -397,8 +446,8 @@ EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, Encoded
static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
if (base->isObject()) {
JSObject* object = asObject(base);
@@ -414,8 +463,8 @@ static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t in
EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue baseValue = JSValue::decode(encodedBase);
JSValue property = JSValue::decode(encodedProperty);
@@ -445,8 +494,8 @@ EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue e
EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue property = JSValue::decode(encodedProperty);
@@ -471,8 +520,8 @@ EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base
EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
if (index < 0) {
// Go the slowest way possible becase negative indices don't use indexed storage.
@@ -485,8 +534,8 @@ EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray*
EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue baseValue = JSValue::decode(base);
PropertySlot slot(baseValue);
@@ -496,8 +545,8 @@ EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue ba
J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -515,8 +564,8 @@ EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecStat
J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList);
EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -534,8 +583,8 @@ EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(Exe
J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -556,16 +605,16 @@ EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState
EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(function(exec, asObject(base), *ident));
}
EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
GetterSetter* getterSetter = asGetterSetter(value);
JSObject* getter = getterSetter->getter();
@@ -578,40 +627,40 @@ EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base,
void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
}
void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
}
void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
}
void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
}
void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
if (index >= 0) {
array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
@@ -625,8 +674,8 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSO
void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
if (index >= 0) {
array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
@@ -640,8 +689,8 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec,
void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
@@ -657,8 +706,8 @@ void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exe
void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
@@ -674,8 +723,8 @@ void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState*
EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
array->push(exec, JSValue::decode(encodedValue));
return JSValue::encode(jsNumber(array->length()));
@@ -683,8 +732,8 @@ EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue
EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
return JSValue::encode(jsNumber(array->length()));
@@ -692,16 +741,16 @@ EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double va
EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(array->pop(exec));
}
EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
@@ -710,8 +759,8 @@ EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec,
EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
if (!base->inherits(&RegExpObject::s_info))
return throwVMTypeError(exec);
@@ -723,8 +772,8 @@ EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base,
size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
if (!base->inherits(&RegExpObject::s_info)) {
throwTypeError(exec);
@@ -738,8 +787,8 @@ size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell*
void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
PutPropertySlot slot(true);
base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
@@ -747,8 +796,8 @@ void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encode
void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
PutPropertySlot slot(false);
base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
@@ -756,29 +805,29 @@ void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue enc
void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
PutPropertySlot slot(true);
ASSERT(base->isObject());
- asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
+ asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot);
}
void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
PutPropertySlot slot(false);
ASSERT(base->isObject());
- asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
+ asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot);
}
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -801,8 +850,8 @@ void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* ex
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -825,8 +874,8 @@ void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState*
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -835,7 +884,7 @@ void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecSta
PutPropertySlot slot(true);
ASSERT(base->isObject());
- asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
+ asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
if (accessType != static_cast<AccessType>(stubInfo.accessType))
return;
@@ -849,8 +898,8 @@ void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecSta
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -859,7 +908,7 @@ void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(Exec
PutPropertySlot slot(false);
ASSERT(base->isObject());
- asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
+ asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
if (accessType != static_cast<AccessType>(stubInfo.accessType))
return;
@@ -873,8 +922,8 @@ void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(Exec
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -894,8 +943,8 @@ void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* e
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -915,8 +964,8 @@ void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -925,7 +974,7 @@ void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecSt
PutPropertySlot slot(true);
ASSERT(base->isObject());
- asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
+ asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
if (accessType != static_cast<AccessType>(stubInfo.accessType))
return;
@@ -936,8 +985,8 @@ void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecSt
V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
@@ -946,7 +995,7 @@ void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(Exe
PutPropertySlot slot(false);
ASSERT(base->isObject());
- asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
+ asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
if (accessType != static_cast<AccessType>(stubInfo.accessType))
return;
@@ -956,48 +1005,65 @@ void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(Exe
size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
}
size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
}
size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
}
size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
}
size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
}
+#if USE(JSVALUE64)
+EncodedJSValue DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
+#else
+size_t DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
+#endif
+{
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+
+ bool result = asString(left)->value(exec) == asString(right)->value(exec);
+#if USE(JSVALUE64)
+ return JSValue::encode(jsBoolean(result));
+#else
+ return result;
+#endif
+}
+
size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue op1 = JSValue::decode(encodedOp1);
JSValue op2 = JSValue::decode(encodedOp2);
@@ -1010,8 +1076,8 @@ size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValu
size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue src1 = JSValue::decode(encodedOp1);
JSValue src2 = JSValue::decode(encodedOp2);
@@ -1022,7 +1088,7 @@ size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue en
static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
execCallee->setScope(exec->scope());
execCallee->setCodeBlock(0);
@@ -1034,18 +1100,18 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ
ASSERT(callType != CallTypeJS);
if (callType == CallTypeHost) {
- NativeCallFrameTracer tracer(globalData, execCallee);
+ NativeCallFrameTracer tracer(vm, execCallee);
execCallee->setCallee(asObject(callee));
- globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
- if (globalData->exception)
- return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
+ vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
+ if (vm->exception)
+ return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
return reinterpret_cast<void*>(getHostCallReturnValue);
}
ASSERT(callType == CallTypeNone);
- exec->globalData().exception = createNotAFunctionError(exec, callee);
- return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
+ exec->vm().exception = createNotAFunctionError(exec, callee);
+ return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
}
ASSERT(kind == CodeForConstruct);
@@ -1056,25 +1122,25 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ
ASSERT(constructType != ConstructTypeJS);
if (constructType == ConstructTypeHost) {
- NativeCallFrameTracer tracer(globalData, execCallee);
+ NativeCallFrameTracer tracer(vm, execCallee);
execCallee->setCallee(asObject(callee));
- globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
- if (globalData->exception)
- return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
+ vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
+ if (vm->exception)
+ return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
return reinterpret_cast<void*>(getHostCallReturnValue);
}
ASSERT(constructType == ConstructTypeNone);
- exec->globalData().exception = createNotAConstructorError(exec, callee);
- return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
+ exec->vm().exception = createNotAConstructorError(exec, callee);
+ return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
}
inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue calleeAsValue = execCallee->calleeAsValue();
JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
@@ -1093,8 +1159,8 @@ inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
if (error) {
- globalData->exception = createStackOverflowError(exec);
- return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+ vm->exception = createStackOverflowError(exec);
+ return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
@@ -1123,8 +1189,8 @@ char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell)
{
ExecState* exec = execCallee->callerFrame();
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue calleeAsValue = execCallee->calleeAsValue();
calleeAsFunctionCell = getJSFunction(calleeAsValue);
@@ -1138,8 +1204,8 @@ inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKin
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
if (error) {
- exec->globalData().exception = error;
- return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
+ exec->vm().exception = error;
+ return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
}
}
return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
@@ -1212,31 +1278,31 @@ void DFG_OPERATION operationNotifyGlobalVarWrite(WatchpointSet* watchpointSet)
EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName, ResolveOperations* operations)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(JSScope::resolve(exec, *propertyName, operations));
}
EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(JSScope::resolveBase(exec, *propertyName, false, operations, putToBaseOperations));
}
EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(JSScope::resolveBase(exec, *propertyName, true, operations, putToBaseOperations));
}
EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOperation* resolveOperation, JSGlobalObject* globalObject, Identifier* propertyName)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
ASSERT(globalObject);
UNUSED_PARAM(resolveOperation);
UNUSED_PARAM(globalObject);
@@ -1246,93 +1312,88 @@ EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOper
EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
}
-EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* buffer, size_t size)
-{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
-
- return JSValue::encode(jsString(exec, static_cast<Register*>(buffer), size));
-}
-
char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
}
char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
- return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure));
+ return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
}
char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
-
- return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure, size));
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+
+ if (UNLIKELY(size < 0))
+ return bitwise_cast<char*>(throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
+
+ return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
}
char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
}
EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
RegExp* regexp = static_cast<RegExp*>(regexpPtr);
if (!regexp->isValid()) {
throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
return JSValue::encode(jsUndefined());
}
- return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
+ return JSValue::encode(RegExpObject::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
}
JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
- JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock());
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+ JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
exec->setScope(activation);
return activation;
}
JSCell* DFG_OPERATION operationCreateArguments(ExecState* exec)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
// NB: This needs to be exceedingly careful with top call frame tracking, since it
// may be called from OSR exit, while the state of the call stack is bizarre.
- Arguments* result = Arguments::create(globalData, exec);
- ASSERT(!globalData.exception);
+ Arguments* result = Arguments::create(vm, exec);
+ ASSERT(!vm.exception);
return result;
}
JSCell* DFG_OPERATION operationCreateInlinedArguments(
ExecState* exec, InlineCallFrame* inlineCallFrame)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
// NB: This needs to be exceedingly careful with top call frame tracking, since it
// may be called from OSR exit, while the state of the call stack is bizarre.
- Arguments* result = Arguments::create(globalData, exec, inlineCallFrame);
- ASSERT(!globalData.exception);
+ Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
+ ASSERT(!vm.exception);
return result;
}
@@ -1355,11 +1416,11 @@ void DFG_OPERATION operationTearOffInlinedArguments(
EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
// Here we can assume that the argumernts were created. Because otherwise the JIT code would
// have not made this call.
- Identifier ident(&globalData, "length");
+ Identifier ident(&vm, "length");
JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
PropertySlot slot(baseValue);
return JSValue::encode(baseValue.get(exec, ident, slot));
@@ -1367,15 +1428,15 @@ EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_
EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
// If there are no arguments, and we're accessing out of bounds, then we have to create the
// arguments in case someone has installed a getter on a numeric property.
if (!argumentsValue)
- exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->globalData(), exec);
+ exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec);
return JSValue::encode(argumentsValue.get(exec, index));
}
@@ -1383,8 +1444,8 @@ EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t
EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(
ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
@@ -1392,26 +1453,34 @@ EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(
// arguments in case someone has installed a getter on a numeric property.
if (!argumentsValue) {
exec->uncheckedR(argumentsRegister) = argumentsValue =
- Arguments::create(exec->globalData(), exec, inlineCallFrame);
+ Arguments::create(exec->vm(), exec, inlineCallFrame);
}
return JSValue::encode(argumentsValue.get(exec, index));
}
-JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
+JSCell* DFG_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSCell* functionExecutable)
{
ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
}
+EncodedJSValue DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
+{
+ ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+ return JSValue::encode(JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope()));
+}
+
JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
{
ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
FunctionExecutable* functionExecutable =
static_cast<FunctionExecutable*>(functionExecutableAsCell);
@@ -1428,86 +1497,162 @@ size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
return jsIsFunctionType(JSValue::decode(value));
}
+JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
+{
+ return jsTypeStringForValue(exec, JSValue(value)).asCell();
+}
+
void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity());
- ASSERT(!globalData.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
- base->setStructureAndReallocateStorageIfNecessary(globalData, structure);
- base->putDirectOffset(globalData, offset, JSValue::decode(value));
+ ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
+ base->setStructureAndReallocateStorageIfNecessary(vm, structure);
+ base->putDirect(vm, offset, JSValue::decode(value));
}
char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
return reinterpret_cast<char*>(
- Butterfly::createUninitialized(globalData, 0, initialOutOfLineCapacity, false, 0));
+ Butterfly::createUninitialized(vm, 0, initialOutOfLineCapacity, false, 0));
}
char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
return reinterpret_cast<char*>(
- Butterfly::createUninitialized(globalData, 0, newSize, false, 0));
+ Butterfly::createUninitialized(vm, 0, newSize, false, 0));
}
char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
ASSERT(!object->structure()->outOfLineCapacity());
- Butterfly* result = object->growOutOfLineStorage(globalData, 0, initialOutOfLineCapacity);
+ Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
object->setButterflyWithoutChangingStructure(result);
return reinterpret_cast<char*>(result);
}
char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- Butterfly* result = object->growOutOfLineStorage(globalData, object->structure()->outOfLineCapacity(), newSize);
+ Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
object->setButterflyWithoutChangingStructure(result);
return reinterpret_cast<char*>(result);
}
-char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSObject* object)
+char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- return reinterpret_cast<char*>(object->ensureInt32(globalData));
+ if (!cell->isObject())
+ return 0;
+
+ return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
+}
+
+char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ if (!cell->isObject())
+ return 0;
+
+ return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
+}
+
+char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ if (!cell->isObject())
+ return 0;
+
+ return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
+}
+
+char* DFG_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ if (!cell->isObject())
+ return 0;
+
+ return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data());
+}
+
+char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ if (!cell->isObject())
+ return 0;
+
+ return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
+}
+
+StringImpl* DFG_OPERATION operationResolveRope(ExecState* exec, JSString* string)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return string->value(exec).impl();
}
-char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSObject* object)
+JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- return reinterpret_cast<char*>(object->ensureDouble(globalData));
+ return StringObject::create(exec, structure, string);
}
-char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSObject* object)
+JSCell* DFG_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- return reinterpret_cast<char*>(object->ensureContiguous(globalData));
+ return JSValue(cell).toString(exec);
}
-char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSObject* object)
+JSCell* DFG_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
{
- JSGlobalData& globalData = exec->globalData();
- NativeCallFrameTracer tracer(&globalData, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- return reinterpret_cast<char*>(object->ensureArrayStorage(globalData));
+ return JSValue::decode(value).toString(exec);
+}
+
+JSCell* DFG_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return JSRopeString::create(vm, left, right);
+}
+
+JSCell* DFG_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return JSRopeString::create(vm, a, b, c);
}
double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
@@ -1515,24 +1660,31 @@ double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
return fmod(a, b);
}
+JSCell* DFG_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
+{
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+ return JSC::stringFromCharCode(exec, op1);
+}
+
DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue exceptionValue = exec->exception();
ASSERT(exceptionValue);
unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
- ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, vPCIndex);
+ ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, vPCIndex);
ASSERT(handler.catchRoutine);
return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
}
DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
JSValue exceptionValue = exec->exception();
ASSERT(exceptionValue);
@@ -1541,23 +1693,15 @@ DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, St
while (codeOrigin.inlineCallFrame)
codeOrigin = codeOrigin.inlineCallFrame->caller;
- ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, codeOrigin.bytecodeIndex);
+ ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, codeOrigin.bytecodeIndex);
ASSERT(handler.catchRoutine);
return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
}
-double DFG_OPERATION dfgConvertJSValueToNumber(ExecState* exec, EncodedJSValue value)
-{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
-
- return JSValue::decode(value).toNumber(exec);
-}
-
size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
// toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
return JSValue::decode(value).toUInt32(exec);
@@ -1565,24 +1709,22 @@ size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue va
size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
return JSValue::decode(encodedOp).toBoolean(exec);
}
-#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
-void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw)
+void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
CodeBlock* codeBlock = debugInfo->codeBlock;
CodeBlock* alternative = codeBlock->alternative();
dataLog(
- "Speculation failure in ", *codeBlock, " at @", debugInfo->nodeIndex,
- " with ");
+ "Speculation failure in ", *codeBlock, " with ");
if (alternative) {
dataLog(
"executeCounter = ", alternative->jitExecuteCounter(),
@@ -1591,8 +1733,25 @@ void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void*
} else
dataLog("no alternative code block (i.e. we've been jettisoned)");
dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
+ dataLog(" GPRs at time of exit:");
+ char* scratchPointer = static_cast<char*>(scratch);
+ for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
+ GPRReg gpr = GPRInfo::toRegister(i);
+ dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
+ scratchPointer += sizeof(EncodedJSValue);
+ }
+ dataLog("\n");
+ dataLog(" FPRs at time of exit:");
+ for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
+ FPRReg fpr = FPRInfo::toRegister(i);
+ dataLog(" ", FPRInfo::debugName(fpr), ":");
+ uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
+ double value = *reinterpret_cast_ptr<double*>(scratchPointer);
+ dataLogF("%llx:%lf", static_cast<long long>(bits), value);
+ scratchPointer += sizeof(EncodedJSValue);
+ }
+ dataLog("\n");
}
-#endif
extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
{
@@ -1676,13 +1835,28 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
"move $a0, $s0" "\n"
"b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
);
+#elif COMPILER(GCC) && CPU(SH4)
+asm(
+".text" "\n"
+".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
+HIDE_SYMBOL(getHostCallReturnValue) "\n"
+SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
+ "add #-40, r14" "\n"
+ "mov.l @r14, r14" "\n"
+ "mov r14, r4" "\n"
+ "mov.l 2f, " SH4_SCRATCH_REGISTER "\n"
+ "braf " SH4_SCRATCH_REGISTER "\n"
+ "nop" "\n"
+ "1: .balign 4" "\n"
+ "2: .long " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "-1b\n"
+);
#endif
extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
{
if (!exec)
return JSValue::encode(JSValue());
- return JSValue::encode(exec->globalData().hostCallReturnValue);
+ return JSValue::encode(exec->vm().hostCallReturnValue);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h
index 00e6b07b7..2c7a5f7fa 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.h
+++ b/Source/JavaScriptCore/dfg/DFGOperations.h
@@ -61,6 +61,7 @@ extern "C" {
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_E)(ExecState*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EA)(ExecState*, JSArray*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EAZ)(ExecState*, JSArray*, int32_t);
+typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EC)(ExecState*, JSCell*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECI)(ExecState*, JSCell*, Identifier*);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue);
@@ -82,10 +83,17 @@ typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZ)(ExecState*, int32_t);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZIcfZ)(ExecState*, int32_t, InlineCallFrame*, int32_t);
typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZZ)(ExecState*, int32_t, int32_t);
typedef JSCell* DFG_OPERATION (*C_DFGOperation_E)(ExecState*);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EZ)(ExecState*, int32_t);
typedef JSCell* DFG_OPERATION (*C_DFGOperation_EC)(ExecState*, JSCell*);
typedef JSCell* DFG_OPERATION (*C_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*);
typedef JSCell* DFG_OPERATION (*C_DFGOperation_EIcf)(ExecState*, InlineCallFrame*);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EJ)(ExecState*, EncodedJSValue);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EJssSt)(ExecState*, JSString*, Structure*);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EJssJss)(ExecState*, JSString*, JSString*);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EJssJssJss)(ExecState*, JSString*, JSString*, JSString*);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EOZ)(ExecState*, JSObject*, int32_t);
typedef JSCell* DFG_OPERATION (*C_DFGOperation_ESt)(ExecState*, Structure*);
+typedef JSCell* DFG_OPERATION (*C_DFGOperation_EZ)(ExecState*, int32_t);
typedef double DFG_OPERATION (*D_DFGOperation_DD)(double, double);
typedef double DFG_OPERATION (*D_DFGOperation_ZZ)(int32_t, int32_t);
typedef double DFG_OPERATION (*D_DFGOperation_EJ)(ExecState*, EncodedJSValue);
@@ -108,6 +116,7 @@ typedef void DFG_OPERATION (*V_DFGOperation_EJPP)(ExecState*, EncodedJSValue, En
typedef void DFG_OPERATION (*V_DFGOperation_EPZJ)(ExecState*, void*, int32_t, EncodedJSValue);
typedef void DFG_OPERATION (*V_DFGOperation_W)(WatchpointSet*);
typedef char* DFG_OPERATION (*P_DFGOperation_E)(ExecState*);
+typedef char* DFG_OPERATION (*P_DFGOperation_EC)(ExecState*, JSCell*);
typedef char* DFG_OPERATION (*P_DFGOperation_EO)(ExecState*, JSObject*);
typedef char* DFG_OPERATION (*P_DFGOperation_EOS)(ExecState*, JSObject*, size_t);
typedef char* DFG_OPERATION (*P_DFGOperation_EOZ)(ExecState*, JSObject*, int32_t);
@@ -117,10 +126,12 @@ typedef char* DFG_OPERATION (*P_DFGOperation_ESt)(ExecState*, Structure*);
typedef char* DFG_OPERATION (*P_DFGOperation_EStPS)(ExecState*, Structure*, void*, size_t);
typedef char* DFG_OPERATION (*P_DFGOperation_EStSS)(ExecState*, Structure*, size_t, size_t);
typedef char* DFG_OPERATION (*P_DFGOperation_EStZ)(ExecState*, Structure*, int32_t);
+typedef StringImpl* DFG_OPERATION (*Str_DFGOperation_EJss)(ExecState*, JSString*);
+JSCell* DFG_OPERATION operationStringFromCharCode(ExecState*, int32_t) WTF_INTERNAL;
// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
JSCell* DFG_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
-JSCell* DFG_OPERATION operationCreateThis(ExecState*, JSCell* constructor) WTF_INTERNAL;
+JSCell* DFG_OPERATION operationCreateThis(ExecState*, JSObject* constructor, int32_t inlineCapacity) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationConvertThis(ExecState*, EncodedJSValue encodedOp1) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
@@ -139,7 +150,6 @@ EncodedJSValue DFG_OPERATION operationResolveBase(ExecState*, Identifier*, Resol
EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState*, Identifier*, ResolveOperations*, PutToBaseOperation*) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState*, ResolveOperation*, JSGlobalObject*, Identifier*) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState*, EncodedJSValue) WTF_INTERNAL;
-EncodedJSValue DFG_OPERATION operationStrCat(ExecState*, void*, size_t) WTF_INTERNAL;
char* DFG_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL;
char* DFG_OPERATION operationNewArrayBuffer(ExecState*, Structure*, size_t, size_t) WTF_INTERNAL;
char* DFG_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL;
@@ -177,6 +187,11 @@ size_t DFG_OPERATION operationCompareLessEq(ExecState*, EncodedJSValue encodedOp
size_t DFG_OPERATION operationCompareGreater(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
size_t DFG_OPERATION operationCompareGreaterEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
size_t DFG_OPERATION operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
+#if USE(JSVALUE64)
+EncodedJSValue DFG_OPERATION operationCompareStringEq(ExecState*, JSCell* left, JSCell* right) WTF_INTERNAL;
+#else
+size_t DFG_OPERATION operationCompareStringEq(ExecState*, JSCell* left, JSCell* right) WTF_INTERNAL;
+#endif
size_t DFG_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
size_t DFG_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
char* DFG_OPERATION operationVirtualCall(ExecState*) WTF_INTERNAL;
@@ -192,20 +207,29 @@ void DFG_OPERATION operationTearOffInlinedArguments(ExecState*, JSCell*, JSCell*
EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState*, int32_t) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(ExecState*, int32_t, InlineCallFrame*, int32_t) WTF_INTERNAL;
EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState*, int32_t, int32_t) WTF_INTERNAL;
-JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*) WTF_INTERNAL;
+JSCell* DFG_OPERATION operationNewFunctionNoCheck(ExecState*, JSCell*) WTF_INTERNAL;
+EncodedJSValue DFG_OPERATION operationNewFunction(ExecState*, JSCell*) WTF_INTERNAL;
JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*) WTF_INTERNAL;
double DFG_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
size_t DFG_OPERATION operationIsObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
+JSCell* DFG_OPERATION operationTypeOf(ExecState*, JSCell*) WTF_INTERNAL;
void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
char* DFG_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL;
char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL;
char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*, JSObject*, size_t newSize) WTF_INTERNAL;
-char* DFG_OPERATION operationEnsureInt32(ExecState*, JSObject*);
-char* DFG_OPERATION operationEnsureDouble(ExecState*, JSObject*);
-char* DFG_OPERATION operationEnsureContiguous(ExecState*, JSObject*);
-char* DFG_OPERATION operationEnsureArrayStorage(ExecState*, JSObject*);
+char* DFG_OPERATION operationEnsureInt32(ExecState*, JSCell*);
+char* DFG_OPERATION operationEnsureDouble(ExecState*, JSCell*);
+char* DFG_OPERATION operationEnsureContiguous(ExecState*, JSCell*);
+char* DFG_OPERATION operationRageEnsureContiguous(ExecState*, JSCell*);
+char* DFG_OPERATION operationEnsureArrayStorage(ExecState*, JSCell*);
+StringImpl* DFG_OPERATION operationResolveRope(ExecState*, JSString*);
+JSCell* DFG_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
+JSCell* DFG_OPERATION operationToStringOnCell(ExecState*, JSCell*);
+JSCell* DFG_OPERATION operationToString(ExecState*, EncodedJSValue);
+JSCell* DFG_OPERATION operationMakeRope2(ExecState*, JSString*, JSString*);
+JSCell* DFG_OPERATION operationMakeRope3(ExecState*, JSString*, JSString*, JSString*);
// 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.
@@ -248,15 +272,12 @@ inline DFGHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler)
DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState*, uint32_t) WTF_INTERNAL;
DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState*, StructureStubInfo*) WTF_INTERNAL;
-// These operations implement the implicitly called ToInt32, ToNumber, and ToBoolean conversions from ES5.
-double DFG_OPERATION dfgConvertJSValueToNumber(ExecState*, EncodedJSValue) WTF_INTERNAL;
+// These operations implement the implicitly called ToInt32 and ToBoolean conversions from ES5.
// This conversion returns an int32_t within a size_t such that the value is zero extended to fill the register.
size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState*, EncodedJSValue) WTF_INTERNAL;
size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState*, EncodedJSValue) WTF_INTERNAL;
-#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
-void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void*) WTF_INTERNAL;
-#endif
+void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void*, void*) WTF_INTERNAL;
void DFG_OPERATION triggerReoptimizationNow(CodeBlock*) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/dfg/DFGPhase.cpp b/Source/JavaScriptCore/dfg/DFGPhase.cpp
index 20301e814..32e039ec5 100644
--- a/Source/JavaScriptCore/dfg/DFGPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPhase.cpp
@@ -32,21 +32,21 @@
namespace JSC { namespace DFG {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
void Phase::beginPhase()
{
- dataLogF("Beginning DFG phase %s.\n", m_name);
- dataLogF("Graph before %s:\n", m_name);
+ if (!shouldDumpGraphAtEachPhase())
+ return;
+ dataLog("Beginning DFG phase ", m_name, ".\n");
+ dataLog("Before ", m_name, ":\n");
m_graph.dump();
}
-#endif
-#if DFG_ENABLE(PER_PHASE_VALIDATION)
void Phase::endPhase()
{
+ if (!Options::validateGraphAtEachPhase())
+ return;
validate(m_graph, DumpGraph);
}
-#endif
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGPhase.h b/Source/JavaScriptCore/dfg/DFGPhase.h
index 939e199e0..6de043bbd 100644
--- a/Source/JavaScriptCore/dfg/DFGPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGPhase.h
@@ -57,7 +57,7 @@ protected:
// Things you need to have a DFG compiler phase.
Graph& m_graph;
- JSGlobalData& globalData() { return m_graph.m_globalData; }
+ VM& vm() { return m_graph.m_vm; }
CodeBlock* codeBlock() { return m_graph.m_codeBlock; }
CodeBlock* profiledBlock() { return m_graph.m_profiledBlock; }
@@ -65,26 +65,16 @@ protected:
private:
// Call these hooks when starting and finishing.
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
void beginPhase();
-#else
- void beginPhase() { }
-#endif
-#if DFG_ENABLE(PER_PHASE_VALIDATION)
void endPhase();
-#else
- void endPhase() { }
-#endif
};
template<typename PhaseType>
bool runAndLog(PhaseType& phase)
{
bool result = phase.run();
-#if DFG_ENABLE(DEBUG_VERBOSE)
- if (result)
+ if (result && logCompilationChanges())
dataLogF("Phase %s changed the IR.\n", phase.name());
-#endif
return result;
}
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp
new file mode 100644
index 000000000..d5a592024
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGPredictionInjectionPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+class PredictionInjectionPhase : public Phase {
+public:
+ PredictionInjectionPhase(Graph& graph)
+ : Phase(graph, "prediction injection")
+ {
+ }
+
+ bool run()
+ {
+ ASSERT(m_graph.m_form == ThreadedCPS);
+ ASSERT(m_graph.m_unificationState == GloballyUnified);
+
+ ASSERT(codeBlock()->numParameters() >= 1);
+ for (size_t arg = 0; arg < static_cast<size_t>(codeBlock()->numParameters()); ++arg) {
+ ValueProfile* profile = profiledBlock()->valueProfileForArgument(arg);
+ if (!profile)
+ continue;
+
+ m_graph.m_arguments[arg]->variableAccessData()->predict(profile->computeUpdatedPrediction());
+
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLog(
+ "Argument [", arg, "] prediction: ",
+ SpeculationDump(m_graph.m_arguments[arg]->variableAccessData()->prediction()), "\n");
+#endif
+ }
+
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ if (!block->isOSRTarget)
+ continue;
+ if (block->bytecodeBegin != m_graph.m_osrEntryBytecodeIndex)
+ continue;
+ for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) {
+ Node* node = block->variablesAtHead.operand(
+ m_graph.m_mustHandleValues.operandForIndex(i));
+ if (!node)
+ continue;
+ ASSERT(node->hasLocal());
+ node->variableAccessData()->predict(
+ speculationFromValue(m_graph.m_mustHandleValues[i]));
+ }
+ }
+
+ return true;
+ }
+};
+
+bool performPredictionInjection(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Prediction Injection Phase");
+ return runPhase<PredictionInjectionPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.h b/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.h
new file mode 100644
index 000000000..00f04a3d3
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGPredictionInjectionPhase_h
+#define DFGPredictionInjectionPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Prediction Injection:
+//
+// Takes miscellaneous data about variable type predictions and injects them.
+// This includes argument predictions and OSR entry predictions.
+
+bool performPredictionInjection(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGPredictionInjectionPhase_h
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 4226fcc6a..980e6b447 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,9 +30,21 @@
#include "DFGGraph.h"
#include "DFGPhase.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
+SpeculatedType resultOfToPrimitive(SpeculatedType type)
+{
+ if (type & SpecObject) {
+ // Objects get turned into strings. So if the input has hints of objectness,
+ // the output will have hinsts of stringiness.
+ return mergeSpeculations(type & ~SpecObject, SpecString);
+ }
+
+ return type;
+}
+
class PredictionPropagationPhase : public Phase {
public:
PredictionPropagationPhase(Graph& graph)
@@ -42,6 +54,9 @@ public:
bool run()
{
+ ASSERT(m_graph.m_form == ThreadedCPS);
+ ASSERT(m_graph.m_unificationState == GloballyUnified);
+
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
m_count = 0;
#endif
@@ -69,13 +84,10 @@ public:
do {
m_changed = false;
doRoundOfDoubleVoting();
- propagateForward();
if (!m_changed)
break;
-
m_changed = false;
- doRoundOfDoubleVoting();
- propagateBackward();
+ propagateForward();
} while (m_changed);
return true;
@@ -84,85 +96,24 @@ public:
private:
bool setPrediction(SpeculatedType prediction)
{
- ASSERT(m_graph[m_compileIndex].hasResult());
+ ASSERT(m_currentNode->hasResult());
// setPrediction() is used when we know that there is no way that we can change
// our minds about what the prediction is going to be. There is no semantic
// difference between setPrediction() and mergeSpeculation() other than the
// increased checking to validate this property.
- ASSERT(m_graph[m_compileIndex].prediction() == SpecNone || m_graph[m_compileIndex].prediction() == prediction);
+ ASSERT(m_currentNode->prediction() == SpecNone || m_currentNode->prediction() == prediction);
- return m_graph[m_compileIndex].predict(prediction);
+ return m_currentNode->predict(prediction);
}
bool mergePrediction(SpeculatedType prediction)
{
- ASSERT(m_graph[m_compileIndex].hasResult());
+ ASSERT(m_currentNode->hasResult());
- return m_graph[m_compileIndex].predict(prediction);
- }
-
- bool isNotNegZero(NodeIndex nodeIndex)
- {
- if (!m_graph.isNumberConstant(nodeIndex))
- return false;
- double value = m_graph.valueOfNumberConstant(nodeIndex);
- return !value && 1.0 / value < 0.0;
- }
-
- bool isNotZero(NodeIndex nodeIndex)
- {
- if (!m_graph.isNumberConstant(nodeIndex))
- return false;
- return !!m_graph.valueOfNumberConstant(nodeIndex);
- }
-
- bool isWithinPowerOfTwoForConstant(Node& node, int power)
- {
- JSValue immediateValue = node.valueOfJSConstant(codeBlock());
- if (!immediateValue.isInt32())
- return false;
- int32_t intImmediate = immediateValue.asInt32();
- return intImmediate > -(1 << power) && intImmediate < (1 << power);
- }
-
- bool isWithinPowerOfTwoNonRecursive(NodeIndex nodeIndex, int power)
- {
- Node& node = m_graph[nodeIndex];
- if (node.op() != JSConstant)
- return false;
- return isWithinPowerOfTwoForConstant(node, power);
+ return m_currentNode->predict(prediction);
}
- bool isWithinPowerOfTwo(NodeIndex nodeIndex, int power)
- {
- Node& node = m_graph[nodeIndex];
- switch (node.op()) {
- case JSConstant: {
- return isWithinPowerOfTwoForConstant(node, power);
- }
-
- case BitAnd: {
- return isWithinPowerOfTwoNonRecursive(node.child1().index(), power)
- || isWithinPowerOfTwoNonRecursive(node.child2().index(), power);
- }
-
- case BitRShift:
- case BitURShift: {
- Node& shiftAmount = m_graph[node.child2()];
- if (shiftAmount.op() != JSConstant)
- return false;
- JSValue immediateValue = shiftAmount.valueOfJSConstant(codeBlock());
- if (!immediateValue.isInt32())
- return false;
- return immediateValue > 32 - power;
- }
-
- default:
- return false;
- }
- }
-
SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
{
if (!isNumberSpeculation(value))
@@ -177,16 +128,12 @@ private:
return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
}
- void propagate(Node& node)
+ void propagate(Node* node)
{
- if (!node.shouldGenerate())
- return;
-
- NodeType op = node.op();
- NodeFlags flags = node.flags() & NodeBackPropMask;
+ NodeType op = node->op();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" %s @%u: %s ", Graph::opName(op), m_compileIndex, nodeFlagsAsString(flags));
+ dataLog(" ", Graph::opName(op), " ", m_currentNode, ": ", NodeFlagsDump(node->flags()), " ");
#endif
bool changed = false;
@@ -194,37 +141,21 @@ private:
switch (op) {
case JSConstant:
case WeakJSConstant: {
- changed |= setPrediction(speculationFromValue(m_graph.valueOfJSConstant(m_compileIndex)));
+ changed |= setPrediction(speculationFromValue(m_graph.valueOfJSConstant(node)));
break;
}
case GetLocal: {
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
SpeculatedType prediction = variableAccessData->prediction();
if (prediction)
changed |= mergePrediction(prediction);
-
- changed |= variableAccessData->mergeFlags(flags);
break;
}
case SetLocal: {
- VariableAccessData* variableAccessData = node.variableAccessData();
- changed |= variableAccessData->predict(m_graph[node.child1()].prediction());
-
- // Assume conservatively that a SetLocal implies that the value may flow through a loop,
- // and so we would have overflow leading to the program "observing" numbers even if all
- // users of the value are doing toInt32. It might be worthwhile to revisit this at some
- // point and actually check if the data flow involves loops, but right now I don't think
- // we have evidence that this would be beneficial for benchmarks.
- changed |= m_graph[node.child1()].mergeFlags(variableAccessData->flags() | NodeUsedAsNumber);
- break;
- }
-
- case Flush: {
- // Make sure that the analysis knows that flushed locals escape.
- VariableAccessData* variableAccessData = node.variableAccessData();
- changed |= variableAccessData->mergeFlags(NodeUsedAsValue);
+ VariableAccessData* variableAccessData = node->variableAccessData();
+ changed |= variableAccessData->predict(node->child1()->prediction());
break;
}
@@ -233,69 +164,57 @@ private:
case BitXor:
case BitRShift:
case BitLShift:
- case BitURShift: {
+ case BitURShift:
+ case ArithIMul: {
changed |= setPrediction(SpecInt32);
- flags |= NodeUsedAsInt;
- flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ValueToInt32: {
changed |= setPrediction(SpecInt32);
- flags |= NodeUsedAsInt;
- flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
- changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
- case ArrayPop: {
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultFlags(node);
- break;
- }
-
- case ArrayPush: {
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
- break;
- }
-
+ case ArrayPop:
+ case ArrayPush:
case RegExpExec:
- case RegExpTest: {
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultFlags(node);
+ case RegExpTest:
+ case GetById:
+ case GetByIdFlush:
+ case GetMyArgumentByValSafe:
+ case GetByOffset:
+ case Call:
+ case Construct:
+ case GetGlobalVar:
+ case GetScopedVar:
+ case Resolve:
+ case ResolveBase:
+ case ResolveBaseStrictPut:
+ case ResolveGlobal: {
+ changed |= setPrediction(node->getHeapPrediction());
break;
}
case StringCharCodeAt: {
- changed |= mergePrediction(SpecInt32);
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
+ changed |= setPrediction(SpecInt32);
break;
}
case UInt32ToNumber: {
- if (nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (nodeCanSpeculateInteger(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(SpecNumber);
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
case ValueAdd: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
-
- AddSpeculationMode mode = DontSpeculateInteger;
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
- if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
+ if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
@@ -305,107 +224,62 @@ private:
} else
changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
}
-
- if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index()))
- flags &= ~NodeNeedsNegZero;
- if (m_graph[node.child1()].hasNumberResult() || m_graph[node.child2()].hasNumberResult())
- flags &= ~NodeUsedAsOther;
-
- if (mode != SpeculateInteger)
- flags |= NodeUsedAsNumber;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithAdd: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
-
- AddSpeculationMode mode = DontSpeculateInteger;
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
+ if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
}
-
- if (isNotNegZero(node.child1().index()) || isNotNegZero(node.child2().index()))
- flags &= ~NodeNeedsNegZero;
- flags &= ~NodeUsedAsOther;
-
- if (mode != SpeculateInteger)
- flags |= NodeUsedAsNumber;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithSub: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
-
- AddSpeculationMode mode = DontSpeculateInteger;
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
+ if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
}
-
- if (isNotZero(node.child1().index()) || isNotZero(node.child2().index()))
- flags &= ~NodeNeedsNegZero;
- flags &= ~NodeUsedAsOther;
-
- if (mode != SpeculateInteger)
- flags |= NodeUsedAsNumber;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithNegate:
- if (m_graph[node.child1()].prediction()) {
+ if (node->child1()->prediction()) {
if (m_graph.negateShouldSpeculateInteger(node))
changed |= mergePrediction(SpecInt32);
else
- changed |= mergePrediction(speculatedDoubleTypeForPrediction(m_graph[node.child1()].prediction()));
+ changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
}
-
- flags &= ~NodeUsedAsOther;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
break;
case ArithMin:
case ArithMax: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
- && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
+ && nodeCanSpeculateInteger(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
}
-
- flags |= NodeUsedAsNumber;
- flags &= ~NodeUsedAsOther;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithMul: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
if (m_graph.mulShouldSpeculateInteger(node))
@@ -413,90 +287,49 @@ private:
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
}
-
- // As soon as a multiply happens, we can easily end up in the part
- // of the double domain where the point at which you do truncation
- // can change the outcome. So, ArithMul always forces its inputs to
- // check for overflow. Additionally, it will have to check for overflow
- // itself unless we can prove that there is no way for the values
- // produced to cause double rounding.
-
- if (!isWithinPowerOfTwo(node.child1().index(), 22)
- && !isWithinPowerOfTwo(node.child2().index(), 22))
- flags |= NodeUsedAsNumber;
-
- changed |= node.mergeFlags(flags);
-
- flags |= NodeUsedAsNumber | NodeNeedsNegZero;
- flags &= ~NodeUsedAsOther;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithDiv: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
- && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
+ && nodeCanSpeculateInteger(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(SpecDouble);
}
-
- // As soon as a multiply happens, we can easily end up in the part
- // of the double domain where the point at which you do truncation
- // can change the outcome. So, ArithDiv always checks for overflow
- // no matter what, and always forces its inputs to check as well.
-
- flags |= NodeUsedAsNumber | NodeNeedsNegZero;
- flags &= ~NodeUsedAsOther;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithMod: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
if (left && right) {
- if (Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child2()])
- && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
+ && nodeCanSpeculateInteger(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(SpecDouble);
}
-
- flags |= NodeUsedAsNumber | NodeNeedsNegZero;
- flags &= ~NodeUsedAsOther;
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
- changed |= m_graph[node.child2()].mergeFlags(flags);
break;
}
case ArithSqrt: {
changed |= setPrediction(SpecDouble);
- flags |= NodeUsedAsNumber | NodeNeedsNegZero;
- flags &= ~NodeUsedAsOther;
- changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
case ArithAbs: {
- SpeculatedType child = m_graph[node.child1()].prediction();
+ SpeculatedType child = node->child1()->prediction();
if (isInt32SpeculationForArithmetic(child)
- && nodeCanSpeculateInteger(node.arithNodeFlags()))
+ && nodeCanSpeculateInteger(node->arithNodeFlags()))
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
-
- changed |= m_graph[node.child1()].mergeFlags(flags);
break;
}
@@ -506,7 +339,9 @@ private:
case CompareGreater:
case CompareGreaterEq:
case CompareEq:
+ case CompareEqConstant:
case CompareStrictEq:
+ case CompareStrictEqConstant:
case InstanceOf:
case IsUndefined:
case IsBoolean:
@@ -515,36 +350,20 @@ private:
case IsObject:
case IsFunction: {
changed |= setPrediction(SpecBoolean);
- changed |= mergeDefaultFlags(node);
break;
}
-
- case GetById: {
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultFlags(node);
+
+ case TypeOf: {
+ changed |= setPrediction(SpecString);
break;
}
-
- case GetByIdFlush:
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultFlags(node);
- break;
-
+
case GetByVal: {
- if (m_graph[node.child1()].shouldSpeculateFloat32Array()
- || m_graph[node.child1()].shouldSpeculateFloat64Array())
+ if (node->child1()->shouldSpeculateFloat32Array()
+ || node->child1()->shouldSpeculateFloat64Array())
changed |= mergePrediction(SpecDouble);
else
- changed |= mergePrediction(node.getHeapPrediction());
-
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
- break;
- }
-
- case GetMyArgumentByValSafe: {
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
+ changed |= mergePrediction(node->getHeapPrediction());
break;
}
@@ -559,63 +378,24 @@ private:
case AllocatePropertyStorage:
case ReallocatePropertyStorage: {
changed |= setPrediction(SpecOther);
- changed |= mergeDefaultFlags(node);
break;
}
- case GetByOffset: {
- changed |= mergePrediction(node.getHeapPrediction());
- changed |= mergeDefaultFlags(node);
- break;
- }
-
- case Call:
- case Construct: {
- changed |= mergePrediction(node.getHeapPrediction());
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- ++childIdx) {
- Edge edge = m_graph.m_varArgChildren[childIdx];
- changed |= m_graph[edge].mergeFlags(NodeUsedAsValue);
- }
- break;
- }
-
case ConvertThis: {
- SpeculatedType prediction = m_graph[node.child1()].prediction();
+ SpeculatedType prediction = node->child1()->prediction();
if (prediction) {
- if (prediction & ~SpecObjectMask) {
- prediction &= SpecObjectMask;
+ if (prediction & ~SpecObject) {
+ prediction &= SpecObject;
prediction = mergeSpeculations(prediction, SpecObjectOther);
}
changed |= mergePrediction(prediction);
}
- changed |= mergeDefaultFlags(node);
break;
}
- case GetGlobalVar: {
- changed |= mergePrediction(node.getHeapPrediction());
- break;
- }
-
- case PutGlobalVar:
- case PutGlobalVarCheck: {
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- break;
- }
-
- case GetScopedVar:
- case Resolve:
- case ResolveBase:
- case ResolveBaseStrictPut:
- case ResolveGlobal: {
- SpeculatedType prediction = node.getHeapPrediction();
- changed |= mergePrediction(prediction);
- break;
- }
-
- case GetScope: {
+ case GetMyScope:
+ case SkipTopScope:
+ case SkipScope: {
changed |= setPrediction(SpecCellOther);
break;
}
@@ -628,88 +408,60 @@ private:
case CreateThis:
case NewObject: {
changed |= setPrediction(SpecFinalObject);
- changed |= mergeDefaultFlags(node);
- break;
- }
-
- case NewArray: {
- changed |= setPrediction(SpecArray);
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- ++childIdx) {
- Edge edge = m_graph.m_varArgChildren[childIdx];
- changed |= m_graph[edge].mergeFlags(NodeUsedAsValue);
- }
- break;
- }
-
- case NewArrayWithSize: {
- changed |= setPrediction(SpecArray);
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue | NodeUsedAsInt);
break;
}
+ case NewArray:
+ case NewArrayWithSize:
case NewArrayBuffer: {
changed |= setPrediction(SpecArray);
break;
}
- case NewRegexp: {
+ case NewRegexp:
+ case CreateActivation: {
changed |= setPrediction(SpecObjectOther);
break;
}
- case StringCharAt: {
+ case StringFromCharCode: {
changed |= setPrediction(SpecString);
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
+ changed |= node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
break;
}
-
- case StrCat: {
+ case StringCharAt:
+ case ToString:
+ case MakeRope: {
changed |= setPrediction(SpecString);
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- ++childIdx)
- changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsNumber | NodeUsedAsOther);
break;
}
case ToPrimitive: {
- SpeculatedType child = m_graph[node.child1()].prediction();
- if (child) {
- if (isObjectSpeculation(child)) {
- // I'd love to fold this case into the case below, but I can't, because
- // removing SpecObjectMask from something that only has an object
- // prediction and nothing else means we have an ill-formed SpeculatedType
- // (strong predict-none). This should be killed once we remove all traces
- // of static (aka weak) predictions.
- changed |= mergePrediction(SpecString);
- } else if (child & SpecObjectMask) {
- // Objects get turned into strings. So if the input has hints of objectness,
- // the output will have hinsts of stringiness.
- changed |= mergePrediction(
- mergeSpeculations(child & ~SpecObjectMask, SpecString));
- } else
- changed |= mergePrediction(child);
- }
- changed |= m_graph[node.child1()].mergeFlags(flags);
+ SpeculatedType child = node->child1()->prediction();
+ if (child)
+ changed |= mergePrediction(resultOfToPrimitive(child));
break;
}
- case CreateActivation: {
- changed |= setPrediction(SpecObjectOther);
+ case NewStringObject: {
+ changed |= setPrediction(SpecStringObject);
break;
}
case CreateArguments: {
- // At this stage we don't try to predict whether the arguments are ours or
- // someone else's. We could, but we don't, yet.
changed |= setPrediction(SpecArguments);
break;
}
- case NewFunction:
+ case NewFunction: {
+ SpeculatedType child = node->child1()->prediction();
+ if (child & SpecEmpty)
+ changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
+ else
+ changed |= mergePrediction(child);
+ break;
+ }
+
case NewFunctionNoCheck:
case NewFunctionExpression: {
changed |= setPrediction(SpecFunction);
@@ -719,6 +471,7 @@ private:
case PutByValAlias:
case GetArrayLength:
case Int32ToDouble:
+ case ForwardInt32ToDouble:
case DoubleAsInt32:
case GetLocalUnlinked:
case GetMyArgumentsLength:
@@ -728,45 +481,40 @@ private:
case CheckArray:
case Arrayify:
case ArrayifyToStructure:
- case Identity: {
+ case MovHint:
+ case MovHintAndCheck:
+ case ZombieHint: {
// This node should never be visible at this stage of compilation. It is
// inserted by fixup(), which follows this phase.
CRASH();
break;
}
- case PutByVal:
- changed |= m_graph[m_graph.varArgChild(node, 0)].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[m_graph.varArgChild(node, 1)].mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt);
- changed |= m_graph[m_graph.varArgChild(node, 2)].mergeFlags(NodeUsedAsValue);
- break;
-
- case PutScopedVar:
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
- break;
-
- case Return:
- case Throw:
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ case Phi:
+ // Phis should not be visible here since we're iterating the all-but-Phi's
+ // part of basic blocks.
+ CRASH();
break;
- case PutById:
- case PutByIdDirect:
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
+ case GetScope:
+ changed |= setPrediction(SpecCellOther);
break;
- case PutByOffset:
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
- break;
-
- case Phi:
+ case Identity:
+ changed |= mergePrediction(node->child1()->prediction());
break;
#ifndef NDEBUG
// These get ignored because they don't return anything.
+ case PutByVal:
+ case PutScopedVar:
+ case Return:
+ case Throw:
+ case PutById:
+ case PutByIdDirect:
+ case PutByOffset:
+ case SetCallee:
+ case SetMyScope:
case DFG::Jump:
case Branch:
case Breakpoint:
@@ -775,6 +523,7 @@ private:
case ForceOSRExit:
case SetArgument:
case CheckStructure:
+ case CheckExecutable:
case ForwardCheckStructure:
case StructureTransitionWatchpoint:
case ForwardStructureTransitionWatchpoint:
@@ -782,18 +531,22 @@ private:
case PutStructure:
case TearOffActivation:
case TearOffArguments:
- case CheckNumber:
case CheckArgumentsNotCreated:
case GlobalVarWatchpoint:
case GarbageValue:
- case InheritorIDWatchpoint:
- changed |= mergeDefaultFlags(node);
+ case AllocationProfileWatchpoint:
+ case Phantom:
+ case PutGlobalVar:
+ case PutGlobalVarCheck:
+ case CheckWatchdogTimer:
break;
// These gets ignored because it doesn't do anything.
- case Phantom:
case InlineStart:
case Nop:
+ case CountExecution:
+ case PhantomLocal:
+ case Flush:
break;
case LastNodeType:
@@ -801,49 +554,32 @@ private:
break;
#else
default:
- changed |= mergeDefaultFlags(node);
break;
#endif
}
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("%s\n", speculationToString(m_graph[m_compileIndex].prediction()));
+ dataLog(SpeculationDump(node->prediction()), "\n");
#endif
m_changed |= changed;
}
- bool mergeDefaultFlags(Node& node)
- {
- bool changed = false;
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- childIdx++) {
- if (!!m_graph.m_varArgChildren[childIdx])
- changed |= m_graph[m_graph.m_varArgChildren[childIdx]].mergeFlags(NodeUsedAsValue);
- }
- } else {
- if (!node.child1())
- return changed;
- changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
- if (!node.child2())
- return changed;
- changed |= m_graph[node.child2()].mergeFlags(NodeUsedAsValue);
- if (!node.child3())
- return changed;
- changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
- }
- return changed;
- }
-
void propagateForward()
{
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("Propagating predictions forward [%u]\n", ++m_count);
#endif
- for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex)
- propagate(m_graph[m_compileIndex]);
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(block->isReachable);
+ for (unsigned i = 0; i < block->size(); ++i) {
+ m_currentNode = block->at(i);
+ propagate(m_currentNode);
+ }
+ }
}
void propagateBackward()
@@ -851,147 +587,158 @@ private:
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("Propagating predictions backward [%u]\n", ++m_count);
#endif
- for (m_compileIndex = m_graph.size(); m_compileIndex-- > 0;)
- propagate(m_graph[m_compileIndex]);
+ for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(block->isReachable);
+ for (unsigned i = block->size(); i--;) {
+ m_currentNode = block->at(i);
+ propagate(m_currentNode);
+ }
+ }
}
- void doRoundOfDoubleVoting()
+ void doDoubleVoting(Node* node)
{
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Voting on double uses of locals [%u]\n", m_count);
-#endif
- for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
- m_graph.m_variableAccessData[i].find()->clearVotes();
- for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex) {
- Node& node = m_graph[m_compileIndex];
- switch (node.op()) {
- case ValueAdd:
- case ArithAdd:
- case ArithSub: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ switch (node->op()) {
+ case ValueAdd:
+ case ArithAdd:
+ case ArithSub: {
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
- DoubleBallot ballot;
+ DoubleBallot ballot;
- if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)
- && !m_graph.addShouldSpeculateInteger(node))
- ballot = VoteDouble;
- else
- ballot = VoteValue;
+ if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)
+ && !m_graph.addShouldSpeculateInteger(node))
+ ballot = VoteDouble;
+ else
+ ballot = VoteValue;
- m_graph.vote(node.child1(), ballot);
- m_graph.vote(node.child2(), ballot);
- break;
- }
+ m_graph.voteNode(node->child1(), ballot);
+ m_graph.voteNode(node->child2(), ballot);
+ break;
+ }
- case ArithMul: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ case ArithMul: {
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
- DoubleBallot ballot;
+ DoubleBallot ballot;
- if (isNumberSpeculation(left) && isNumberSpeculation(right)
- && !m_graph.mulShouldSpeculateInteger(node))
- ballot = VoteDouble;
- else
- ballot = VoteValue;
+ if (isNumberSpeculation(left) && isNumberSpeculation(right)
+ && !m_graph.mulShouldSpeculateInteger(node))
+ ballot = VoteDouble;
+ else
+ ballot = VoteValue;
- m_graph.vote(node.child1(), ballot);
- m_graph.vote(node.child2(), ballot);
- break;
- }
+ m_graph.voteNode(node->child1(), ballot);
+ m_graph.voteNode(node->child2(), ballot);
+ break;
+ }
- case ArithMin:
- case ArithMax:
- case ArithMod:
- case ArithDiv: {
- SpeculatedType left = m_graph[node.child1()].prediction();
- SpeculatedType right = m_graph[node.child2()].prediction();
+ case ArithMin:
+ case ArithMax:
+ case ArithMod:
+ case ArithDiv: {
+ SpeculatedType left = node->child1()->prediction();
+ SpeculatedType right = node->child2()->prediction();
- DoubleBallot ballot;
+ DoubleBallot ballot;
- if (isNumberSpeculation(left) && isNumberSpeculation(right)
- && !(Node::shouldSpeculateIntegerForArithmetic(m_graph[node.child1()], m_graph[node.child1()])
- && node.canSpeculateInteger()))
- ballot = VoteDouble;
- else
- ballot = VoteValue;
+ if (isNumberSpeculation(left) && isNumberSpeculation(right)
+ && !(Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInteger()))
+ ballot = VoteDouble;
+ else
+ ballot = VoteValue;
- m_graph.vote(node.child1(), ballot);
- m_graph.vote(node.child2(), ballot);
- break;
- }
+ m_graph.voteNode(node->child1(), ballot);
+ m_graph.voteNode(node->child2(), ballot);
+ break;
+ }
- case ArithAbs:
- DoubleBallot ballot;
- if (!(m_graph[node.child1()].shouldSpeculateIntegerForArithmetic()
- && node.canSpeculateInteger()))
- ballot = VoteDouble;
- else
- ballot = VoteValue;
+ case ArithAbs:
+ DoubleBallot ballot;
+ if (!(node->child1()->shouldSpeculateIntegerForArithmetic() && node->canSpeculateInteger()))
+ ballot = VoteDouble;
+ else
+ ballot = VoteValue;
- m_graph.vote(node.child1(), ballot);
- break;
+ m_graph.voteNode(node->child1(), ballot);
+ break;
- case ArithSqrt:
- m_graph.vote(node.child1(), VoteDouble);
- break;
+ case ArithSqrt:
+ m_graph.voteNode(node->child1(), VoteDouble);
+ break;
- case SetLocal: {
- SpeculatedType prediction = m_graph[node.child1()].prediction();
- if (isDoubleSpeculation(prediction))
- node.variableAccessData()->vote(VoteDouble);
- else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
- node.variableAccessData()->vote(VoteValue);
- break;
- }
+ case SetLocal: {
+ SpeculatedType prediction = node->child1()->prediction();
+ if (isDoubleSpeculation(prediction))
+ node->variableAccessData()->vote(VoteDouble);
+ else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
+ node->variableAccessData()->vote(VoteValue);
+ break;
+ }
- case PutByVal:
- case PutByValAlias: {
- Edge child1 = m_graph.varArgChild(node, 0);
- Edge child2 = m_graph.varArgChild(node, 1);
- Edge child3 = m_graph.varArgChild(node, 2);
- m_graph.vote(child1, VoteValue);
- m_graph.vote(child2, VoteValue);
- switch (node.arrayMode().type()) {
- case Array::Double:
- m_graph.vote(child3, VoteDouble);
- break;
- default:
- m_graph.vote(child3, VoteValue);
- break;
- }
+ case PutByVal:
+ case PutByValAlias: {
+ Edge child1 = m_graph.varArgChild(node, 0);
+ Edge child2 = m_graph.varArgChild(node, 1);
+ Edge child3 = m_graph.varArgChild(node, 2);
+ m_graph.voteNode(child1, VoteValue);
+ m_graph.voteNode(child2, VoteValue);
+ switch (node->arrayMode().type()) {
+ case Array::Double:
+ m_graph.voteNode(child3, VoteDouble);
break;
- }
-
default:
- m_graph.vote(node, VoteValue);
+ m_graph.voteNode(child3, VoteValue);
break;
}
+ break;
+ }
+
+ default:
+ m_graph.voteChildren(node, VoteValue);
+ break;
+ }
+ }
+
+ void doRoundOfDoubleVoting()
+ {
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLogF("Voting on double uses of locals [%u]\n", m_count);
+#endif
+ for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
+ m_graph.m_variableAccessData[i].find()->clearVotes();
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(block->isReachable);
+ for (unsigned i = 0; i < block->size(); ++i) {
+ m_currentNode = block->at(i);
+ doDoubleVoting(m_currentNode);
+ }
}
for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
if (!variableAccessData->isRoot())
continue;
- if (operandIsArgument(variableAccessData->local())
- || variableAccessData->isCaptured())
- continue;
m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
}
for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
- m_changed |= m_graph.m_argumentPositions[i].mergeArgumentAwareness();
+ m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
if (!variableAccessData->isRoot())
continue;
- if (operandIsArgument(variableAccessData->local())
- || variableAccessData->isCaptured())
- continue;
m_changed |= variableAccessData->makePredictionForDoubleFormat();
}
}
- NodeIndex m_compileIndex;
+ Node* m_currentNode;
bool m_changed;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h
index ae025cdeb..29fe8455e 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h
@@ -30,6 +30,8 @@
#if ENABLE(DFG_JIT)
+#include "SpeculatedType.h"
+
namespace JSC { namespace DFG {
class Graph;
@@ -45,6 +47,9 @@ class Graph;
bool performPredictionPropagation(Graph&);
+// Helper used for FixupPhase for computing the predicted type of a ToPrimitive.
+SpeculatedType resultOfToPrimitive(SpeculatedType type);
+
} } // namespace JSC::DFG::Phase
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGRegisterBank.h b/Source/JavaScriptCore/dfg/DFGRegisterBank.h
index 3dbd1fe91..4d1be406a 100644
--- a/Source/JavaScriptCore/dfg/DFGRegisterBank.h
+++ b/Source/JavaScriptCore/dfg/DFGRegisterBank.h
@@ -28,7 +28,7 @@
#if ENABLE(DFG_JIT)
-#include <dfg/DFGCommon.h>
+#include "DFGCommon.h"
namespace JSC { namespace DFG {
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index bba3a5b43..1063f3c50 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -37,6 +37,7 @@
#include "Operations.h"
#include "PolymorphicPutByIdList.h"
#include "RepatchBuffer.h"
+#include "StructureRareDataInlines.h"
#include <wtf/StringPrintStream.h>
namespace JSC { namespace DFG {
@@ -171,7 +172,7 @@ static void linkRestoreScratch(LinkBuffer& patchBuffer, bool needToRestoreScratc
static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stubInfo, StructureChain* chain, size_t count, PropertyOffset offset, Structure* structure, CodeLocationLabel successLabel, CodeLocationLabel slowCaseLabel, RefPtr<JITStubRoutine>& stubRoutine)
{
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
MacroAssembler stubJit;
@@ -230,7 +231,7 @@ static void generateProtoChainAccessStub(ExecState* exec, StructureStubInfo& stu
emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
- LinkBuffer patchBuffer(*globalData, &stubJit, exec->codeBlock());
+ LinkBuffer patchBuffer(*vm, &stubJit, exec->codeBlock());
linkRestoreScratch(patchBuffer, needToRestoreScratch, success, fail, failureCases, successLabel, slowCaseLabel);
@@ -246,7 +247,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
// like the interpreter does, then add a check for recursion.
CodeBlock* codeBlock = exec->codeBlock();
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
if (isJSArray(baseValue) && propertyName == exec->propertyNames().length) {
GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.dfg.baseGPR);
@@ -291,7 +292,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCases);
- LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock);
+ LinkBuffer patchBuffer(*vm, &stubJit, codeBlock);
linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCases);
@@ -323,13 +324,13 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
// Optimize self access.
if (slot.slotBase() == baseValue) {
if ((slot.cachedPropertyType() != PropertySlot::Value)
- || !MacroAssembler::isCompactPtrAlignedAddressOffset(offsetRelativeToPatchedStorage(slot.cachedOffset()))) {
+ || !MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset()))) {
dfgRepatchCall(codeBlock, stubInfo.callReturnLocation, operationGetByIdBuildList);
return true;
}
dfgRepatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdBuildList, true);
- stubInfo.initGetByIdSelf(*globalData, codeBlock->ownerExecutable(), structure);
+ stubInfo.initGetByIdSelf(*vm, codeBlock->ownerExecutable(), structure);
return true;
}
@@ -355,7 +356,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
replaceWithJump(repatchBuffer, stubInfo, stubInfo.stubRoutine->code().code());
repatchBuffer.relink(stubInfo.callReturnLocation, operationGetByIdProtoBuildList);
- stubInfo.initGetByIdChain(*globalData, codeBlock->ownerExecutable(), structure, prototypeChain, count, true);
+ stubInfo.initGetByIdChain(*vm, codeBlock->ownerExecutable(), structure, prototypeChain, count, true);
return true;
}
@@ -385,7 +386,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
CodeBlock* codeBlock = exec->codeBlock();
JSCell* baseCell = baseValue.asCell();
Structure* structure = baseCell->structure();
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
ASSERT(slot.slotBase().isObject());
@@ -399,7 +400,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
listIndex = 0;
} else if (stubInfo.accessType == access_get_by_id_self) {
ASSERT(!stubInfo.stubRoutine);
- polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), JITStubRoutine::createSelfManagedRoutine(stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
+ polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock->ownerExecutable(), JITStubRoutine::createSelfManagedRoutine(stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
stubInfo.initGetByIdSelfList(polymorphicStructureList, 1);
listIndex = 1;
} else {
@@ -417,7 +418,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
GPRReg resultGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR);
GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR();
- CCallHelpers stubJit(globalData, codeBlock);
+ CCallHelpers stubJit(vm, codeBlock);
MacroAssembler::Jump wrongStruct = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(structure));
@@ -506,7 +507,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
isDirect = true;
}
- LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock);
+ LinkBuffer patchBuffer(*vm, &stubJit, codeBlock);
CodeLocationLabel lastProtoBegin;
if (listIndex)
@@ -529,12 +530,12 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
("DFG GetById polymorphic list access for %s, return point %p",
toCString(*exec->codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
stubInfo.patch.dfg.deltaCallToDone).executableAddress())),
- *globalData,
+ *vm,
codeBlock->ownerExecutable(),
slot.cachedPropertyType() == PropertySlot::Getter
|| slot.cachedPropertyType() == PropertySlot::Custom);
- polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
+ polymorphicStructureList->list[listIndex].set(*vm, codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
RepatchBuffer repatchBuffer(codeBlock);
repatchBuffer.relink(
@@ -576,14 +577,14 @@ static bool tryBuildGetByIDProtoList(ExecState* exec, JSValue baseValue, const I
Structure* structure = baseValue.asCell()->structure();
StructureChain* prototypeChain = structure->prototypeChain(exec);
CodeBlock* codeBlock = exec->codeBlock();
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
PolymorphicAccessStructureList* polymorphicStructureList;
int listIndex = 1;
if (stubInfo.accessType == access_get_by_id_chain) {
ASSERT(!!stubInfo.stubRoutine);
- polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get(), true);
+ polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get(), true);
stubInfo.stubRoutine.clear();
stubInfo.initGetByIdProtoList(polymorphicStructureList, 1);
} else {
@@ -602,7 +603,7 @@ static bool tryBuildGetByIDProtoList(ExecState* exec, JSValue baseValue, const I
generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), lastProtoBegin, stubRoutine);
- polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure, true);
+ polymorphicStructureList->list[listIndex].set(*vm, codeBlock->ownerExecutable(), stubRoutine, structure, true);
RepatchBuffer repatchBuffer(codeBlock);
replaceWithJump(repatchBuffer, stubInfo, stubRoutine->code().code());
@@ -656,7 +657,7 @@ static void emitPutReplaceStub(
CodeLocationLabel failureLabel,
RefPtr<JITStubRoutine>& stubRoutine)
{
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.dfg.baseGPR);
#if USE(JSVALUE32_64)
GPRReg valueTagGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueTagGPR);
@@ -664,7 +665,7 @@ static void emitPutReplaceStub(
GPRReg valueGPR = static_cast<GPRReg>(stubInfo.patch.dfg.valueGPR);
GPRReg scratchGPR = RegisterSet(stubInfo.patch.dfg.usedRegisters).getFreeGPR();
bool needToRestoreScratch = false;
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
GPRReg scratchGPR2;
const bool writeBarrierNeeded = true;
#else
@@ -688,7 +689,7 @@ static void emitPutReplaceStub(
MacroAssembler::Address(baseGPR, JSCell::structureOffset()),
MacroAssembler::TrustedImmPtr(structure));
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
#if USE(JSVALUE64)
scratchGPR2 = SpeculativeJIT::selectScratchGPR(baseGPR, valueGPR, scratchGPR);
#else
@@ -732,7 +733,7 @@ static void emitPutReplaceStub(
failure = badStructure;
}
- LinkBuffer patchBuffer(*globalData, &stubJit, exec->codeBlock());
+ LinkBuffer patchBuffer(*vm, &stubJit, exec->codeBlock());
patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone));
patchBuffer.link(failure, failureLabel);
@@ -756,7 +757,7 @@ static void emitPutTransitionStub(
CodeLocationLabel failureLabel,
RefPtr<JITStubRoutine>& stubRoutine)
{
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
GPRReg baseGPR = static_cast<GPRReg>(stubInfo.patch.dfg.baseGPR);
#if USE(JSVALUE32_64)
@@ -771,7 +772,7 @@ static void emitPutTransitionStub(
#endif
allocator.lock(valueGPR);
- CCallHelpers stubJit(globalData);
+ CCallHelpers stubJit(vm);
GPRReg scratchGPR1 = allocator.allocateScratchGPR();
ASSERT(scratchGPR1 != baseGPR);
@@ -779,7 +780,7 @@ static void emitPutTransitionStub(
bool needSecondScratch = false;
bool needThirdScratch = false;
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
needSecondScratch = true;
#endif
if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()
@@ -826,7 +827,7 @@ static void emitPutTransitionStub(
}
}
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
ASSERT(needSecondScratch);
ASSERT(scratchGPR2 != InvalidGPRReg);
// Must always emit this write barrier as the structure transition itself requires it
@@ -839,7 +840,7 @@ static void emitPutTransitionStub(
if (structure->outOfLineCapacity() != oldStructure->outOfLineCapacity()) {
size_t newSize = structure->outOfLineCapacity() * sizeof(JSValue);
- CopiedAllocator* copiedAllocator = &globalData->heap.storageAllocator();
+ CopiedAllocator* copiedAllocator = &vm->heap.storageAllocator();
if (!oldStructure->outOfLineCapacity()) {
stubJit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR1);
@@ -911,7 +912,7 @@ static void emitPutTransitionStub(
slowPath.link(&stubJit);
allocator.restoreReusedRegistersByPopping(stubJit);
- ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(allocator.desiredScratchBufferSize());
+ ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(allocator.desiredScratchBufferSize());
allocator.preserveUsedRegistersToScratchBuffer(stubJit, scratchBuffer, scratchGPR1);
#if USE(JSVALUE64)
stubJit.setupArgumentsWithExecState(baseGPR, MacroAssembler::TrustedImmPtr(structure), MacroAssembler::TrustedImm32(slot.cachedOffset()), valueGPR);
@@ -923,7 +924,7 @@ static void emitPutTransitionStub(
successInSlowPath = stubJit.jump();
}
- LinkBuffer patchBuffer(*globalData, &stubJit, exec->codeBlock());
+ LinkBuffer patchBuffer(*vm, &stubJit, exec->codeBlock());
patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone));
if (allocator.didReuseRegisters())
patchBuffer.link(failure, failureLabel);
@@ -943,7 +944,7 @@ static void emitPutTransitionStub(
oldStructure, structure,
toCString(*exec->codeBlock()).data(), stubInfo.callReturnLocation.labelAtOffset(
stubInfo.patch.dfg.deltaCallToDone).executableAddress())),
- *globalData,
+ *vm,
exec->codeBlock()->ownerExecutable(),
structure->outOfLineCapacity() != oldStructure->outOfLineCapacity(),
structure);
@@ -952,7 +953,7 @@ static void emitPutTransitionStub(
static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier& ident, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
{
CodeBlock* codeBlock = exec->codeBlock();
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
if (!baseValue.isCell())
return false;
@@ -1001,13 +1002,13 @@ static bool tryCachePutByID(ExecState* exec, JSValue baseValue, const Identifier
CodeLocationLabel(stubInfo.stubRoutine->code().code()));
repatchBuffer.relink(stubInfo.callReturnLocation, appropriateListBuildingPutByIdFunction(slot, putKind));
- stubInfo.initPutByIdTransition(*globalData, codeBlock->ownerExecutable(), oldStructure, structure, prototypeChain, putKind == Direct);
+ stubInfo.initPutByIdTransition(*vm, codeBlock->ownerExecutable(), oldStructure, structure, prototypeChain, putKind == Direct);
return true;
}
dfgRepatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), appropriateListBuildingPutByIdFunction(slot, putKind), false);
- stubInfo.initPutByIdReplace(*globalData, codeBlock->ownerExecutable(), structure);
+ stubInfo.initPutByIdReplace(*vm, codeBlock->ownerExecutable(), structure);
return true;
}
@@ -1024,7 +1025,7 @@ void dfgRepatchPutByID(ExecState* exec, JSValue baseValue, const Identifier& pro
static bool tryBuildPutByIdList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind)
{
CodeBlock* codeBlock = exec->codeBlock();
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
if (!baseValue.isCell())
return false;
@@ -1076,7 +1077,7 @@ static bool tryBuildPutByIdList(ExecState* exec, JSValue baseValue, const Identi
list->addAccess(
PutByIdAccess::transition(
- *globalData, codeBlock->ownerExecutable(),
+ *vm, codeBlock->ownerExecutable(),
oldStructure, structure, prototypeChain,
stubRoutine));
} else {
@@ -1091,7 +1092,7 @@ static bool tryBuildPutByIdList(ExecState* exec, JSValue baseValue, const Identi
list->addAccess(
PutByIdAccess::replace(
- *globalData, codeBlock->ownerExecutable(),
+ *vm, codeBlock->ownerExecutable(),
structure, stubRoutine));
}
@@ -1114,14 +1115,14 @@ void dfgBuildPutByIdList(ExecState* exec, JSValue baseValue, const Identifier& p
dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriateGenericPutByIdFunction(slot, putKind));
}
-static void linkSlowFor(RepatchBuffer& repatchBuffer, JSGlobalData* globalData, CallLinkInfo& callLinkInfo, CodeSpecializationKind kind)
+static void linkSlowFor(RepatchBuffer& repatchBuffer, VM* vm, CallLinkInfo& callLinkInfo, CodeSpecializationKind kind)
{
if (kind == CodeForCall) {
- repatchBuffer.relink(callLinkInfo.callReturnLocation, globalData->getCTIStub(virtualCallThunkGenerator).code());
+ repatchBuffer.relink(callLinkInfo.callReturnLocation, vm->getCTIStub(virtualCallThunkGenerator).code());
return;
}
ASSERT(kind == CodeForConstruct);
- repatchBuffer.relink(callLinkInfo.callReturnLocation, globalData->getCTIStub(virtualConstructThunkGenerator).code());
+ repatchBuffer.relink(callLinkInfo.callReturnLocation, vm->getCTIStub(virtualConstructThunkGenerator).code());
}
void dfgLinkFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr, CodeSpecializationKind kind)
@@ -1129,35 +1130,35 @@ void dfgLinkFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCo
ASSERT(!callLinkInfo.stub);
CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
- JSGlobalData* globalData = callerCodeBlock->globalData();
+ VM* vm = callerCodeBlock->vm();
RepatchBuffer repatchBuffer(callerCodeBlock);
ASSERT(!callLinkInfo.isLinked());
- callLinkInfo.callee.set(exec->callerFrame()->globalData(), callLinkInfo.hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
- callLinkInfo.lastSeenCallee.set(exec->callerFrame()->globalData(), callerCodeBlock->ownerExecutable(), callee);
+ callLinkInfo.callee.set(exec->callerFrame()->vm(), callLinkInfo.hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
+ callLinkInfo.lastSeenCallee.set(exec->callerFrame()->vm(), callerCodeBlock->ownerExecutable(), callee);
repatchBuffer.relink(callLinkInfo.hotPathOther, codePtr);
if (calleeCodeBlock)
calleeCodeBlock->linkIncomingCall(&callLinkInfo);
if (kind == CodeForCall) {
- repatchBuffer.relink(callLinkInfo.callReturnLocation, globalData->getCTIStub(linkClosureCallThunkGenerator).code());
+ repatchBuffer.relink(callLinkInfo.callReturnLocation, vm->getCTIStub(linkClosureCallThunkGenerator).code());
return;
}
ASSERT(kind == CodeForConstruct);
- linkSlowFor(repatchBuffer, globalData, callLinkInfo, CodeForConstruct);
+ linkSlowFor(repatchBuffer, vm, callLinkInfo, CodeForConstruct);
}
void dfgLinkSlowFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeSpecializationKind kind)
{
CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
- JSGlobalData* globalData = callerCodeBlock->globalData();
+ VM* vm = callerCodeBlock->vm();
RepatchBuffer repatchBuffer(callerCodeBlock);
- linkSlowFor(repatchBuffer, globalData, callLinkInfo, kind);
+ linkSlowFor(repatchBuffer, vm, callLinkInfo, kind);
}
void dfgLinkClosureCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, Structure* structure, ExecutableBase* executable, MacroAssemblerCodePtr codePtr)
@@ -1165,11 +1166,11 @@ void dfgLinkClosureCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock*
ASSERT(!callLinkInfo.stub);
CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
- JSGlobalData* globalData = callerCodeBlock->globalData();
+ VM* vm = callerCodeBlock->vm();
GPRReg calleeGPR = static_cast<GPRReg>(callLinkInfo.calleeGPR);
- CCallHelpers stubJit(globalData, callerCodeBlock);
+ CCallHelpers stubJit(vm, callerCodeBlock);
CCallHelpers::JumpList slowPath;
@@ -1222,26 +1223,26 @@ void dfgLinkClosureCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock*
stubJit.restoreReturnAddressBeforeReturn(GPRInfo::nonArgGPR2);
JITCompiler::Jump slow = stubJit.jump();
- LinkBuffer patchBuffer(*globalData, &stubJit, callerCodeBlock);
+ LinkBuffer patchBuffer(*vm, &stubJit, callerCodeBlock);
patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
patchBuffer.link(done, callLinkInfo.callReturnLocation.labelAtOffset(0));
- patchBuffer.link(slow, CodeLocationLabel(globalData->getCTIStub(virtualCallThunkGenerator).code()));
+ patchBuffer.link(slow, CodeLocationLabel(vm->getCTIStub(virtualCallThunkGenerator).code()));
RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
FINALIZE_DFG_CODE(
patchBuffer,
("DFG closure call stub for %s, return point %p, target %p (%s)",
toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation.labelAtOffset(0).executableAddress(),
- codePtr.executableAddress(), toCString(*calleeCodeBlock).data())),
- *globalData, callerCodeBlock->ownerExecutable(), structure, executable, callLinkInfo.codeOrigin));
+ codePtr.executableAddress(), toCString(pointerDump(calleeCodeBlock)).data())),
+ *vm, callerCodeBlock->ownerExecutable(), structure, executable, callLinkInfo.codeOrigin));
RepatchBuffer repatchBuffer(callerCodeBlock);
repatchBuffer.replaceWithJump(
RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin),
CodeLocationLabel(stubRoutine->code().code()));
- linkSlowFor(repatchBuffer, globalData, callLinkInfo, CodeForCall);
+ linkSlowFor(repatchBuffer, vm, callLinkInfo, CodeForCall);
callLinkInfo.stub = stubRoutine.release();
@@ -1258,9 +1259,9 @@ void dfgResetGetByID(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
MacroAssembler::Address(
static_cast<MacroAssembler::RegisterID>(stubInfo.patch.dfg.baseGPR),
JSCell::structureOffset()),
- reinterpret_cast<void*>(-1));
+ reinterpret_cast<void*>(unusedPointer));
}
- repatchBuffer.repatch(structureLabel, reinterpret_cast<void*>(-1));
+ repatchBuffer.repatch(structureLabel, reinterpret_cast<void*>(unusedPointer));
#if USE(JSVALUE64)
repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabelCompactAtOffset(stubInfo.patch.dfg.deltaCallToLoadOrStore), 0);
#else
@@ -1292,9 +1293,9 @@ void dfgResetPutByID(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
MacroAssembler::Address(
static_cast<MacroAssembler::RegisterID>(stubInfo.patch.dfg.baseGPR),
JSCell::structureOffset()),
- reinterpret_cast<void*>(-1));
+ reinterpret_cast<void*>(unusedPointer));
}
- repatchBuffer.repatch(structureLabel, reinterpret_cast<void*>(-1));
+ repatchBuffer.repatch(structureLabel, reinterpret_cast<void*>(unusedPointer));
#if USE(JSVALUE64)
repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.patch.dfg.deltaCallToLoadOrStore), 0);
#else
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.h b/Source/JavaScriptCore/dfg/DFGRepatch.h
index 97d26aab2..dfce0525e 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.h
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.h
@@ -59,8 +59,8 @@ struct StructureStubInfo;
namespace DFG {
-inline NO_RETURN_DUE_TO_ASSERT void dfgResetGetByID(RepatchBuffer&, StructureStubInfo&) { ASSERT_NOT_REACHED(); }
-inline NO_RETURN_DUE_TO_ASSERT void dfgResetPutByID(RepatchBuffer&, StructureStubInfo&) { ASSERT_NOT_REACHED(); }
+inline NO_RETURN void dfgResetGetByID(RepatchBuffer&, StructureStubInfo&) { RELEASE_ASSERT_NOT_REACHED(); }
+inline NO_RETURN void dfgResetPutByID(RepatchBuffer&, StructureStubInfo&) { RELEASE_ASSERT_NOT_REACHED(); }
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGScoreBoard.h b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
index 9b509fe2a..8701fc740 100644
--- a/Source/JavaScriptCore/dfg/DFGScoreBoard.h
+++ b/Source/JavaScriptCore/dfg/DFGScoreBoard.h
@@ -43,9 +43,8 @@ namespace JSC { namespace DFG {
// another node.
class ScoreBoard {
public:
- ScoreBoard(Graph& graph, const BitVector& usedVars)
- : m_graph(graph)
- , m_highWatermark(0)
+ ScoreBoard(const BitVector& usedVars)
+ : m_highWatermark(0)
{
m_used.fill(0, usedVars.size());
m_free.reserveCapacity(usedVars.size());
@@ -102,16 +101,15 @@ public:
// Increment the usecount for the VirtualRegsiter associated with 'child',
// if it reaches the node's refcount, free the VirtualRegsiter.
- void use(NodeIndex child)
+ void use(Node* child)
{
- if (child == NoNode)
+ if (!child)
return;
// Find the virtual register number for this child, increment its use count.
- Node& node = m_graph[child];
- uint32_t index = node.virtualRegister();
+ uint32_t index = child->virtualRegister();
ASSERT(m_used[index] != max());
- if (node.refCount() == ++m_used[index]) {
+ if (child->refCount() == ++m_used[index]) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" Freeing virtual register %u.", index);
#endif
@@ -122,20 +120,20 @@ public:
m_free.append(index);
} else {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Virtual register %u is at %u/%u uses.", index, m_used[index], node.refCount());
+ dataLogF(" Virtual register %u is at %u/%u uses.", index, m_used[index], child->refCount());
#endif
}
}
void use(Edge child)
{
- use(child.indexUnchecked());
+ use(child.node());
}
void useIfHasResult(Edge child)
{
if (!child)
return;
- if (!m_graph[child].hasResult())
+ if (!child->hasResult())
return;
use(child);
}
@@ -175,9 +173,6 @@ public:
private:
static uint32_t max() { return std::numeric_limits<uint32_t>::max(); }
- // The graph, so we can get refCounts for nodes, to determine when values are dead.
- Graph& m_graph;
-
// The size of the span of virtual registers that this code block will use.
unsigned m_highWatermark;
diff --git a/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h b/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h
index 706bcd61d..d32d85a0c 100644
--- a/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h
+++ b/Source/JavaScriptCore/dfg/DFGScratchRegisterAllocator.h
@@ -137,16 +137,16 @@ public:
if (scratchGPR == InvalidGPRReg && !m_lockedRegisters.getGPRByIndex(i) && !m_scratchRegisters.getGPRByIndex(i))
scratchGPR = GPRInfo::toRegister(i);
}
- ASSERT(scratchGPR != InvalidGPRReg);
+ RELEASE_ASSERT(scratchGPR != InvalidGPRReg);
for (unsigned i = FPRInfo::numberOfRegisters; i--;) {
if (m_usedRegisters.getFPRByIndex(i)) {
jit.move(MacroAssembler::TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + (count++)), scratchGPR);
jit.storeDouble(FPRInfo::toRegister(i), scratchGPR);
}
}
- ASSERT(count * sizeof(JSValue) == desiredScratchBufferSize());
+ RELEASE_ASSERT(count * sizeof(JSValue) == desiredScratchBufferSize());
- jit.move(MacroAssembler::TrustedImmPtr(&scratchBuffer->m_activeLength), scratchGPR);
+ jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratchGPR);
jit.storePtr(MacroAssembler::TrustedImmPtr(static_cast<size_t>(count * sizeof(JSValue))), scratchGPR);
}
@@ -161,9 +161,9 @@ public:
break;
}
}
- ASSERT(scratchGPR != InvalidGPRReg);
+ RELEASE_ASSERT(scratchGPR != InvalidGPRReg);
- jit.move(MacroAssembler::TrustedImmPtr(&scratchBuffer->m_activeLength), scratchGPR);
+ jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratchGPR);
jit.storePtr(MacroAssembler::TrustedImmPtr(0), scratchGPR);
// Restore double registers first.
diff --git a/Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h b/Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h
index bb04646bf..6b9df19d7 100644
--- a/Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h
+++ b/Source/JavaScriptCore/dfg/DFGSilentRegisterSavePlan.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -74,38 +74,38 @@ public:
: m_spillAction(DoNothingForSpill)
, m_fillAction(DoNothingForFill)
, m_register(-1)
- , m_nodeIndex(NoNode)
+ , m_node(0)
{
}
SilentRegisterSavePlan(
SilentSpillAction spillAction,
SilentFillAction fillAction,
- NodeIndex nodeIndex,
+ Node* node,
GPRReg gpr)
: m_spillAction(spillAction)
, m_fillAction(fillAction)
, m_register(gpr)
- , m_nodeIndex(nodeIndex)
+ , m_node(node)
{
}
SilentRegisterSavePlan(
SilentSpillAction spillAction,
SilentFillAction fillAction,
- NodeIndex nodeIndex,
+ Node* node,
FPRReg fpr)
: m_spillAction(spillAction)
, m_fillAction(fillAction)
, m_register(fpr)
- , m_nodeIndex(nodeIndex)
+ , m_node(node)
{
}
SilentSpillAction spillAction() const { return static_cast<SilentSpillAction>(m_spillAction); }
SilentFillAction fillAction() const { return static_cast<SilentFillAction>(m_fillAction); }
- NodeIndex nodeIndex() const { return m_nodeIndex; }
+ Node* node() const { return m_node; }
GPRReg gpr() const { return static_cast<GPRReg>(m_register); }
FPRReg fpr() const { return static_cast<FPRReg>(m_register); }
@@ -114,7 +114,7 @@ private:
int8_t m_spillAction;
int8_t m_fillAction;
int8_t m_register;
- NodeIndex m_nodeIndex;
+ Node* m_node;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h b/Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h
index 4acd8690a..6b723ba20 100644
--- a/Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h
+++ b/Source/JavaScriptCore/dfg/DFGSlowPathGenerator.h
@@ -42,7 +42,7 @@ class SlowPathGenerator {
WTF_MAKE_FAST_ALLOCATED;
public:
SlowPathGenerator(SpeculativeJIT* jit)
- : m_compileIndex(jit->m_compileIndex)
+ : m_currentNode(jit->m_currentNode)
{
}
virtual ~SlowPathGenerator() { }
@@ -52,7 +52,7 @@ public:
dataLogF("Generating slow path %p at offset 0x%x\n", this, jit->m_jit.debugOffset());
#endif
m_label = jit->m_jit.label();
- jit->m_compileIndex = m_compileIndex;
+ jit->m_currentNode = m_currentNode;
generateInternal(jit);
#if !ASSERT_DISABLED
jit->m_jit.breakpoint(); // make sure that the generator jumps back to somewhere
@@ -61,13 +61,13 @@ public:
MacroAssembler::Label label() const { return m_label; }
virtual MacroAssembler::Call call() const
{
- ASSERT_NOT_REACHED(); // By default slow path generators don't have a call.
+ RELEASE_ASSERT_NOT_REACHED(); // By default slow path generators don't have a call.
return MacroAssembler::Call();
}
protected:
virtual void generateInternal(SpeculativeJIT*) = 0;
MacroAssembler::Label m_label;
- NodeIndex m_compileIndex;
+ Node* m_currentNode;
};
template<typename JumpType>
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 4f2889b8f..325a876a2 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,8 +29,10 @@
#if ENABLE(DFG_JIT)
#include "Arguments.h"
+#include "DFGArrayifySlowPathGenerator.h"
#include "DFGCallArrayAllocatorSlowPathGenerator.h"
#include "DFGSlowPathGenerator.h"
+#include "JSCJSValueInlines.h"
#include "LinkBuffer.h"
namespace JSC { namespace DFG {
@@ -38,7 +40,7 @@ namespace JSC { namespace DFG {
SpeculativeJIT::SpeculativeJIT(JITCompiler& jit)
: m_compileOkay(true)
, m_jit(jit)
- , m_compileIndex(0)
+ , m_currentNode(0)
, m_indexInBlock(0)
, m_generationInfo(m_jit.codeBlock()->m_numCalleeRegisters)
, m_blockHeads(jit.graph().m_blocks.size())
@@ -54,15 +56,16 @@ SpeculativeJIT::SpeculativeJIT(JITCompiler& jit)
SpeculativeJIT::~SpeculativeJIT()
{
- WTF::deleteAllValues(m_slowPathGenerators);
}
-void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR, GPRReg storageGPR, unsigned numElements)
+void SpeculativeJIT::emitAllocateJSArray(GPRReg resultGPR, Structure* structure, GPRReg storageGPR, unsigned numElements)
{
ASSERT(hasUndecided(structure->indexingType()) || hasInt32(structure->indexingType()) || hasDouble(structure->indexingType()) || hasContiguous(structure->indexingType()));
GPRTemporary scratch(this);
+ GPRTemporary scratch2(this);
GPRReg scratchGPR = scratch.gpr();
+ GPRReg scratch2GPR = scratch2.gpr();
unsigned vectorLength = std::max(BASE_VECTOR_LEN, numElements);
@@ -71,12 +74,8 @@ void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR,
slowCases.append(
emitAllocateBasicStorage(TrustedImm32(vectorLength * sizeof(JSValue) + sizeof(IndexingHeader)), storageGPR));
m_jit.subPtr(TrustedImm32(vectorLength * sizeof(JSValue)), storageGPR);
- emitAllocateBasicJSObject<JSArray, MarkedBlock::None>(
- TrustedImmPtr(structure), resultGPR, scratchGPR,
- storageGPR, sizeof(JSArray), slowCases);
+ emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases);
- // I'm assuming that two 32-bit stores are better than a 64-bit store.
- // I have no idea if that's true. And it probably doesn't matter anyway.
m_jit.store32(TrustedImm32(numElements), MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
m_jit.store32(TrustedImm32(vectorLength), MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
@@ -104,74 +103,122 @@ void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR,
structure, numElements)));
}
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail)
+void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
{
if (!m_compileOkay)
return;
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex), jumpToFail, this, m_stream->size()));
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ m_jit.appendExitInfo(jumpToFail);
+ m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
+}
+
+void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail)
+{
+ if (!m_compileOkay)
+ return;
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ m_jit.appendExitInfo(jumpsToFail);
+ m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
+{
+ if (!m_compileOkay)
+ return;
+ backwardSpeculationCheck(kind, jsValueSource, node, jumpToFail);
+ if (m_speculationDirection == ForwardSpeculation)
+ convertLastOSRExitToForward();
}
void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ speculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail);
}
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, const MacroAssembler::JumpList& jumpsToFail)
+OSRExitJumpPlaceholder SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps();
- for (unsigned i = 0; i < jumpVector.size(); ++i)
- speculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i]);
+ if (!m_compileOkay)
+ return OSRExitJumpPlaceholder();
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ unsigned index = m_jit.codeBlock()->numberOfOSRExits();
+ m_jit.appendExitInfo();
+ m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size()));
+ return OSRExitJumpPlaceholder(index);
+}
+
+OSRExitJumpPlaceholder SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse)
+{
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ return backwardSpeculationCheck(kind, jsValueSource, nodeUse.node());
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail)
+{
+ if (!m_compileOkay)
+ return;
+ backwardSpeculationCheck(kind, jsValueSource, node, jumpsToFail);
+ if (m_speculationDirection == ForwardSpeculation)
+ convertLastOSRExitToForward();
}
void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, const MacroAssembler::JumpList& jumpsToFail)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeUse.index(), jumpsToFail);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ speculationCheck(kind, jsValueSource, nodeUse.node(), jumpsToFail);
}
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
{
if (!m_compileOkay)
return;
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
m_jit.codeBlock()->appendSpeculationRecovery(recovery);
- m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex), jumpToFail, this, m_stream->size(), m_jit.codeBlock()->numberOfSpeculationRecoveries()));
+ m_jit.appendExitInfo(jumpToFail);
+ m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(node), this, m_stream->size(), m_jit.codeBlock()->numberOfSpeculationRecoveries()));
}
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+void SpeculativeJIT::backwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail, recovery);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ backwardSpeculationCheck(kind, jsValueSource, nodeUse.node(), jumpToFail, recovery);
}
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery, SpeculationDirection direction)
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
{
- speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail, recovery);
- if (direction == ForwardSpeculation)
+ if (!m_compileOkay)
+ return;
+ backwardSpeculationCheck(kind, jsValueSource, node, jumpToFail, recovery);
+ if (m_speculationDirection == ForwardSpeculation)
convertLastOSRExitToForward();
}
-JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex)
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+{
+ speculationCheck(kind, jsValueSource, edge.node(), jumpToFail, recovery);
+}
+
+JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, Node* node)
{
if (!m_compileOkay)
return 0;
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ m_jit.appendExitInfo(JITCompiler::JumpList());
OSRExit& exit = m_jit.codeBlock()->osrExit(
- m_jit.codeBlock()->appendOSRExit(
- OSRExit(kind, jsValueSource,
- m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex),
- JITCompiler::Jump(), this, m_stream->size())));
+ m_jit.codeBlock()->appendOSRExit(OSRExit(
+ kind, jsValueSource,
+ m_jit.graph().methodOfGettingAValueProfileFor(node),
+ this, m_stream->size())));
exit.m_watchpointIndex = m_jit.codeBlock()->appendWatchpoint(
JumpReplacementWatchpoint(m_jit.watchpointLabel()));
+ if (m_speculationDirection == ForwardSpeculation)
+ convertLastOSRExitToForward();
return &m_jit.codeBlock()->watchpoint(exit.m_watchpointIndex);
}
JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind)
{
- return speculationWatchpoint(kind, JSValueSource(), NoNode);
+ return speculationWatchpoint(kind, JSValueSource(), 0);
}
void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecovery)
@@ -179,10 +226,10 @@ void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecov
if (!valueRecovery) {
// Check that either the current node is a SetLocal, or the preceding node was a
// SetLocal with the same code origin.
- if (at(m_compileIndex).op() != SetLocal) {
- Node* setLocal = &at(m_jit.graph().m_blocks[m_block]->at(m_indexInBlock - 1));
- ASSERT_UNUSED(setLocal, setLocal->op() == SetLocal);
- ASSERT_UNUSED(setLocal, setLocal->codeOrigin == at(m_compileIndex).codeOrigin);
+ if (!m_currentNode->containsMovHint()) {
+ Node* setLocal = m_jit.graph().m_blocks[m_block]->at(m_indexInBlock - 1);
+ ASSERT_UNUSED(setLocal, setLocal->containsMovHint());
+ ASSERT_UNUSED(setLocal, setLocal->codeOrigin == m_currentNode->codeOrigin);
}
// Find the next node.
@@ -196,13 +243,13 @@ void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecov
ASSERT(node->op() == Jump);
return;
}
- node = &at(m_jit.graph().m_blocks[m_block]->at(indexInBlock));
- if (node->codeOrigin != at(m_compileIndex).codeOrigin)
+ node = m_jit.graph().m_blocks[m_block]->at(indexInBlock);
+ if (node->codeOrigin != m_currentNode->codeOrigin)
break;
indexInBlock++;
}
- ASSERT(node->codeOrigin != at(m_compileIndex).codeOrigin);
+ ASSERT(node->codeOrigin != m_currentNode->codeOrigin);
OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
exit.m_codeOrigin = node->codeOrigin;
return;
@@ -210,29 +257,29 @@ void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecov
unsigned setLocalIndexInBlock = m_indexInBlock + 1;
- Node* setLocal = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock));
+ Node* setLocal = m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock);
bool hadInt32ToDouble = false;
- if (setLocal->op() == Int32ToDouble) {
- setLocal = &at(m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock));
+ if (setLocal->op() == ForwardInt32ToDouble) {
+ setLocal = m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock);
hadInt32ToDouble = true;
}
if (setLocal->op() == Flush || setLocal->op() == Phantom)
- setLocal = &at(m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock));
+ setLocal = m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock);
if (hadInt32ToDouble)
- ASSERT(at(setLocal->child1()).child1() == m_compileIndex);
+ ASSERT(setLocal->child1()->child1() == m_currentNode);
else
- ASSERT(setLocal->child1() == m_compileIndex);
- ASSERT(setLocal->op() == SetLocal);
- ASSERT(setLocal->codeOrigin == at(m_compileIndex).codeOrigin);
+ ASSERT(setLocal->child1() == m_currentNode);
+ ASSERT(setLocal->containsMovHint());
+ ASSERT(setLocal->codeOrigin == m_currentNode->codeOrigin);
- Node* nextNode = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock + 1));
- if (nextNode->op() == Jump && nextNode->codeOrigin == at(m_compileIndex).codeOrigin) {
+ Node* nextNode = m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock + 1);
+ if (nextNode->op() == Jump && nextNode->codeOrigin == m_currentNode->codeOrigin) {
// We're at an inlined return. Use a backward speculation instead.
return;
}
- ASSERT(nextNode->codeOrigin != at(m_compileIndex).codeOrigin);
+ ASSERT(nextNode->codeOrigin != m_currentNode->codeOrigin);
OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
exit.m_codeOrigin = nextNode->codeOrigin;
@@ -242,77 +289,61 @@ void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecov
new ValueRecoveryOverride(setLocal->local(), valueRecovery));
}
-JumpReplacementWatchpoint* SpeculativeJIT::forwardSpeculationWatchpoint(ExitKind kind)
-{
- JumpReplacementWatchpoint* result = speculationWatchpoint(kind);
- convertLastOSRExitToForward();
- return result;
-}
-
-JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind, SpeculationDirection direction)
+void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
{
- JumpReplacementWatchpoint* result = speculationWatchpoint(kind);
- if (direction == ForwardSpeculation)
- convertLastOSRExitToForward();
- return result;
-}
-
-void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
-{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ backwardSpeculationCheck(kind, jsValueSource, node, jumpToFail);
convertLastOSRExitToForward(valueRecovery);
}
-void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery)
+void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps();
- for (unsigned i = 0; i < jumpVector.size(); ++i)
- forwardSpeculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i], valueRecovery);
-}
-
-void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, SpeculationDirection direction)
-{
- if (direction == ForwardSpeculation)
- forwardSpeculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
- else
- speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ backwardSpeculationCheck(kind, jsValueSource, node, jumpsToFail);
+ convertLastOSRExitToForward(valueRecovery);
}
-void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex)
+void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Node* node)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLogF("SpeculativeJIT was terminated.\n");
#endif
if (!m_compileOkay)
return;
- speculationCheck(kind, jsValueRegs, nodeIndex, m_jit.jump());
+ speculationCheck(kind, jsValueRegs, node, m_jit.jump());
m_compileOkay = false;
}
void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Edge nodeUse)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.index());
+ ASSERT(m_isCheckingArgumentTypes || m_canExit);
+ terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.node());
}
-void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex, SpeculationDirection direction)
+void SpeculativeJIT::backwardTypeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
{
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpeculativeJIT was terminated.\n");
-#endif
- if (!m_compileOkay)
- return;
- speculationCheck(kind, jsValueRegs, nodeIndex, m_jit.jump(), direction);
- m_compileOkay = false;
+ ASSERT(needsTypeCheck(edge, typesPassedThrough));
+ m_state.forNode(edge).filter(typesPassedThrough);
+ backwardSpeculationCheck(BadType, source, edge.node(), jumpToFail);
+}
+
+void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
+{
+ backwardTypeCheck(source, edge, typesPassedThrough, jumpToFail);
+ if (m_speculationDirection == ForwardSpeculation)
+ convertLastOSRExitToForward();
+}
+
+void SpeculativeJIT::forwardTypeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
+{
+ backwardTypeCheck(source, edge, typesPassedThrough, jumpToFail);
+ convertLastOSRExitToForward(valueRecovery);
}
void SpeculativeJIT::addSlowPathGenerator(PassOwnPtr<SlowPathGenerator> slowPathGenerator)
{
- m_slowPathGenerators.append(slowPathGenerator.leakPtr());
+ m_slowPathGenerators.append(slowPathGenerator);
}
void SpeculativeJIT::runSlowPathGenerators()
@@ -343,33 +374,301 @@ void SpeculativeJIT::clearGenerationInfo()
m_fprs = RegisterBank<FPRInfo>();
}
+SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source)
+{
+ GenerationInfo& info = m_generationInfo[spillMe];
+ Node* node = info.node();
+ DataFormat registerFormat = info.registerFormat();
+ ASSERT(registerFormat != DataFormatNone);
+ ASSERT(registerFormat != DataFormatDouble);
+
+ SilentSpillAction spillAction;
+ SilentFillAction fillAction;
+
+ if (!info.needsSpill())
+ spillAction = DoNothingForSpill;
+ else {
+#if USE(JSVALUE64)
+ ASSERT(info.gpr() == source);
+ if (registerFormat == DataFormatInteger)
+ spillAction = Store32Payload;
+ else if (registerFormat == DataFormatCell || registerFormat == DataFormatStorage)
+ spillAction = StorePtr;
+ else {
+ ASSERT(registerFormat & DataFormatJS);
+ spillAction = Store64;
+ }
+#elif USE(JSVALUE32_64)
+ if (registerFormat & DataFormatJS) {
+ ASSERT(info.tagGPR() == source || info.payloadGPR() == source);
+ spillAction = source == info.tagGPR() ? Store32Tag : Store32Payload;
+ } else {
+ ASSERT(info.gpr() == source);
+ spillAction = Store32Payload;
+ }
+#endif
+ }
+
+ if (registerFormat == DataFormatInteger) {
+ ASSERT(info.gpr() == source);
+ ASSERT(isJSInteger(info.registerFormat()));
+ if (node->hasConstant()) {
+ ASSERT(isInt32Constant(node));
+ fillAction = SetInt32Constant;
+ } else
+ fillAction = Load32Payload;
+ } else if (registerFormat == DataFormatBoolean) {
+#if USE(JSVALUE64)
+ RELEASE_ASSERT_NOT_REACHED();
+ fillAction = DoNothingForFill;
+#elif USE(JSVALUE32_64)
+ ASSERT(info.gpr() == source);
+ if (node->hasConstant()) {
+ ASSERT(isBooleanConstant(node));
+ fillAction = SetBooleanConstant;
+ } else
+ fillAction = Load32Payload;
+#endif
+ } else if (registerFormat == DataFormatCell) {
+ ASSERT(info.gpr() == source);
+ if (node->hasConstant()) {
+ JSValue value = valueOfJSConstant(node);
+ ASSERT_UNUSED(value, value.isCell());
+ fillAction = SetCellConstant;
+ } else {
+#if USE(JSVALUE64)
+ fillAction = LoadPtr;
+#else
+ fillAction = Load32Payload;
+#endif
+ }
+ } else if (registerFormat == DataFormatStorage) {
+ ASSERT(info.gpr() == source);
+ fillAction = LoadPtr;
+ } else {
+ ASSERT(registerFormat & DataFormatJS);
+#if USE(JSVALUE64)
+ ASSERT(info.gpr() == source);
+ if (node->hasConstant()) {
+ if (valueOfJSConstant(node).isCell())
+ fillAction = SetTrustedJSConstant;
+ else
+ fillAction = SetJSConstant;
+ } else if (info.spillFormat() == DataFormatInteger) {
+ ASSERT(registerFormat == DataFormatJSInteger);
+ fillAction = Load32PayloadBoxInt;
+ } else if (info.spillFormat() == DataFormatDouble) {
+ ASSERT(registerFormat == DataFormatJSDouble);
+ fillAction = LoadDoubleBoxDouble;
+ } else
+ fillAction = Load64;
+#else
+ ASSERT(info.tagGPR() == source || info.payloadGPR() == source);
+ if (node->hasConstant())
+ fillAction = info.tagGPR() == source ? SetJSConstantTag : SetJSConstantPayload;
+ else if (info.payloadGPR() == source)
+ fillAction = Load32Payload;
+ else { // Fill the Tag
+ switch (info.spillFormat()) {
+ case DataFormatInteger:
+ ASSERT(registerFormat == DataFormatJSInteger);
+ fillAction = SetInt32Tag;
+ break;
+ case DataFormatCell:
+ ASSERT(registerFormat == DataFormatJSCell);
+ fillAction = SetCellTag;
+ break;
+ case DataFormatBoolean:
+ ASSERT(registerFormat == DataFormatJSBoolean);
+ fillAction = SetBooleanTag;
+ break;
+ default:
+ fillAction = Load32Tag;
+ break;
+ }
+ }
+#endif
+ }
+
+ return SilentRegisterSavePlan(spillAction, fillAction, node, source);
+}
+
+SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source)
+{
+ GenerationInfo& info = m_generationInfo[spillMe];
+ Node* node = info.node();
+ ASSERT(info.registerFormat() == DataFormatDouble);
+
+ SilentSpillAction spillAction;
+ SilentFillAction fillAction;
+
+ if (!info.needsSpill())
+ spillAction = DoNothingForSpill;
+ else {
+ ASSERT(!node->hasConstant());
+ ASSERT(info.spillFormat() == DataFormatNone);
+ ASSERT(info.fpr() == source);
+ spillAction = StoreDouble;
+ }
+
+#if USE(JSVALUE64)
+ if (node->hasConstant()) {
+ ASSERT(isNumberConstant(node));
+ fillAction = SetDoubleConstant;
+ } else if (info.spillFormat() != DataFormatNone && info.spillFormat() != DataFormatDouble) {
+ // it was already spilled previously and not as a double, which means we need unboxing.
+ ASSERT(info.spillFormat() & DataFormatJS);
+ fillAction = LoadJSUnboxDouble;
+ } else
+ fillAction = LoadDouble;
+#elif USE(JSVALUE32_64)
+ ASSERT(info.registerFormat() == DataFormatDouble || info.registerFormat() == DataFormatJSDouble);
+ if (node->hasConstant()) {
+ ASSERT(isNumberConstant(node));
+ fillAction = SetDoubleConstant;
+ } else
+ fillAction = LoadDouble;
+#endif
+
+ return SilentRegisterSavePlan(spillAction, fillAction, node, source);
+}
+
+void SpeculativeJIT::silentSpill(const SilentRegisterSavePlan& plan)
+{
+ switch (plan.spillAction()) {
+ case DoNothingForSpill:
+ break;
+ case Store32Tag:
+ m_jit.store32(plan.gpr(), JITCompiler::tagFor(plan.node()->virtualRegister()));
+ break;
+ case Store32Payload:
+ m_jit.store32(plan.gpr(), JITCompiler::payloadFor(plan.node()->virtualRegister()));
+ break;
+ case StorePtr:
+ m_jit.storePtr(plan.gpr(), JITCompiler::addressFor(plan.node()->virtualRegister()));
+ break;
+#if USE(JSVALUE64)
+ case Store64:
+ m_jit.store64(plan.gpr(), JITCompiler::addressFor(plan.node()->virtualRegister()));
+ break;
+#endif
+ case StoreDouble:
+ m_jit.storeDouble(plan.fpr(), JITCompiler::addressFor(plan.node()->virtualRegister()));
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
+void SpeculativeJIT::silentFill(const SilentRegisterSavePlan& plan, GPRReg canTrample)
+{
+#if USE(JSVALUE32_64)
+ UNUSED_PARAM(canTrample);
+#endif
+ switch (plan.fillAction()) {
+ case DoNothingForFill:
+ break;
+ case SetInt32Constant:
+ m_jit.move(Imm32(valueOfInt32Constant(plan.node())), plan.gpr());
+ break;
+ case SetBooleanConstant:
+ m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.node())), plan.gpr());
+ break;
+ case SetCellConstant:
+ m_jit.move(TrustedImmPtr(valueOfJSConstant(plan.node()).asCell()), plan.gpr());
+ break;
+#if USE(JSVALUE64)
+ case SetTrustedJSConstant:
+ m_jit.move(valueOfJSConstantAsImm64(plan.node()).asTrustedImm64(), plan.gpr());
+ break;
+ case SetJSConstant:
+ m_jit.move(valueOfJSConstantAsImm64(plan.node()), plan.gpr());
+ break;
+ case SetDoubleConstant:
+ m_jit.move(Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(plan.node()))), canTrample);
+ m_jit.move64ToDouble(canTrample, plan.fpr());
+ break;
+ case Load32PayloadBoxInt:
+ m_jit.load32(JITCompiler::payloadFor(plan.node()->virtualRegister()), plan.gpr());
+ m_jit.or64(GPRInfo::tagTypeNumberRegister, plan.gpr());
+ break;
+ case LoadDoubleBoxDouble:
+ m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
+ m_jit.sub64(GPRInfo::tagTypeNumberRegister, plan.gpr());
+ break;
+ case LoadJSUnboxDouble:
+ m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), canTrample);
+ unboxDouble(canTrample, plan.fpr());
+ break;
+#else
+ case SetJSConstantTag:
+ m_jit.move(Imm32(valueOfJSConstant(plan.node()).tag()), plan.gpr());
+ break;
+ case SetJSConstantPayload:
+ m_jit.move(Imm32(valueOfJSConstant(plan.node()).payload()), plan.gpr());
+ break;
+ case SetInt32Tag:
+ m_jit.move(TrustedImm32(JSValue::Int32Tag), plan.gpr());
+ break;
+ case SetCellTag:
+ m_jit.move(TrustedImm32(JSValue::CellTag), plan.gpr());
+ break;
+ case SetBooleanTag:
+ m_jit.move(TrustedImm32(JSValue::BooleanTag), plan.gpr());
+ break;
+ case SetDoubleConstant:
+ m_jit.loadDouble(addressOfDoubleConstant(plan.node()), plan.fpr());
+ break;
+#endif
+ case Load32Tag:
+ m_jit.load32(JITCompiler::tagFor(plan.node()->virtualRegister()), plan.gpr());
+ break;
+ case Load32Payload:
+ m_jit.load32(JITCompiler::payloadFor(plan.node()->virtualRegister()), plan.gpr());
+ break;
+ case LoadPtr:
+ m_jit.loadPtr(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
+ break;
+#if USE(JSVALUE64)
+ case Load64:
+ m_jit.load64(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.gpr());
+ break;
+#endif
+ case LoadDouble:
+ m_jit.loadDouble(JITCompiler::addressFor(plan.node()->virtualRegister()), plan.fpr());
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
const TypedArrayDescriptor* SpeculativeJIT::typedArrayDescriptor(ArrayMode arrayMode)
{
switch (arrayMode.type()) {
case Array::Int8Array:
- return &m_jit.globalData()->int8ArrayDescriptor();
+ return &m_jit.vm()->int8ArrayDescriptor();
case Array::Int16Array:
- return &m_jit.globalData()->int16ArrayDescriptor();
+ return &m_jit.vm()->int16ArrayDescriptor();
case Array::Int32Array:
- return &m_jit.globalData()->int32ArrayDescriptor();
+ return &m_jit.vm()->int32ArrayDescriptor();
case Array::Uint8Array:
- return &m_jit.globalData()->uint8ArrayDescriptor();
+ return &m_jit.vm()->uint8ArrayDescriptor();
case Array::Uint8ClampedArray:
- return &m_jit.globalData()->uint8ClampedArrayDescriptor();
+ return &m_jit.vm()->uint8ClampedArrayDescriptor();
case Array::Uint16Array:
- return &m_jit.globalData()->uint16ArrayDescriptor();
+ return &m_jit.vm()->uint16ArrayDescriptor();
case Array::Uint32Array:
- return &m_jit.globalData()->uint32ArrayDescriptor();
+ return &m_jit.vm()->uint32ArrayDescriptor();
case Array::Float32Array:
- return &m_jit.globalData()->float32ArrayDescriptor();
+ return &m_jit.vm()->float32ArrayDescriptor();
case Array::Float64Array:
- return &m_jit.globalData()->float64ArrayDescriptor();
+ return &m_jit.vm()->float64ArrayDescriptor();
default:
return 0;
}
}
-JITCompiler::Jump SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, ArrayMode arrayMode, IndexingType shape, bool invert)
+JITCompiler::Jump SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, ArrayMode arrayMode, IndexingType shape)
{
switch (arrayMode.arrayClass()) {
case Array::OriginalArray: {
@@ -381,27 +680,27 @@ JITCompiler::Jump SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, A
case Array::Array:
m_jit.and32(TrustedImm32(IsArray | IndexingShapeMask), tempGPR);
return m_jit.branch32(
- invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(IsArray | shape));
+ MacroAssembler::NotEqual, tempGPR, TrustedImm32(IsArray | shape));
default:
m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR);
- return m_jit.branch32(invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(shape));
+ return m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(shape));
}
}
-JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, ArrayMode arrayMode, bool invert)
+JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, ArrayMode arrayMode)
{
JITCompiler::JumpList result;
switch (arrayMode.type()) {
case Array::Int32:
- return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, Int32Shape, invert);
+ return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, Int32Shape);
case Array::Double:
- return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, DoubleShape, invert);
+ return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, DoubleShape);
case Array::Contiguous:
- return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, ContiguousShape, invert);
+ return jumpSlowForUnwantedArrayMode(tempGPR, arrayMode, ContiguousShape);
case Array::ArrayStorage:
case Array::SlowPutArrayStorage: {
@@ -409,19 +708,6 @@ JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGP
if (arrayMode.isJSArray()) {
if (arrayMode.isSlowPut()) {
- if (invert) {
- JITCompiler::Jump slow = m_jit.branchTest32(
- MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32(IsArray));
- m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR);
- m_jit.sub32(TrustedImm32(ArrayStorageShape), tempGPR);
- result.append(
- m_jit.branch32(
- MacroAssembler::BelowOrEqual, tempGPR,
- TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)));
-
- slow.link(&m_jit);
- }
-
result.append(
m_jit.branchTest32(
MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32(IsArray)));
@@ -435,7 +721,7 @@ JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGP
}
m_jit.and32(TrustedImm32(IsArray | IndexingShapeMask), tempGPR);
result.append(
- m_jit.branch32(invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(ArrayStorageShape)));
+ m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(IsArray | ArrayStorageShape)));
break;
}
m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR);
@@ -443,12 +729,12 @@ JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGP
m_jit.sub32(TrustedImm32(ArrayStorageShape), tempGPR);
result.append(
m_jit.branch32(
- invert ? MacroAssembler::BelowOrEqual : MacroAssembler::Above, tempGPR,
+ MacroAssembler::Above, tempGPR,
TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)));
break;
}
result.append(
- m_jit.branch32(invert ? MacroAssembler::Equal : MacroAssembler::NotEqual, tempGPR, TrustedImm32(ArrayStorageShape)));
+ m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(ArrayStorageShape)));
break;
}
default:
@@ -459,24 +745,24 @@ JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGP
return result;
}
-void SpeculativeJIT::checkArray(Node& node)
+void SpeculativeJIT::checkArray(Node* node)
{
- ASSERT(node.arrayMode().isSpecific());
- ASSERT(!node.arrayMode().doesConversion());
+ ASSERT(node->arrayMode().isSpecific());
+ ASSERT(!node->arrayMode().doesConversion());
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseReg = base.gpr();
- const TypedArrayDescriptor* result = typedArrayDescriptor(node.arrayMode());
+ const TypedArrayDescriptor* result = typedArrayDescriptor(node->arrayMode());
- if (node.arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node.child1()))) {
- noResult(m_compileIndex);
+ if (node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1()))) {
+ noResult(m_currentNode);
return;
}
const ClassInfo* expectedClassInfo = 0;
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::String:
expectedClassInfo = &JSString::s_info;
break;
@@ -491,10 +777,10 @@ void SpeculativeJIT::checkArray(Node& node)
MacroAssembler::Address(baseReg, JSCell::structureOffset()), tempGPR);
m_jit.load8(MacroAssembler::Address(tempGPR, Structure::indexingTypeOffset()), tempGPR);
speculationCheck(
- BadIndexingType, JSValueSource::unboxedCell(baseReg), NoNode,
- jumpSlowForUnwantedArrayMode(tempGPR, node.arrayMode()));
+ BadIndexingType, JSValueSource::unboxedCell(baseReg), 0,
+ jumpSlowForUnwantedArrayMode(tempGPR, node->arrayMode()));
- noResult(m_compileIndex);
+ noResult(m_currentNode);
return;
}
case Array::Arguments:
@@ -512,7 +798,7 @@ void SpeculativeJIT::checkArray(Node& node)
expectedClassInfo = result->m_classInfo;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -520,38 +806,38 @@ void SpeculativeJIT::checkArray(Node& node)
m_jit.loadPtr(
MacroAssembler::Address(baseReg, JSCell::structureOffset()), temp.gpr());
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branchPtr(
MacroAssembler::NotEqual,
MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()),
MacroAssembler::TrustedImmPtr(expectedClassInfo)));
- noResult(m_compileIndex);
+ noResult(m_currentNode);
}
-void SpeculativeJIT::arrayify(Node& node, GPRReg baseReg, GPRReg propertyReg)
+void SpeculativeJIT::arrayify(Node* node, GPRReg baseReg, GPRReg propertyReg)
{
- ASSERT(node.arrayMode().doesConversion());
+ ASSERT(node->arrayMode().doesConversion());
GPRTemporary temp(this);
GPRTemporary structure;
GPRReg tempGPR = temp.gpr();
GPRReg structureGPR = InvalidGPRReg;
- if (node.op() != ArrayifyToStructure) {
+ if (node->op() != ArrayifyToStructure) {
GPRTemporary realStructure(this);
structure.adopt(realStructure);
structureGPR = structure.gpr();
}
// We can skip all that comes next if we already have array storage.
- MacroAssembler::JumpList done;
+ MacroAssembler::JumpList slowPath;
- if (node.op() == ArrayifyToStructure) {
- done.append(m_jit.branchWeakPtr(
- JITCompiler::Equal,
+ if (node->op() == ArrayifyToStructure) {
+ slowPath.append(m_jit.branchWeakPtr(
+ JITCompiler::NotEqual,
JITCompiler::Address(baseReg, JSCell::structureOffset()),
- node.structure()));
+ node->structure()));
} else {
m_jit.loadPtr(
MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR);
@@ -559,106 +845,34 @@ void SpeculativeJIT::arrayify(Node& node, GPRReg baseReg, GPRReg propertyReg)
m_jit.load8(
MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), tempGPR);
- done = jumpSlowForUnwantedArrayMode(tempGPR, node.arrayMode(), true);
-
- // Next check that the object does not intercept indexed accesses. If it does,
- // then this mode won't work.
- speculationCheck(
- BadIndexingType, JSValueSource::unboxedCell(baseReg), NoNode,
- m_jit.branchTest8(
- MacroAssembler::NonZero,
- MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
- MacroAssembler::TrustedImm32(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero)));
- }
-
- // If we're allegedly creating contiguous storage and the index is bogus, then
- // just don't.
- if (propertyReg != InvalidGPRReg) {
- switch (node.arrayMode().type()) {
- case Array::Int32:
- case Array::Double:
- case Array::Contiguous:
- speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
- m_jit.branch32(
- MacroAssembler::AboveOrEqual, propertyReg, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
- break;
- default:
- break;
- }
+ slowPath.append(jumpSlowForUnwantedArrayMode(tempGPR, node->arrayMode()));
}
- // Now call out to create the array storage.
- silentSpillAllRegisters(tempGPR);
- switch (node.arrayMode().type()) {
- case Array::Int32:
- callOperation(operationEnsureInt32, tempGPR, baseReg);
- break;
- case Array::Double:
- callOperation(operationEnsureDouble, tempGPR, baseReg);
- break;
- case Array::Contiguous:
- callOperation(operationEnsureContiguous, tempGPR, baseReg);
- break;
- case Array::ArrayStorage:
- case Array::SlowPutArrayStorage:
- callOperation(operationEnsureArrayStorage, tempGPR, baseReg);
- break;
- default:
- CRASH();
- break;
- }
- silentFillAllRegisters(tempGPR);
-
- if (node.op() == ArrayifyToStructure) {
- speculationCheck(
- BadIndexingType, JSValueSource::unboxedCell(baseReg), NoNode,
- m_jit.branchWeakPtr(
- JITCompiler::NotEqual,
- JITCompiler::Address(baseReg, JSCell::structureOffset()),
- node.structure()));
- } else {
- // Alas, we need to reload the structure because silent spilling does not save
- // temporaries. Nor would it be useful for it to do so. Either way we're talking
- // about a load.
- m_jit.loadPtr(
- MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR);
-
- // Finally, check that we have the kind of array storage that we wanted to get.
- // Note that this is a backwards speculation check, which will result in the
- // bytecode operation corresponding to this arrayification being reexecuted.
- // That's fine, since arrayification is not user-visible.
- m_jit.load8(
- MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), structureGPR);
- speculationCheck(
- BadIndexingType, JSValueSource::unboxedCell(baseReg), NoNode,
- jumpSlowForUnwantedArrayMode(structureGPR, node.arrayMode()));
- }
+ addSlowPathGenerator(adoptPtr(new ArrayifySlowPathGenerator(
+ slowPath, this, node, baseReg, propertyReg, tempGPR, structureGPR)));
- done.link(&m_jit);
- noResult(m_compileIndex);
+ noResult(m_currentNode);
}
-void SpeculativeJIT::arrayify(Node& node)
+void SpeculativeJIT::arrayify(Node* node)
{
- ASSERT(node.arrayMode().isSpecific());
+ ASSERT(node->arrayMode().isSpecific());
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
- if (!node.child2()) {
+ if (!node->child2()) {
arrayify(node, base.gpr(), InvalidGPRReg);
return;
}
- SpeculateIntegerOperand property(this, node.child2());
+ SpeculateIntegerOperand property(this, node->child2());
arrayify(node, base.gpr(), property.gpr());
}
-GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
+GPRReg SpeculativeJIT::fillStorage(Edge edge)
{
- Node& node = m_jit.graph()[nodeIndex];
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
@@ -672,7 +886,7 @@ GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
}
// Must be a cell; fill it as a cell and then return the pointer.
- return fillSpeculateCell(nodeIndex, BackwardSpeculation);
+ return fillSpeculateCell(edge);
}
case DataFormatStorage: {
@@ -682,115 +896,39 @@ GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
}
default:
- return fillSpeculateCell(nodeIndex, BackwardSpeculation);
+ return fillSpeculateCell(edge);
}
}
-void SpeculativeJIT::useChildren(Node& node)
+void SpeculativeJIT::useChildren(Node* node)
{
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) {
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
if (!!m_jit.graph().m_varArgChildren[childIdx])
use(m_jit.graph().m_varArgChildren[childIdx]);
}
} else {
- Edge child1 = node.child1();
+ Edge child1 = node->child1();
if (!child1) {
- ASSERT(!node.child2() && !node.child3());
+ ASSERT(!node->child2() && !node->child3());
return;
}
use(child1);
- Edge child2 = node.child2();
+ Edge child2 = node->child2();
if (!child2) {
- ASSERT(!node.child3());
+ ASSERT(!node->child3());
return;
}
use(child2);
- Edge child3 = node.child3();
+ Edge child3 = node->child3();
if (!child3)
return;
use(child3);
}
}
-bool SpeculativeJIT::isStrictInt32(NodeIndex nodeIndex)
-{
- if (isInt32Constant(nodeIndex))
- return true;
-
- Node& node = m_jit.graph()[nodeIndex];
- GenerationInfo& info = m_generationInfo[node.virtualRegister()];
-
- return info.registerFormat() == DataFormatInteger;
-}
-
-bool SpeculativeJIT::isKnownInteger(NodeIndex nodeIndex)
-{
- if (isInt32Constant(nodeIndex))
- return true;
-
- Node& node = m_jit.graph()[nodeIndex];
-
- if (node.hasInt32Result())
- return true;
-
- GenerationInfo& info = m_generationInfo[node.virtualRegister()];
-
- return info.isJSInteger();
-}
-
-bool SpeculativeJIT::isKnownNumeric(NodeIndex nodeIndex)
-{
- if (isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex))
- return true;
-
- Node& node = m_jit.graph()[nodeIndex];
-
- if (node.hasNumberResult())
- return true;
-
- GenerationInfo& info = m_generationInfo[node.virtualRegister()];
-
- return info.isJSInteger() || info.isJSDouble();
-}
-
-bool SpeculativeJIT::isKnownCell(NodeIndex nodeIndex)
-{
- return m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()].isJSCell();
-}
-
-bool SpeculativeJIT::isKnownNotCell(NodeIndex nodeIndex)
-{
- Node& node = m_jit.graph()[nodeIndex];
- VirtualRegister virtualRegister = node.virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
- if (node.hasConstant() && !valueOfJSConstant(nodeIndex).isCell())
- return true;
- return !(info.isJSCell() || info.isUnknownJS());
-}
-
-bool SpeculativeJIT::isKnownNotInteger(NodeIndex nodeIndex)
-{
- Node& node = m_jit.graph()[nodeIndex];
- VirtualRegister virtualRegister = node.virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
-
- return info.isJSDouble() || info.isJSCell() || info.isJSBoolean()
- || (node.hasConstant() && !valueOfJSConstant(nodeIndex).isInt32());
-}
-
-bool SpeculativeJIT::isKnownNotNumber(NodeIndex nodeIndex)
-{
- Node& node = m_jit.graph()[nodeIndex];
- VirtualRegister virtualRegister = node.virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
-
- return (!info.isJSDouble() && !info.isJSInteger() && !info.isUnknownJS())
- || (node.hasConstant() && !isNumberConstant(nodeIndex));
-}
-
void SpeculativeJIT::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
{
UNUSED_PARAM(jit);
@@ -805,30 +943,6 @@ void SpeculativeJIT::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scra
#if ENABLE(WRITE_BARRIER_PROFILING)
JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
#endif
- markCellCard(jit, owner, scratch1, scratch2);
-}
-
-void SpeculativeJIT::markCellCard(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
-{
- UNUSED_PARAM(jit);
- UNUSED_PARAM(owner);
- UNUSED_PARAM(scratch1);
- UNUSED_PARAM(scratch2);
-
-#if ENABLE(GGC)
- jit.move(owner, scratch1);
- jit.andPtr(TrustedImm32(static_cast<int32_t>(MarkedBlock::blockMask)), scratch1);
- jit.move(owner, scratch2);
- // consume additional 8 bits as we're using an approximate filter
- jit.rshift32(TrustedImm32(MarkedBlock::atomShift + 8), scratch2);
- jit.andPtr(TrustedImm32(MarkedBlock::atomMask >> 8), scratch2);
- MacroAssembler::Jump filter = jit.branchTest8(MacroAssembler::Zero, MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfMarks()));
- jit.move(owner, scratch2);
- jit.rshift32(TrustedImm32(MarkedBlock::cardShift), scratch2);
- jit.andPtr(TrustedImm32(MarkedBlock::cardMask), scratch2);
- jit.store8(TrustedImm32(1), MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfCards()));
- filter.link(&jit);
-#endif
}
void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
@@ -839,39 +953,12 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUs
UNUSED_PARAM(scratch2);
UNUSED_PARAM(useKind);
- if (isKnownNotCell(valueUse.index()))
+ if (isKnownNotCell(valueUse.node()))
return;
#if ENABLE(WRITE_BARRIER_PROFILING)
JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
#endif
-
-#if ENABLE(GGC)
- GPRTemporary temp1;
- GPRTemporary temp2;
- if (scratch1 == InvalidGPRReg) {
- GPRTemporary scratchGPR(this);
- temp1.adopt(scratchGPR);
- scratch1 = temp1.gpr();
- }
- if (scratch2 == InvalidGPRReg) {
- GPRTemporary scratchGPR(this);
- temp2.adopt(scratchGPR);
- scratch2 = temp2.gpr();
- }
-
- JITCompiler::Jump rhsNotCell;
- bool hadCellCheck = false;
- if (!isKnownCell(valueUse.index()) && !isCellSpeculation(m_jit.getSpeculation(valueUse.index()))) {
- hadCellCheck = true;
- rhsNotCell = m_jit.branchIfNotCell(valueGPR);
- }
-
- markCellCard(m_jit, ownerGPR, scratch1, scratch2);
-
- if (hadCellCheck)
- rhsNotCell.link(&m_jit);
-#endif
}
void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
@@ -888,23 +975,6 @@ void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUs
#if ENABLE(WRITE_BARRIER_PROFILING)
JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
#endif
-
-#if ENABLE(GGC)
- GPRTemporary temp1;
- GPRTemporary temp2;
- if (scratch1 == InvalidGPRReg) {
- GPRTemporary scratchGPR(this);
- temp1.adopt(scratchGPR);
- scratch1 = temp1.gpr();
- }
- if (scratch2 == InvalidGPRReg) {
- GPRTemporary scratchGPR(this);
- temp2.adopt(scratchGPR);
- scratch2 = temp2.gpr();
- }
-
- markCellCard(m_jit, ownerGPR, scratch1, scratch2);
-#endif
}
void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind useKind, GPRReg scratch)
@@ -914,49 +984,26 @@ void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, Edge valueUse,
UNUSED_PARAM(scratch);
UNUSED_PARAM(useKind);
- if (isKnownNotCell(valueUse.index()))
+ if (isKnownNotCell(valueUse.node()))
return;
#if ENABLE(WRITE_BARRIER_PROFILING)
JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
#endif
-
-#if ENABLE(GGC)
- JITCompiler::Jump rhsNotCell;
- bool hadCellCheck = false;
- if (!isKnownCell(valueUse.index()) && !isCellSpeculation(m_jit.getSpeculation(valueUse.index()))) {
- hadCellCheck = true;
- rhsNotCell = m_jit.branchIfNotCell(valueGPR);
- }
-
- GPRTemporary temp;
- if (scratch == InvalidGPRReg) {
- GPRTemporary scratchGPR(this);
- temp.adopt(scratchGPR);
- scratch = temp.gpr();
- }
-
- uint8_t* cardAddress = Heap::addressOfCardFor(owner);
- m_jit.move(JITCompiler::TrustedImmPtr(cardAddress), scratch);
- m_jit.store8(JITCompiler::TrustedImm32(1), JITCompiler::Address(scratch));
-
- if (hadCellCheck)
- rhsNotCell.link(&m_jit);
-#endif
}
-bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
+bool SpeculativeJIT::nonSpeculativeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
{
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
- ASSERT(node.adjustedRefCount() == 1);
+ ASSERT(node->adjustedRefCount() == 1);
- nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
+ nonSpeculativePeepholeBranch(node, branchNode, cond, helperFunction);
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
@@ -966,18 +1013,18 @@ bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::Relationa
return false;
}
-bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert)
+bool SpeculativeJIT::nonSpeculativeStrictEq(Node* node, bool invert)
{
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
- ASSERT(node.adjustedRefCount() == 1);
+ ASSERT(node->adjustedRefCount() == 1);
- nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
+ nonSpeculativePeepholeStrictEq(node, branchNode, invert);
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
@@ -1101,6 +1148,11 @@ void SpeculativeJIT::checkConsistency()
}
break;
}
+ case DataFormatOSRMarker:
+ case DataFormatDead:
+ case DataFormatArguments:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
}
}
@@ -1173,7 +1225,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateIntegerOperand& op1)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1183,9 +1235,9 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateIntegerOperand& op1, Sp
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
- else if (m_jit->canReuse(op2.index()))
+ else if (m_jit->canReuse(op2.node()))
m_gpr = m_jit->reuse(op2.gpr());
else
m_gpr = m_jit->allocate();
@@ -1195,7 +1247,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateStrictInt32Operand& op1
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1205,7 +1257,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, IntegerOperand& op1)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1215,9 +1267,9 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, IntegerOperand& op1, IntegerOper
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
- else if (m_jit->canReuse(op2.index()))
+ else if (m_jit->canReuse(op2.node()))
m_gpr = m_jit->reuse(op2.gpr());
else
m_gpr = m_jit->allocate();
@@ -1227,7 +1279,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateCellOperand& op1)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1237,7 +1289,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateBooleanOperand& op1)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1248,7 +1300,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1258,7 +1310,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1, bool tag)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (!op1.isDouble() && m_jit->canReuse(op1.index()))
+ if (!op1.isDouble() && m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(tag ? op1.tagGPR() : op1.payloadGPR());
else
m_gpr = m_jit->allocate();
@@ -1269,7 +1321,7 @@ GPRTemporary::GPRTemporary(SpeculativeJIT* jit, StorageOperand& op1)
: m_jit(jit)
, m_gpr(InvalidGPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_gpr = m_jit->reuse(op1.gpr());
else
m_gpr = m_jit->allocate();
@@ -1294,33 +1346,11 @@ FPRTemporary::FPRTemporary(SpeculativeJIT* jit)
m_fpr = m_jit->fprAllocate();
}
-FPRTemporary::FPRTemporary(SpeculativeJIT* jit, DoubleOperand& op1)
- : m_jit(jit)
- , m_fpr(InvalidFPRReg)
-{
- if (m_jit->canReuse(op1.index()))
- m_fpr = m_jit->reuse(op1.fpr());
- else
- m_fpr = m_jit->fprAllocate();
-}
-
-FPRTemporary::FPRTemporary(SpeculativeJIT* jit, DoubleOperand& op1, DoubleOperand& op2)
- : m_jit(jit)
- , m_fpr(InvalidFPRReg)
-{
- if (m_jit->canReuse(op1.index()))
- m_fpr = m_jit->reuse(op1.fpr());
- else if (m_jit->canReuse(op2.index()))
- m_fpr = m_jit->reuse(op2.fpr());
- else
- m_fpr = m_jit->fprAllocate();
-}
-
FPRTemporary::FPRTemporary(SpeculativeJIT* jit, SpeculateDoubleOperand& op1)
: m_jit(jit)
, m_fpr(InvalidFPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_fpr = m_jit->reuse(op1.fpr());
else
m_fpr = m_jit->fprAllocate();
@@ -1330,9 +1360,9 @@ FPRTemporary::FPRTemporary(SpeculativeJIT* jit, SpeculateDoubleOperand& op1, Spe
: m_jit(jit)
, m_fpr(InvalidFPRReg)
{
- if (m_jit->canReuse(op1.index()))
+ if (m_jit->canReuse(op1.node()))
m_fpr = m_jit->reuse(op1.fpr());
- else if (m_jit->canReuse(op2.index()))
+ else if (m_jit->canReuse(op2.node()))
m_fpr = m_jit->reuse(op2.fpr());
else
m_fpr = m_jit->fprAllocate();
@@ -1343,31 +1373,29 @@ FPRTemporary::FPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
: m_jit(jit)
, m_fpr(InvalidFPRReg)
{
- if (op1.isDouble() && m_jit->canReuse(op1.index()))
+ if (op1.isDouble() && m_jit->canReuse(op1.node()))
m_fpr = m_jit->reuse(op1.fpr());
else
m_fpr = m_jit->fprAllocate();
}
#endif
-void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
+void SpeculativeJIT::compilePeepHoleDoubleBranch(Node* node, Node* branchNode, JITCompiler::DoubleCondition condition)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
branchDouble(condition, op1.fpr(), op2.fpr(), taken);
jump(notTaken);
}
-void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex)
+void SpeculativeJIT::compilePeepHoleObjectEquality(Node* node, Node* branchNode)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
@@ -1378,47 +1406,59 @@ void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchN
notTaken = tmp;
}
- SpeculateCellOperand op1(this, node.child1());
- SpeculateCellOperand op2(this, node.child2());
+ SpeculateCellOperand op1(this, node->child1());
+ SpeculateCellOperand op2(this, node->child2());
GPRReg op1GPR = op1.gpr();
GPRReg op2GPR = op2.gpr();
- if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1().index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2().index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
+ speculationCheck(
+ BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ }
+ if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
+ speculationCheck(
+ BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ }
} else {
GPRTemporary structure(this);
GPRReg structureGPR = structure.gpr();
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1().index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1().index(),
+ if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
+ speculationCheck(
+ BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ structureGPR,
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ }
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2().index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2().index(),
+ if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
+ speculationCheck(
+ BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ structureGPR,
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ }
+ speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1429,11 +1469,41 @@ void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchN
jump(notTaken);
}
-void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition condition)
+void SpeculativeJIT::compilePeepHoleBooleanBranch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
+{
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
+
+ // The branch instruction will branch to the taken block.
+ // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
+ if (taken == nextBlock()) {
+ condition = JITCompiler::invert(condition);
+ BlockIndex tmp = taken;
+ taken = notTaken;
+ notTaken = tmp;
+ }
+
+ if (isBooleanConstant(node->child1().node())) {
+ bool imm = valueOfBooleanConstant(node->child1().node());
+ SpeculateBooleanOperand op2(this, node->child2());
+ branch32(condition, JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), op2.gpr(), taken);
+ } else if (isBooleanConstant(node->child2().node())) {
+ SpeculateBooleanOperand op1(this, node->child1());
+ bool imm = valueOfBooleanConstant(node->child2().node());
+ branch32(condition, op1.gpr(), JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), taken);
+ } else {
+ SpeculateBooleanOperand op1(this, node->child1());
+ SpeculateBooleanOperand op2(this, node->child2());
+ branch32(condition, op1.gpr(), op2.gpr(), taken);
+ }
+
+ jump(notTaken);
+}
+
+void SpeculativeJIT::compilePeepHoleIntegerBranch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
// The branch instruction will branch to the taken block.
// If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
@@ -1444,17 +1514,17 @@ void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNo
notTaken = tmp;
}
- if (isInt32Constant(node.child1().index())) {
- int32_t imm = valueOfInt32Constant(node.child1().index());
- SpeculateIntegerOperand op2(this, node.child2());
+ if (isInt32Constant(node->child1().node())) {
+ int32_t imm = valueOfInt32Constant(node->child1().node());
+ SpeculateIntegerOperand op2(this, node->child2());
branch32(condition, JITCompiler::Imm32(imm), op2.gpr(), taken);
- } else if (isInt32Constant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
- int32_t imm = valueOfInt32Constant(node.child2().index());
+ } else if (isInt32Constant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
+ int32_t imm = valueOfInt32Constant(node->child2().node());
branch32(condition, op1.gpr(), JITCompiler::Imm32(imm), taken);
} else {
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
branch32(condition, op1.gpr(), op2.gpr(), taken);
}
@@ -1462,74 +1532,124 @@ void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNo
}
// Returns true if the compare is fused with a subsequent branch.
-bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
+bool SpeculativeJIT::compilePeepHoleBranch(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
{
// Fused compare & branch.
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ Node* branchNode = 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);
-
- if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())))
- compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
- else if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2())))
- compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
- else if (node.op() == CompareEq) {
- if (at(node.child1()).shouldSpeculateString() || at(node.child2()).shouldSpeculateString()) {
- nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
- return true;
+ ASSERT(node->adjustedRefCount() == 1);
+
+ if (node->isBinaryUseKind(Int32Use))
+ compilePeepHoleIntegerBranch(node, branchNode, condition);
+ else if (node->isBinaryUseKind(NumberUse))
+ compilePeepHoleDoubleBranch(node, branchNode, doubleCondition);
+ else if (node->op() == CompareEq) {
+ if (node->isBinaryUseKind(StringUse)) {
+ // Use non-peephole comparison, for now.
+ return false;
}
- if (at(node.child1()).shouldSpeculateNonStringCell() && at(node.child2()).shouldSpeculateNonStringCellOrOther())
- compilePeepHoleObjectToObjectOrOtherEquality(node.child1(), node.child2(), branchNodeIndex);
- else if (at(node.child1()).shouldSpeculateNonStringCellOrOther() && at(node.child2()).shouldSpeculateNonStringCell())
- compilePeepHoleObjectToObjectOrOtherEquality(node.child2(), node.child1(), branchNodeIndex);
- else if (at(node.child1()).shouldSpeculateNonStringCell() && at(node.child2()).shouldSpeculateNonStringCell())
- compilePeepHoleObjectEquality(node, branchNodeIndex);
+ if (node->isBinaryUseKind(BooleanUse))
+ compilePeepHoleBooleanBranch(node, branchNode, condition);
+ else if (node->isBinaryUseKind(ObjectUse))
+ compilePeepHoleObjectEquality(node, branchNode);
+ else if (node->child1().useKind() == ObjectUse && node->child2().useKind() == ObjectOrOtherUse)
+ compilePeepHoleObjectToObjectOrOtherEquality(node->child1(), node->child2(), branchNode);
+ else if (node->child1().useKind() == ObjectOrOtherUse && node->child2().useKind() == ObjectUse)
+ compilePeepHoleObjectToObjectOrOtherEquality(node->child2(), node->child1(), branchNode);
else {
- nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
+ nonSpeculativePeepholeBranch(node, branchNode, condition, operation);
return true;
}
} else {
- nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
+ nonSpeculativePeepholeBranch(node, branchNode, condition, operation);
return true;
}
- use(node.child1());
- use(node.child2());
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
return false;
}
-void SpeculativeJIT::noticeOSRBirth(NodeIndex nodeIndex, Node& node)
+void SpeculativeJIT::noticeOSRBirth(Node* node)
{
- if (!node.hasVirtualRegister())
+ if (!node->hasVirtualRegister())
return;
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.noticeOSRBirth(*m_stream, nodeIndex, virtualRegister);
+ info.noticeOSRBirth(*m_stream, node, virtualRegister);
}
-void SpeculativeJIT::compileMovHint(Node& node)
+void SpeculativeJIT::compileMovHint(Node* node)
{
- ASSERT(node.op() == SetLocal);
-
- m_lastSetOperand = node.local();
+ ASSERT(node->containsMovHint() && node->op() != ZombieHint);
- Node& child = at(node.child1());
- noticeOSRBirth(node.child1().index(), child);
+ m_lastSetOperand = node->local();
+
+ Node* child = node->child1().node();
+ noticeOSRBirth(child);
- if (child.op() == UInt32ToNumber)
- noticeOSRBirth(child.child1().index(), at(child.child1()));
+ if (child->op() == UInt32ToNumber)
+ noticeOSRBirth(child->child1().node());
- m_stream->appendAndLog(VariableEvent::movHint(node.child1().index(), node.local()));
+ m_stream->appendAndLog(VariableEvent::movHint(MinifiedID(child), node->local()));
+}
+
+void SpeculativeJIT::compileMovHintAndCheck(Node* node)
+{
+ compileMovHint(node);
+ speculate(node, node->child1());
+ noResult(node);
+}
+
+void SpeculativeJIT::compileInlineStart(Node* node)
+{
+ InlineCallFrame* inlineCallFrame = node->codeOrigin.inlineCallFrame;
+ int argumentCountIncludingThis = inlineCallFrame->arguments.size();
+ unsigned argumentPositionStart = node->argumentPositionStart();
+ CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
+ for (int i = 0; i < argumentCountIncludingThis; ++i) {
+ ValueRecovery recovery;
+ if (codeBlock->isCaptured(argumentToOperand(i)))
+ recovery = ValueRecovery::alreadyInJSStack();
+ else {
+ ArgumentPosition& argumentPosition =
+ m_jit.graph().m_argumentPositions[argumentPositionStart + i];
+ ValueSource valueSource;
+ if (!argumentPosition.shouldUnboxIfPossible())
+ valueSource = ValueSource(ValueInJSStack);
+ else if (argumentPosition.shouldUseDoubleFormat())
+ valueSource = ValueSource(DoubleInJSStack);
+ else if (isInt32Speculation(argumentPosition.prediction()))
+ valueSource = ValueSource(Int32InJSStack);
+ else if (isCellSpeculation(argumentPosition.prediction()))
+ valueSource = ValueSource(CellInJSStack);
+ else if (isBooleanSpeculation(argumentPosition.prediction()))
+ valueSource = ValueSource(BooleanInJSStack);
+ else
+ valueSource = ValueSource(ValueInJSStack);
+ recovery = computeValueRecoveryFor(valueSource);
+ }
+ // The recovery should refer either to something that has already been
+ // stored into the stack at the right place, or to a constant,
+ // since the Arguments code isn't smart enough to handle anything else.
+ // The exception is the this argument, which we don't really need to be
+ // able to recover.
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLogF("\nRecovery for argument %d: ", i);
+ recovery.dump(WTF::dataFile());
+#endif
+ inlineCallFrame->arguments[i] = recovery;
+ }
}
void SpeculativeJIT::compile(BasicBlock& block)
@@ -1574,21 +1694,22 @@ 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);
+ Node* node = block.variablesAtHead.local(i);
ValueSource valueSource;
- if (nodeIndex == NoNode)
+ if (!node)
valueSource = ValueSource(SourceIsDead);
- else if (at(nodeIndex).variableAccessData()->isArgumentsAlias())
+ else if (node->variableAccessData()->isArgumentsAlias())
valueSource = ValueSource(ArgumentsSource);
- else if (at(nodeIndex).variableAccessData()->isCaptured())
- valueSource = ValueSource(ValueInJSStack);
- else if (!at(nodeIndex).refCount())
+ else if (!node->refCount())
valueSource = ValueSource(SourceIsDead);
- else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat())
+ else if (!node->variableAccessData()->shouldUnboxIfPossible())
+ valueSource = ValueSource(ValueInJSStack);
+ else if (node->variableAccessData()->shouldUseDoubleFormat())
valueSource = ValueSource(DoubleInJSStack);
else
- valueSource = ValueSource::forSpeculation(at(nodeIndex).variableAccessData()->argumentAwarePrediction());
+ valueSource = ValueSource::forSpeculation(node->variableAccessData()->argumentAwarePrediction());
m_variables[i] = valueSource;
+ // FIXME: Don't emit SetLocal(Dead). https://bugs.webkit.org/show_bug.cgi?id=108019
m_stream->appendAndLog(VariableEvent::setLocal(i, valueSource.dataFormat()));
}
@@ -1607,101 +1728,86 @@ void SpeculativeJIT::compile(BasicBlock& block)
#endif
for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
- m_compileIndex = block[m_indexInBlock];
- m_jit.setForNode(m_compileIndex);
- Node& node = at(m_compileIndex);
- m_codeOriginForOSR = node.codeOrigin;
- if (!node.shouldGenerate()) {
+ m_currentNode = block[m_indexInBlock];
+#if !ASSERT_DISABLED
+ m_canExit = m_currentNode->canExit();
+#endif
+ bool shouldExecuteEffects = m_state.startExecuting(m_currentNode);
+ m_jit.setForNode(m_currentNode);
+ m_codeOriginForOSR = m_currentNode->codeOrigin;
+ if (!m_currentNode->shouldGenerate()) {
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
+ dataLogF("SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x ", m_currentNode->index(), m_currentNode->codeOrigin.bytecodeIndex, m_jit.debugOffset());
#endif
- switch (node.op()) {
+ switch (m_currentNode->op()) {
case JSConstant:
- m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
+ m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
break;
case WeakJSConstant:
- m_jit.addWeakReference(node.weakConstant());
- m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
+ m_jit.addWeakReference(m_currentNode->weakConstant());
+ m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
break;
case SetLocal:
- compileMovHint(node);
+ RELEASE_ASSERT_NOT_REACHED();
break;
-
- case InlineStart: {
- InlineCallFrame* inlineCallFrame = node.codeOrigin.inlineCallFrame;
- int argumentCountIncludingThis = inlineCallFrame->arguments.size();
- unsigned argumentPositionStart = node.argumentPositionStart();
- CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
- for (int i = 0; i < argumentCountIncludingThis; ++i) {
- ValueRecovery recovery;
- if (codeBlock->isCaptured(argumentToOperand(i)))
- recovery = ValueRecovery::alreadyInJSStack();
- else {
- ArgumentPosition& argumentPosition =
- m_jit.graph().m_argumentPositions[argumentPositionStart + i];
- ValueSource valueSource;
- if (argumentPosition.shouldUseDoubleFormat())
- valueSource = ValueSource(DoubleInJSStack);
- else if (isInt32Speculation(argumentPosition.prediction()))
- valueSource = ValueSource(Int32InJSStack);
- else if (isCellSpeculation(argumentPosition.prediction()))
- valueSource = ValueSource(CellInJSStack);
- else if (isBooleanSpeculation(argumentPosition.prediction()))
- valueSource = ValueSource(BooleanInJSStack);
- else
- valueSource = ValueSource(ValueInJSStack);
- recovery = computeValueRecoveryFor(valueSource);
- }
- // The recovery should refer either to something that has already been
- // stored into the stack at the right place, or to a constant,
- // since the Arguments code isn't smart enough to handle anything else.
- // The exception is the this argument, which we don't really need to be
- // able to recover.
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("\nRecovery for argument %d: ", i);
- recovery.dump(WTF::dataFile());
-#endif
- inlineCallFrame->arguments[i] = recovery;
- }
+
+ case MovHint:
+ compileMovHint(m_currentNode);
break;
- }
+ case ZombieHint: {
+ m_lastSetOperand = m_currentNode->local();
+ m_stream->appendAndLog(VariableEvent::setLocal(m_currentNode->local(), DataFormatDead));
+ break;
+ }
+
default:
- if (belongsInMinifiedGraph(node.op()))
- m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
+ if (belongsInMinifiedGraph(m_currentNode->op()))
+ m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
break;
}
} else {
+ if (verboseCompilationEnabled()) {
+ dataLogF(
+ "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x",
+ (int)m_currentNode->index(),
+ m_currentNode->codeOrigin.bytecodeIndex, m_jit.debugOffset());
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
+ dataLog(" ");
+#else
+ dataLog("\n");
#endif
+ }
#if DFG_ENABLE(JIT_BREAK_ON_EVERY_NODE)
m_jit.breakpoint();
#endif
#if DFG_ENABLE(XOR_DEBUG_AID)
- m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
- m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
+ m_jit.xorPtr(JITCompiler::TrustedImm32(m_currentNode->index()), GPRInfo::regT0);
+ m_jit.xorPtr(JITCompiler::TrustedImm32(m_currentNode->index()), GPRInfo::regT0);
#endif
checkConsistency();
- compile(node);
+
+ m_speculationDirection = (m_currentNode->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
+
+ compile(m_currentNode);
if (!m_compileOkay) {
m_compileOkay = true;
clearGenerationInfo();
return;
}
- if (belongsInMinifiedGraph(node.op())) {
- m_minifiedGraph->append(MinifiedNode::fromNode(m_compileIndex, node));
- noticeOSRBirth(m_compileIndex, node);
+ if (belongsInMinifiedGraph(m_currentNode->op())) {
+ m_minifiedGraph->append(MinifiedNode::fromNode(m_currentNode));
+ noticeOSRBirth(m_currentNode);
}
#if DFG_ENABLE(DEBUG_VERBOSE)
- if (node.hasResult()) {
- GenerationInfo& info = m_generationInfo[node.virtualRegister()];
- dataLogF("-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)node.virtualRegister());
+ if (m_currentNode->hasResult()) {
+ GenerationInfo& info = m_generationInfo[m_currentNode->virtualRegister()];
+ dataLogF("-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)m_currentNode->virtualRegister());
if (info.registerFormat() != DataFormatNone) {
if (info.registerFormat() == DataFormatDouble)
dataLogF(", %s", FPRInfo::debugName(info.fpr()));
@@ -1723,9 +1829,10 @@ void SpeculativeJIT::compile(BasicBlock& block)
#endif
// Make sure that the abstract state is rematerialized for the next node.
- m_state.execute(m_indexInBlock);
+ if (shouldExecuteEffects)
+ m_state.executeEffects(m_indexInBlock);
- if (node.shouldGenerate())
+ if (m_currentNode->shouldGenerate())
checkConsistency();
}
@@ -1742,8 +1849,9 @@ void SpeculativeJIT::compile(BasicBlock& block)
// we need to check that they are correct on function entry.
void SpeculativeJIT::checkArgumentTypes()
{
- ASSERT(!m_compileIndex);
+ ASSERT(!m_currentNode);
m_isCheckingArgumentTypes = true;
+ m_speculationDirection = BackwardSpeculation;
m_codeOriginForOSR = CodeOrigin(0);
for (size_t i = 0; i < m_arguments.size(); ++i)
@@ -1752,15 +1860,17 @@ void SpeculativeJIT::checkArgumentTypes()
m_variables[i] = ValueSource(ValueInJSStack);
for (int i = 0; i < m_jit.codeBlock()->numParameters(); ++i) {
- NodeIndex nodeIndex = m_jit.graph().m_arguments[i];
- Node& node = at(nodeIndex);
- ASSERT(node.op() == SetArgument);
- if (!node.shouldGenerate()) {
+ Node* node = m_jit.graph().m_arguments[i];
+ ASSERT(node->op() == SetArgument);
+ if (!node->shouldGenerate()) {
// The argument is dead. We don't do any checks for such arguments.
continue;
}
- VariableAccessData* variableAccessData = node.variableAccessData();
+ VariableAccessData* variableAccessData = node->variableAccessData();
+ if (!variableAccessData->isProfitableToUnbox())
+ continue;
+
VirtualRegister virtualRegister = variableAccessData->local();
SpeculatedType predictedType = variableAccessData->prediction();
@@ -1768,21 +1878,21 @@ void SpeculativeJIT::checkArgumentTypes()
#if USE(JSVALUE64)
if (isInt32Speculation(predictedType))
- speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch64(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
+ speculationCheck(BadType, valueSource, node, m_jit.branch64(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
else if (isBooleanSpeculation(predictedType)) {
GPRTemporary temp(this);
m_jit.load64(JITCompiler::addressFor(virtualRegister), temp.gpr());
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), temp.gpr());
- speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
+ speculationCheck(BadType, valueSource, node, m_jit.branchTest64(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
} else if (isCellSpeculation(predictedType))
- speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, JITCompiler::addressFor(virtualRegister), GPRInfo::tagMaskRegister));
+ speculationCheck(BadType, valueSource, node, m_jit.branchTest64(MacroAssembler::NonZero, JITCompiler::addressFor(virtualRegister), GPRInfo::tagMaskRegister));
#else
if (isInt32Speculation(predictedType))
- speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
+ speculationCheck(BadType, valueSource, node, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
else if (isBooleanSpeculation(predictedType))
- speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
+ speculationCheck(BadType, valueSource, node, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
else if (isCellSpeculation(predictedType))
- speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)));
+ speculationCheck(BadType, valueSource, node, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)));
#endif
}
m_isCheckingArgumentTypes = false;
@@ -1795,7 +1905,7 @@ bool SpeculativeJIT::compile()
if (DFG_ENABLE_EDGE_CODE_VERIFICATION)
m_jit.move(TrustedImm32(0), GPRInfo::regT0);
- ASSERT(!m_compileIndex);
+ ASSERT(!m_currentNode);
for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
m_jit.setForBlock(m_block);
BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
@@ -1850,18 +1960,19 @@ ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSo
return valueSource.valueRecovery();
ASSERT(valueSource.kind() == HaveNode);
- if (isConstant(valueSource.nodeIndex()))
- return ValueRecovery::constant(valueOfJSConstant(valueSource.nodeIndex()));
+ Node* node = valueSource.id().node(m_jit.graph());
+ if (isConstant(node))
+ return ValueRecovery::constant(valueOfJSConstant(node));
return ValueRecovery();
}
-void SpeculativeJIT::compileDoublePutByVal(Node& node, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property)
+void SpeculativeJIT::compileDoublePutByVal(Node* node, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property)
{
Edge child3 = m_jit.graph().varArgChild(node, 2);
Edge child4 = m_jit.graph().varArgChild(node, 3);
- ArrayMode arrayMode = node.arrayMode();
+ ArrayMode arrayMode = node->arrayMode();
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -1870,13 +1981,10 @@ void SpeculativeJIT::compileDoublePutByVal(Node& node, SpeculateCellOperand& bas
FPRReg valueReg = value.fpr();
- if (!isRealNumberSpeculation(m_state.forNode(child3).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(), child3, SpecRealNumber,
+ m_jit.branchDouble(
+ MacroAssembler::DoubleNotEqualOrUnordered, valueReg, valueReg));
if (!m_compileOkay)
return;
@@ -1884,32 +1992,32 @@ void SpeculativeJIT::compileDoublePutByVal(Node& node, SpeculateCellOperand& bas
StorageOperand storage(this, child4);
GPRReg storageReg = storage.gpr();
- if (node.op() == PutByValAlias) {
+ if (node->op() == PutByValAlias) {
// Store the value to the array.
GPRReg propertyReg = property.gpr();
FPRReg valueReg = value.fpr();
m_jit.storeDouble(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
- noResult(m_compileIndex);
+ noResult(m_currentNode);
return;
}
GPRTemporary temporary;
GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
- MacroAssembler::JumpList slowCases;
+ MacroAssembler::Jump slowCase;
if (arrayMode.isInBounds()) {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ StoreToHoleOrOutOfBounds, JSValueRegs(), 0,
m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
} else {
MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
+ slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
if (!arrayMode.isOutOfBounds())
- speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
@@ -1927,28 +2035,28 @@ void SpeculativeJIT::compileDoublePutByVal(Node& node, SpeculateCellOperand& bas
if (arrayMode.isOutOfBounds()) {
addSlowPathGenerator(
slowPathCall(
- slowCases, this,
+ slowCase, this,
m_jit.codeBlock()->isStrictMode() ? operationPutDoubleByValBeyondArrayBoundsStrict : operationPutDoubleByValBeyondArrayBoundsNonStrict,
NoResult, baseReg, propertyReg, valueReg));
}
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(m_currentNode, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::compileGetCharCodeAt(Node& node)
+void SpeculativeJIT::compileGetCharCodeAt(Node* node)
{
- SpeculateCellOperand string(this, node.child1());
- SpeculateStrictInt32Operand index(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand string(this, node->child1());
+ SpeculateStrictInt32Operand index(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg stringReg = string.gpr();
GPRReg indexReg = index.gpr();
GPRReg storageReg = storage.gpr();
- ASSERT(speculationChecked(m_state.forNode(node.child1()).m_type, SpecString));
+ ASSERT(speculationChecked(m_state.forNode(node->child1()).m_type, SpecString));
// unsigned comparison so we can filter out negative indices and indices that are too large
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
@@ -1967,22 +2075,22 @@ void SpeculativeJIT::compileGetCharCodeAt(Node& node)
cont8Bit.link(&m_jit);
- integerResult(scratchReg, m_compileIndex);
+ integerResult(scratchReg, m_currentNode);
}
-void SpeculativeJIT::compileGetByValOnString(Node& node)
+void SpeculativeJIT::compileGetByValOnString(Node* node)
{
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
- ASSERT(ArrayMode(Array::String).alreadyChecked(m_jit.graph(), node, m_state.forNode(node.child1())));
+ ASSERT(ArrayMode(Array::String).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
// unsigned comparison so we can filter out negative indices and indices that are too large
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
@@ -2000,51 +2108,53 @@ void SpeculativeJIT::compileGetByValOnString(Node& node)
m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
// We only support ascii characters
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
// 8 bit string values don't need the isASCII check.
cont8Bit.link(&m_jit);
GPRTemporary smallStrings(this);
GPRReg smallStringsReg = smallStrings.gpr();
- m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg);
+ m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.vm()->smallStrings.singleCharacterStrings()), smallStringsReg);
m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg);
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
- cellResult(scratchReg, m_compileIndex);
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
+ cellResult(scratchReg, m_currentNode);
}
-GeneratedOperandType SpeculativeJIT::checkGeneratedTypeForToInt32(NodeIndex nodeIndex)
+void SpeculativeJIT::compileFromCharCode(Node* node)
{
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("checkGeneratedTypeForToInt32@%d ", nodeIndex);
-#endif
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
-
- if (info.registerFormat() == DataFormatNone) {
- if (node.hasConstant()) {
- if (isInt32Constant(nodeIndex))
- return GeneratedOperandInteger;
+ SpeculateStrictInt32Operand property(this, node->child1());
+ GPRReg propertyReg = property.gpr();
+ GPRTemporary smallStrings(this);
+ GPRTemporary scratch(this);
+ GPRReg scratchReg = scratch.gpr();
+ GPRReg smallStringsReg = smallStrings.gpr();
- if (isNumberConstant(nodeIndex))
- return GeneratedOperandDouble;
+ JITCompiler::JumpList slowCases;
+ slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, TrustedImm32(0xff)));
+ m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.vm()->smallStrings.singleCharacterStrings()), smallStringsReg);
+ m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, propertyReg, MacroAssembler::ScalePtr, 0), scratchReg);
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
- return GeneratedOperandTypeUnknown;
- }
+ slowCases.append(m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
+ addSlowPathGenerator(slowPathCall(slowCases, this, operationStringFromCharCode, scratchReg, propertyReg));
+ cellResult(scratchReg, m_currentNode);
+}
- if (info.spillFormat() == DataFormatDouble)
- return GeneratedOperandDouble;
- }
+GeneratedOperandType SpeculativeJIT::checkGeneratedTypeForToInt32(Node* node)
+{
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLogF("checkGeneratedTypeForToInt32@%d ", node->index());
+#endif
+ VirtualRegister virtualRegister = node->virtualRegister();
+ GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
- case DataFormatBoolean: // This type never occurs.
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
+ case DataFormatBoolean:
case DataFormatCell:
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return GeneratedOperandTypeUnknown;
case DataFormatNone:
@@ -2062,46 +2172,48 @@ GeneratedOperandType SpeculativeJIT::checkGeneratedTypeForToInt32(NodeIndex node
return GeneratedOperandDouble;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return GeneratedOperandTypeUnknown;
}
}
-void SpeculativeJIT::compileValueToInt32(Node& node)
+void SpeculativeJIT::compileValueToInt32(Node* node)
{
- if (at(node.child1()).shouldSpeculateInteger()) {
- SpeculateIntegerOperand op1(this, node.child1());
+ switch (node->child1().useKind()) {
+ case Int32Use: {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this, op1);
m_jit.move(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex, op1.format());
+ integerResult(result.gpr(), node, op1.format());
return;
}
- if (at(node.child1()).shouldSpeculateNumber()) {
- switch (checkGeneratedTypeForToInt32(node.child1().index())) {
+ case NumberUse:
+ case NotCellUse: {
+ switch (checkGeneratedTypeForToInt32(node->child1().node())) {
case GeneratedOperandInteger: {
- SpeculateIntegerOperand op1(this, node.child1());
+ SpeculateIntegerOperand op1(this, node->child1(), ManualOperandSpeculation);
GPRTemporary result(this, op1);
m_jit.move(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex, op1.format());
+ integerResult(result.gpr(), node, op1.format());
return;
}
case GeneratedOperandDouble: {
GPRTemporary result(this);
- DoubleOperand op1(this, node.child1());
+ SpeculateDoubleOperand op1(this, node->child1(), ManualOperandSpeculation);
FPRReg fpr = op1.fpr();
GPRReg gpr = result.gpr();
JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
- integerResult(gpr, m_compileIndex);
+ integerResult(gpr, node);
return;
}
case GeneratedOperandJSValue: {
GPRTemporary result(this);
#if USE(JSVALUE64)
- JSValueOperand op1(this, node.child1());
+ JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
GPRReg gpr = op1.gpr();
GPRReg resultGpr = result.gpr();
@@ -2109,9 +2221,27 @@ void SpeculativeJIT::compileValueToInt32(Node& node)
FPRReg fpr = tempFpr.fpr();
JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
+ JITCompiler::JumpList converted;
- if (!isNumberSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueRegs(gpr), node.child1().index(), m_jit.branchTest64(MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
+ if (node->child1().useKind() == NumberUse) {
+ DFG_TYPE_CHECK(
+ JSValueRegs(gpr), node->child1(), SpecNumber,
+ m_jit.branchTest64(
+ MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
+ } else {
+ JITCompiler::Jump isNumber = m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagTypeNumberRegister);
+
+ DFG_TYPE_CHECK(
+ JSValueRegs(gpr), node->child1(), ~SpecCell,
+ m_jit.branchTest64(
+ JITCompiler::Zero, gpr, GPRInfo::tagMaskRegister));
+
+ // It's not a cell: so true turns into 1 and all else turns into 0.
+ m_jit.compare64(JITCompiler::Equal, gpr, TrustedImm32(ValueTrue), resultGpr);
+ converted.append(m_jit.jump());
+
+ isNumber.link(&m_jit);
+ }
// First, if we get here we have a double encoded as a JSValue
m_jit.move(gpr, resultGpr);
@@ -2121,21 +2251,23 @@ void SpeculativeJIT::compileValueToInt32(Node& node)
callOperation(toInt32, resultGpr, fpr);
silentFillAllRegisters(resultGpr);
- JITCompiler::Jump converted = m_jit.jump();
+ converted.append(m_jit.jump());
isInteger.link(&m_jit);
m_jit.zeroExtend32ToPtr(gpr, resultGpr);
converted.link(&m_jit);
#else
- Node& childNode = at(node.child1().index());
- VirtualRegister virtualRegister = childNode.virtualRegister();
+ Node* childNode = node->child1().node();
+ VirtualRegister virtualRegister = childNode->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
- JSValueOperand op1(this, node.child1());
+ JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
GPRReg payloadGPR = op1.payloadGPR();
GPRReg resultGpr = result.gpr();
+
+ JITCompiler::JumpList converted;
if (info.registerFormat() == DataFormatJSInteger)
m_jit.move(payloadGPR, resultGpr);
@@ -2147,8 +2279,31 @@ void SpeculativeJIT::compileValueToInt32(Node& node)
JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
- if (!isNumberSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node.child1().index(), m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
+ if (node->child1().useKind() == NumberUse) {
+ DFG_TYPE_CHECK(
+ JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecNumber,
+ m_jit.branch32(
+ MacroAssembler::AboveOrEqual, tagGPR,
+ TrustedImm32(JSValue::LowestTag)));
+ } else {
+ JITCompiler::Jump isNumber = m_jit.branch32(MacroAssembler::Below, tagGPR, TrustedImm32(JSValue::LowestTag));
+
+ DFG_TYPE_CHECK(
+ JSValueRegs(tagGPR, payloadGPR), node->child1(), ~SpecCell,
+ m_jit.branch32(
+ JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::CellTag)));
+
+ // It's not a cell: so true turns into 1 and all else turns into 0.
+ JITCompiler::Jump isBoolean = m_jit.branch32(JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::BooleanTag));
+ m_jit.move(TrustedImm32(0), resultGpr);
+ converted.append(m_jit.jump());
+
+ isBoolean.link(&m_jit);
+ m_jit.move(payloadGPR, resultGpr);
+ converted.append(m_jit.jump());
+
+ isNumber.link(&m_jit);
+ }
unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
@@ -2156,7 +2311,7 @@ void SpeculativeJIT::compileValueToInt32(Node& node)
callOperation(toInt32, resultGpr, fpr);
silentFillAllRegisters(resultGpr);
- JITCompiler::Jump converted = m_jit.jump();
+ converted.append(m_jit.jump());
isInteger.link(&m_jit);
m_jit.move(payloadGPR, resultGpr);
@@ -2164,38 +2319,41 @@ void SpeculativeJIT::compileValueToInt32(Node& node)
converted.link(&m_jit);
}
#endif
- integerResult(resultGpr, m_compileIndex);
+ integerResult(resultGpr, node);
return;
}
case GeneratedOperandTypeUnknown:
- ASSERT_NOT_REACHED();
- break;
+ RELEASE_ASSERT(!m_compileOkay);
+ return;
}
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
}
- if (at(node.child1()).shouldSpeculateBoolean()) {
- SpeculateBooleanOperand op1(this, node.child1());
+ case BooleanUse: {
+ SpeculateBooleanOperand op1(this, node->child1());
GPRTemporary result(this, op1);
m_jit.move(op1.gpr(), result.gpr());
m_jit.and32(JITCompiler::TrustedImm32(1), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
+ return;
+ }
+
+ default:
+ ASSERT(!m_compileOkay);
return;
}
-
- // Do it the safe way.
- nonSpeculativeValueToInt32(node);
- return;
}
-void SpeculativeJIT::compileUInt32ToNumber(Node& node)
+void SpeculativeJIT::compileUInt32ToNumber(Node* node)
{
- if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
+ if (!nodeCanSpeculateInteger(node->arithNodeFlags())) {
// We know that this sometimes produces doubles. So produce a double every
// time. This at least allows subsequent code to not have weird conditionals.
- IntegerOperand op1(this, node.child1());
+ IntegerOperand op1(this, node->child1());
FPRTemporary result(this);
GPRReg inputGPR = op1.gpr();
@@ -2207,11 +2365,11 @@ void SpeculativeJIT::compileUInt32ToNumber(Node& node)
m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), outputFPR);
positive.link(&m_jit);
- doubleResult(outputFPR, m_compileIndex);
+ doubleResult(outputFPR, node);
return;
}
- IntegerOperand op1(this, node.child1());
+ IntegerOperand op1(this, node->child1());
GPRTemporary result(this); // For the benefit of OSR exit, force these to be in different registers. In reality the OSR exit compiler could find cases where you have uint32(%r1) followed by int32(%r1) and then use different registers, but that seems like too much effort.
m_jit.move(op1.gpr(), result.gpr());
@@ -2221,14 +2379,14 @@ void SpeculativeJIT::compileUInt32ToNumber(Node& node)
// instruction that follows us, rather than the one we're executing right now. We have
// to do this because by this point, the original values necessary to compile whatever
// operation the UInt32ToNumber originated from might be dead.
- forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, result.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(result.gpr()));
+ forwardSpeculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, result.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(result.gpr()));
- integerResult(result.gpr(), m_compileIndex, op1.format());
+ integerResult(result.gpr(), node, op1.format());
}
-void SpeculativeJIT::compileDoubleAsInt32(Node& node)
+void SpeculativeJIT::compileDoubleAsInt32(Node* node)
{
- SpeculateDoubleOperand op1(this, node.child1());
+ SpeculateDoubleOperand op1(this, node->child1());
FPRTemporary scratch(this);
GPRTemporary result(this);
@@ -2237,38 +2395,26 @@ void SpeculativeJIT::compileDoubleAsInt32(Node& node)
GPRReg resultGPR = result.gpr();
JITCompiler::JumpList failureCases;
- m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR);
- forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, failureCases, ValueRecovery::inFPR(valueFPR));
+ bool negZeroCheck = !nodeCanIgnoreNegativeZero(node->arithNodeFlags());
+ m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR, negZeroCheck);
+ forwardSpeculationCheck(Overflow, JSValueRegs(), 0, failureCases, ValueRecovery::inFPR(valueFPR));
- integerResult(resultGPR, m_compileIndex);
+ integerResult(resultGPR, node);
}
-void SpeculativeJIT::compileInt32ToDouble(Node& node)
+void SpeculativeJIT::compileInt32ToDouble(Node* node)
{
-#if USE(JSVALUE64)
- // On JSVALUE64 we have a way of loading double constants in a more direct manner
- // than a int->double conversion. On 32_64, unfortunately, we currently don't have
- // any such mechanism - though we could have it, if we just provisioned some memory
- // in CodeBlock for the double form of integer constants.
- if (isInt32Constant(node.child1().index())) {
- FPRTemporary result(this);
- GPRTemporary temp(this);
- m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(node.child1().index()))), temp.gpr());
- m_jit.move64ToDouble(temp.gpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
- return;
- }
-#endif
+ ASSERT(!isInt32Constant(node->child1().node())); // This should have been constant folded.
- if (isInt32Speculation(m_state.forNode(node.child1()).m_type)) {
- SpeculateIntegerOperand op1(this, node.child1());
+ if (isInt32Speculation(m_state.forNode(node->child1()).m_type)) {
+ SpeculateIntegerOperand op1(this, node->child1(), ManualOperandSpeculation);
FPRTemporary result(this);
m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(result.fpr(), node);
return;
}
- JSValueOperand op1(this, node.child1());
+ JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
FPRTemporary result(this);
#if USE(JSVALUE64)
@@ -2281,10 +2427,17 @@ void SpeculativeJIT::compileInt32ToDouble(Node& node)
JITCompiler::Jump isInteger = m_jit.branch64(
MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
- if (!isNumberSpeculation(m_state.forNode(node.child1()).m_type)) {
- speculationCheck(
- BadType, JSValueRegs(op1GPR), node.child1(),
- m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
+ if (needsTypeCheck(node->child1(), SpecNumber)) {
+ if (node->op() == ForwardInt32ToDouble) {
+ forwardTypeCheck(
+ JSValueRegs(op1GPR), node->child1(), SpecNumber,
+ m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister),
+ ValueRecovery::inGPR(op1GPR, DataFormatJS));
+ } else {
+ backwardTypeCheck(
+ JSValueRegs(op1GPR), node->child1(), SpecNumber,
+ m_jit.branchTest64(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
+ }
}
m_jit.move(op1GPR, tempGPR);
@@ -2305,10 +2458,17 @@ void SpeculativeJIT::compileInt32ToDouble(Node& node)
JITCompiler::Jump isInteger = m_jit.branch32(
MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
- if (!isNumberSpeculation(m_state.forNode(node.child1()).m_type)) {
- speculationCheck(
- BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node.child1(),
- m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
+ if (needsTypeCheck(node->child1(), SpecNumber)) {
+ if (node->op() == ForwardInt32ToDouble) {
+ forwardTypeCheck(
+ JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber,
+ m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)),
+ ValueRecovery::inPair(op1TagGPR, op1PayloadGPR));
+ } else {
+ backwardTypeCheck(
+ JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecNumber,
+ m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
+ }
}
unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
@@ -2319,7 +2479,7 @@ void SpeculativeJIT::compileInt32ToDouble(Node& node)
done.link(&m_jit);
#endif
- doubleResult(resultFPR, m_compileIndex);
+ doubleResult(resultFPR, node);
}
static double clampDoubleToByte(double d)
@@ -2374,11 +2534,11 @@ static void compileClampDoubleToByte(JITCompiler& jit, GPRReg result, FPRReg sou
}
-void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySignedness signedness)
+void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node* node, size_t elementSize, TypedArraySignedness signedness)
{
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2387,10 +2547,10 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor&
GPRTemporary result(this);
GPRReg resultReg = result.gpr();
- ASSERT(node.arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node.child1())));
+ ASSERT(node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset)));
switch (elementSize) {
@@ -2413,14 +2573,14 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor&
CRASH();
}
if (elementSize < 4 || signedness == SignedTypedArray) {
- integerResult(resultReg, m_compileIndex);
+ integerResult(resultReg, node);
return;
}
ASSERT(elementSize == 4 && signedness == UnsignedTypedArray);
- if (node.shouldSpeculateInteger()) {
- forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultReg, TrustedImm32(0)), ValueRecovery::uint32InGPR(resultReg));
- integerResult(resultReg, m_compileIndex);
+ if (node->shouldSpeculateInteger()) {
+ forwardSpeculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, resultReg, TrustedImm32(0)), ValueRecovery::uint32InGPR(resultReg));
+ integerResult(resultReg, node);
return;
}
@@ -2429,10 +2589,10 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor&
JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, resultReg, TrustedImm32(0));
m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), fresult.fpr());
positive.link(&m_jit);
- doubleResult(fresult.fpr(), m_compileIndex);
+ doubleResult(fresult.fpr(), node);
}
-void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySignedness signedness, TypedArrayRounding rounding)
+void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node* node, size_t elementSize, TypedArraySignedness signedness, TypedArrayRounding rounding)
{
StorageOperand storage(this, m_jit.graph().varArgChild(node, 3));
GPRReg storageReg = storage.gpr();
@@ -2440,13 +2600,13 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
Edge valueUse = m_jit.graph().varArgChild(node, 2);
GPRTemporary value;
- GPRReg valueGPR;
+ GPRReg valueGPR = InvalidGPRReg;
- if (at(valueUse).isConstant()) {
- JSValue jsValue = valueOfJSConstant(valueUse.index());
+ if (valueUse->isConstant()) {
+ JSValue jsValue = valueOfJSConstant(valueUse.node());
if (!jsValue.isNumber()) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
- noResult(m_compileIndex);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ noResult(node);
return;
}
double d = jsValue.asNumber();
@@ -2459,54 +2619,69 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
m_jit.move(Imm32(toInt32(d)), scratchReg);
value.adopt(scratch);
valueGPR = scratchReg;
- } else if (at(valueUse).shouldSpeculateInteger()) {
- SpeculateIntegerOperand valueOp(this, valueUse);
- GPRTemporary scratch(this);
- GPRReg scratchReg = scratch.gpr();
- m_jit.move(valueOp.gpr(), scratchReg);
- if (rounding == ClampRounding) {
- ASSERT(elementSize == 1);
- compileClampIntegerToByte(m_jit, scratchReg);
- }
- value.adopt(scratch);
- valueGPR = scratchReg;
- } else if (rounding == ClampRounding) {
- ASSERT(elementSize == 1);
- SpeculateDoubleOperand valueOp(this, valueUse);
- GPRTemporary result(this);
- FPRTemporary floatScratch(this);
- FPRReg fpr = valueOp.fpr();
- GPRReg gpr = result.gpr();
- compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
- value.adopt(result);
- valueGPR = gpr;
} else {
- SpeculateDoubleOperand valueOp(this, valueUse);
- GPRTemporary result(this);
- FPRReg fpr = valueOp.fpr();
- GPRReg gpr = result.gpr();
- MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
- m_jit.xorPtr(gpr, gpr);
- MacroAssembler::Jump fixed = m_jit.jump();
- notNaN.link(&m_jit);
-
- MacroAssembler::Jump failed;
- if (signedness == SignedTypedArray)
- failed = m_jit.branchTruncateDoubleToInt32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
- else
- failed = m_jit.branchTruncateDoubleToUint32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
-
- addSlowPathGenerator(slowPathCall(failed, this, toInt32, gpr, fpr));
-
- fixed.link(&m_jit);
- value.adopt(result);
- valueGPR = gpr;
+ switch (valueUse.useKind()) {
+ case Int32Use: {
+ SpeculateIntegerOperand valueOp(this, valueUse);
+ GPRTemporary scratch(this);
+ GPRReg scratchReg = scratch.gpr();
+ m_jit.move(valueOp.gpr(), scratchReg);
+ if (rounding == ClampRounding) {
+ ASSERT(elementSize == 1);
+ compileClampIntegerToByte(m_jit, scratchReg);
+ }
+ value.adopt(scratch);
+ valueGPR = scratchReg;
+ break;
+ }
+
+ case NumberUse: {
+ if (rounding == ClampRounding) {
+ ASSERT(elementSize == 1);
+ SpeculateDoubleOperand valueOp(this, valueUse);
+ GPRTemporary result(this);
+ FPRTemporary floatScratch(this);
+ FPRReg fpr = valueOp.fpr();
+ GPRReg gpr = result.gpr();
+ compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
+ value.adopt(result);
+ valueGPR = gpr;
+ } else {
+ SpeculateDoubleOperand valueOp(this, valueUse);
+ GPRTemporary result(this);
+ FPRReg fpr = valueOp.fpr();
+ GPRReg gpr = result.gpr();
+ MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
+ m_jit.xorPtr(gpr, gpr);
+ MacroAssembler::Jump fixed = m_jit.jump();
+ notNaN.link(&m_jit);
+
+ MacroAssembler::Jump failed;
+ if (signedness == SignedTypedArray)
+ failed = m_jit.branchTruncateDoubleToInt32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
+ else
+ failed = m_jit.branchTruncateDoubleToUint32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
+
+ addSlowPathGenerator(slowPathCall(failed, this, toInt32, gpr, fpr));
+
+ fixed.link(&m_jit);
+ value.adopt(result);
+ valueGPR = gpr;
+ }
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
}
+
ASSERT_UNUSED(valueGPR, valueGPR != property);
ASSERT(valueGPR != base);
ASSERT(valueGPR != storageReg);
MacroAssembler::Jump outOfBounds;
- if (node.op() == PutByVal)
+ if (node->op() == PutByVal)
outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
switch (elementSize) {
@@ -2522,27 +2697,27 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor&
default:
CRASH();
}
- if (node.op() == PutByVal)
+ if (node->op() == PutByVal)
outOfBounds.link(&m_jit);
- noResult(m_compileIndex);
+ noResult(node);
}
-void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize)
+void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node* node, size_t elementSize)
{
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
- ASSERT(node.arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node.child1())));
+ ASSERT(node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
FPRTemporary result(this);
FPRReg resultReg = result.fpr();
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset)));
switch (elementSize) {
@@ -2552,60 +2727,62 @@ void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor
break;
case 8: {
m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
- MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
- static const double NaN = QNaN;
- m_jit.loadDouble(&NaN, resultReg);
- notNaN.link(&m_jit);
break;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
- doubleResult(resultReg, m_compileIndex);
+
+ MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
+ static const double NaN = QNaN;
+ m_jit.loadDouble(&NaN, resultReg);
+ notNaN.link(&m_jit);
+
+ doubleResult(resultReg, node);
}
-void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize)
+void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node* node, size_t elementSize)
{
StorageOperand storage(this, m_jit.graph().varArgChild(node, 3));
GPRReg storageReg = storage.gpr();
Edge baseUse = m_jit.graph().varArgChild(node, 0);
Edge valueUse = m_jit.graph().varArgChild(node, 2);
-
+
SpeculateDoubleOperand valueOp(this, valueUse);
-
- ASSERT_UNUSED(baseUse, node.arrayMode().alreadyChecked(m_jit.graph(), m_jit.graph()[m_compileIndex], m_state.forNode(baseUse)));
-
- GPRTemporary result(this);
+ FPRTemporary scratch(this);
+ FPRReg valueFPR = valueOp.fpr();
+ FPRReg scratchFPR = scratch.fpr();
+
+ ASSERT_UNUSED(baseUse, node->arrayMode().alreadyChecked(m_jit.graph(), node, m_state.forNode(baseUse)));
MacroAssembler::Jump outOfBounds;
- if (node.op() == PutByVal)
+ if (node->op() == PutByVal)
outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
switch (elementSize) {
case 4: {
- FPRTemporary scratch(this);
- m_jit.moveDouble(valueOp.fpr(), scratch.fpr());
- m_jit.convertDoubleToFloat(valueOp.fpr(), scratch.fpr());
- m_jit.storeFloat(scratch.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
+ m_jit.moveDouble(valueFPR, scratchFPR);
+ m_jit.convertDoubleToFloat(valueFPR, scratchFPR);
+ m_jit.storeFloat(scratchFPR, MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
break;
}
case 8:
- m_jit.storeDouble(valueOp.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesEight));
+ m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesEight));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
- if (node.op() == PutByVal)
+ if (node->op() == PutByVal)
outOfBounds.link(&m_jit);
- noResult(m_compileIndex);
+ noResult(node);
}
-void SpeculativeJIT::compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg)
+void SpeculativeJIT::compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg)
{
// Check that prototype is an object.
m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
- speculationCheck(BadType, JSValueRegs(), NoNode, m_jit.branchIfNotObject(scratchReg));
+ speculationCheck(BadType, JSValueRegs(), 0, m_jit.branchIfNotObject(scratchReg));
// Initialize scratchReg with the value being checked.
m_jit.move(valueReg, scratchReg);
@@ -2641,17 +2818,15 @@ void SpeculativeJIT::compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg p
putResult.link(&m_jit);
}
-void SpeculativeJIT::compileInstanceOf(Node& node)
+void SpeculativeJIT::compileInstanceOf(Node* node)
{
- if ((!!(at(node.child1()).prediction() & ~SpecCell)
- && !!(m_state.forNode(node.child1()).m_type & ~SpecCell))
- || at(node.child1()).adjustedRefCount() == 1) {
+ if (node->child1().useKind() == UntypedUse) {
// It might not be a cell. Speculate less aggressively.
// Or: it might only be used once (i.e. by us), so we get zero benefit
// from speculating any more aggressively than we absolutely need to.
- JSValueOperand value(this, node.child1());
- SpeculateCellOperand prototype(this, node.child2());
+ JSValueOperand value(this, node->child1());
+ SpeculateCellOperand prototype(this, node->child2());
GPRTemporary scratch(this);
GPRReg prototypeReg = prototype.gpr();
@@ -2677,15 +2852,15 @@ void SpeculativeJIT::compileInstanceOf(Node& node)
done.link(&m_jit);
#if USE(JSVALUE64)
- jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(scratchReg, node, DataFormatJSBoolean);
#else
- booleanResult(scratchReg, m_compileIndex);
+ booleanResult(scratchReg, node);
#endif
return;
}
- SpeculateCellOperand value(this, node.child1());
- SpeculateCellOperand prototype(this, node.child2());
+ SpeculateCellOperand value(this, node->child1());
+ SpeculateCellOperand prototype(this, node->child2());
GPRTemporary scratch(this);
@@ -2696,20 +2871,20 @@ void SpeculativeJIT::compileInstanceOf(Node& node)
compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
#if USE(JSVALUE64)
- jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(scratchReg, node, DataFormatJSBoolean);
#else
- booleanResult(scratchReg, m_compileIndex);
+ booleanResult(scratchReg, node);
#endif
}
-void SpeculativeJIT::compileSoftModulo(Node& node)
+void SpeculativeJIT::compileSoftModulo(Node* node)
{
// In the fast path, the dividend value could be the final result
// (in case of |dividend| < |divisor|), so we speculate it as strict int32.
- SpeculateStrictInt32Operand op1(this, node.child1());
+ SpeculateStrictInt32Operand op1(this, node->child1());
#if CPU(X86) || CPU(X86_64)
- if (isInt32Constant(node.child2().index())) {
- int32_t divisor = valueOfInt32Constant(node.child2().index());
+ if (isInt32Constant(node->child2().node())) {
+ int32_t divisor = valueOfInt32Constant(node->child2().node());
if (divisor) {
GPRReg op1Gpr = op1.gpr();
@@ -2731,25 +2906,51 @@ void SpeculativeJIT::compileSoftModulo(Node& node)
m_jit.move(op1Gpr, eax.gpr());
m_jit.move(TrustedImm32(divisor), scratchGPR);
if (divisor == -1)
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1)));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1)));
m_jit.assembler().cdq();
m_jit.assembler().idivl_r(scratchGPR);
- // Check that we're not about to create negative zero.
- // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
- numeratorPositive.link(&m_jit);
-
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ // Check that we're not about to create negative zero.
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
+ numeratorPositive.link(&m_jit);
+ }
if (op1SaveGPR != op1Gpr)
unlock(op1SaveGPR);
- integerResult(edx.gpr(), m_compileIndex);
+ integerResult(edx.gpr(), node);
+ return;
+ }
+ }
+#elif CPU(APPLE_ARMV7S) || CPU(ARM_THUMB2)
+ if (isInt32Constant(node->child2().node())) {
+ int32_t divisor = valueOfInt32Constant(node->child2().node());
+ if (divisor > 0 && hasOneBitSet(divisor)) { // If power of 2 then just mask
+ GPRReg dividendGPR = op1.gpr();
+ GPRTemporary result(this);
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.assembler().cmp(dividendGPR, ARMThumbImmediate::makeEncodedImm(0));
+ m_jit.assembler().it(ARMv7Assembler::ConditionLT, false);
+ m_jit.assembler().neg(resultGPR, dividendGPR);
+ m_jit.assembler().mov(resultGPR, dividendGPR);
+ m_jit.and32(TrustedImm32(divisor - 1), resultGPR);
+ m_jit.assembler().it(ARMv7Assembler::ConditionLT);
+ m_jit.assembler().neg(resultGPR, resultGPR);
+
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ // Check that we're not about to create negative zero.
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR));
+ numeratorPositive.link(&m_jit);
+ }
+ integerResult(resultGPR, node);
return;
}
}
#endif
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op2(this, node->child2());
#if CPU(X86) || CPU(X86_64)
GPRTemporary eax(this, X86Registers::eax);
GPRTemporary edx(this, X86Registers::edx);
@@ -2789,8 +2990,8 @@ void SpeculativeJIT::compileSoftModulo(Node& node)
JITCompiler::Jump done;
// FIXME: if the node is not used as number then we can do this more easily.
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
safeDenominator.link(&m_jit);
@@ -2806,17 +3007,42 @@ void SpeculativeJIT::compileSoftModulo(Node& node)
if (op2TempGPR != InvalidGPRReg)
unlock(op2TempGPR);
- // Check that we're not about to create negative zero.
- // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
- JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
- numeratorPositive.link(&m_jit);
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ // Check that we're not about to create negative zero.
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
+ numeratorPositive.link(&m_jit);
+ }
if (op1SaveGPR != op1GPR)
unlock(op1SaveGPR);
- integerResult(edx.gpr(), m_compileIndex);
-#else // CPU(X86) || CPU(X86_64) --> so not X86
+ integerResult(edx.gpr(), node);
+
+#elif CPU(APPLE_ARMV7S)
+ GPRTemporary temp(this);
+ GPRTemporary quotientThenRemainder(this);
+ GPRTemporary multiplyAnswer(this);
+ GPRReg dividendGPR = op1.gpr();
+ GPRReg divisorGPR = op2.gpr();
+ GPRReg quotientThenRemainderGPR = quotientThenRemainder.gpr();
+ GPRReg multiplyAnswerGPR = multiplyAnswer.gpr();
+
+ m_jit.assembler().sdiv(quotientThenRemainderGPR, dividendGPR, divisorGPR);
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR));
+ m_jit.assembler().sub(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR);
+
+ // If the user cares about negative zero, then speculate that we're not about
+ // to produce negative zero.
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ // Check that we're not about to create negative zero.
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));
+ numeratorPositive.link(&m_jit);
+ }
+
+ integerResult(quotientThenRemainderGPR, node);
+#else // not architecture that can do integer division
// Do this the *safest* way possible: call out to a C function that will do the modulo,
// and then attempt to convert back.
GPRReg op1GPR = op1.gpr();
@@ -2830,55 +3056,62 @@ void SpeculativeJIT::compileSoftModulo(Node& node)
FPRTemporary scratch(this);
GPRTemporary intResult(this);
JITCompiler::JumpList failureCases;
- m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr());
- speculationCheck(Overflow, JSValueRegs(), NoNode, failureCases);
+ m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr(), false);
+ speculationCheck(Overflow, JSValueRegs(), 0, failureCases);
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ // Check that we're not about to create negative zero.
+ JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1GPR, TrustedImm32(0));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, intResult.gpr()));
+ numeratorPositive.link(&m_jit);
+ }
- integerResult(intResult.gpr(), m_compileIndex);
+ integerResult(intResult.gpr(), node);
#endif // CPU(X86) || CPU(X86_64)
}
-void SpeculativeJIT::compileAdd(Node& node)
+void SpeculativeJIT::compileAdd(Node* node)
{
- if (m_jit.graph().addShouldSpeculateInteger(node)) {
- if (isNumberConstant(node.child1().index())) {
- int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
- SpeculateIntegerOperand op2(this, node.child2());
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
+ if (isNumberConstant(node->child1().node())) {
+ int32_t imm1 = valueOfInt32Constant(node->child1().node());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this);
- if (nodeCanTruncateInteger(node.arithNodeFlags())) {
+ if (nodeCanTruncateInteger(node->arithNodeFlags())) {
m_jit.move(op2.gpr(), result.gpr());
m_jit.add32(Imm32(imm1), result.gpr());
} else
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
- if (isNumberConstant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
- int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
+ if (isNumberConstant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
+ int32_t imm2 = valueOfInt32Constant(node->child2().node());
GPRTemporary result(this);
- if (nodeCanTruncateInteger(node.arithNodeFlags())) {
+ if (nodeCanTruncateInteger(node->arithNodeFlags())) {
m_jit.move(op1.gpr(), result.gpr());
m_jit.add32(Imm32(imm2), result.gpr());
} else
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op1, op2);
GPRReg gpr1 = op1.gpr();
GPRReg gpr2 = op2.gpr();
GPRReg gprResult = result.gpr();
- if (nodeCanTruncateInteger(node.arithNodeFlags())) {
+ if (nodeCanTruncateInteger(node->arithNodeFlags())) {
if (gpr1 == gprResult)
m_jit.add32(gpr2, gprResult);
else {
@@ -2889,136 +3122,237 @@ void SpeculativeJIT::compileAdd(Node& node)
MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
if (gpr1 == gprResult)
- speculationCheck(Overflow, JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
+ speculationCheck(Overflow, JSValueRegs(), 0, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
else if (gpr2 == gprResult)
- speculationCheck(Overflow, JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
+ speculationCheck(Overflow, JSValueRegs(), 0, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
else
- speculationCheck(Overflow, JSValueRegs(), NoNode, check);
+ speculationCheck(Overflow, JSValueRegs(), 0, check);
}
- integerResult(gprResult, m_compileIndex);
+ integerResult(gprResult, node);
return;
}
-
- if (Node::shouldSpeculateNumberExpectingDefined(at(node.child1()), at(node.child2()))) {
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
+
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
FPRTemporary result(this, op1, op2);
FPRReg reg1 = op1.fpr();
FPRReg reg2 = op2.fpr();
m_jit.addDouble(reg1, reg2, result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(result.fpr(), node);
return;
}
-
- if (node.op() == ValueAdd) {
+
+ case UntypedUse: {
+ RELEASE_ASSERT(node->op() == ValueAdd);
compileValueAdd(node);
return;
}
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void SpeculativeJIT::compileMakeRope(Node* node)
+{
+ ASSERT(node->child1().useKind() == KnownStringUse);
+ ASSERT(node->child2().useKind() == KnownStringUse);
+ ASSERT(!node->child3() || node->child3().useKind() == KnownStringUse);
+
+ SpeculateCellOperand op1(this, node->child1());
+ SpeculateCellOperand op2(this, node->child2());
+ SpeculateCellOperand op3(this, node->child3());
+ GPRTemporary result(this);
+ GPRTemporary allocator(this);
+ GPRTemporary scratch(this);
- // We don't handle this yet. :-(
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ GPRReg opGPRs[3];
+ unsigned numOpGPRs;
+ opGPRs[0] = op1.gpr();
+ opGPRs[1] = op2.gpr();
+ if (node->child3()) {
+ opGPRs[2] = op3.gpr();
+ numOpGPRs = 3;
+ } else {
+ opGPRs[2] = InvalidGPRReg;
+ numOpGPRs = 2;
+ }
+ GPRReg resultGPR = result.gpr();
+ GPRReg allocatorGPR = allocator.gpr();
+ GPRReg scratchGPR = scratch.gpr();
+
+ JITCompiler::JumpList slowPath;
+ MarkedAllocator& markedAllocator = m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(JSRopeString));
+ m_jit.move(TrustedImmPtr(&markedAllocator), allocatorGPR);
+ emitAllocateJSCell(resultGPR, allocatorGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()), scratchGPR, slowPath);
+
+ m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(resultGPR, JSString::offsetOfValue()));
+ for (unsigned i = 0; i < numOpGPRs; ++i)
+ m_jit.storePtr(opGPRs[i], JITCompiler::Address(resultGPR, JSRopeString::offsetOfFibers() + sizeof(WriteBarrier<JSString>) * i));
+ for (unsigned i = numOpGPRs; i < JSRopeString::s_maxInternalRopeLength; ++i)
+ m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(resultGPR, JSRopeString::offsetOfFibers() + sizeof(WriteBarrier<JSString>) * i));
+ m_jit.load32(JITCompiler::Address(opGPRs[0], JSString::offsetOfFlags()), scratchGPR);
+ m_jit.load32(JITCompiler::Address(opGPRs[0], JSString::offsetOfLength()), allocatorGPR);
+ for (unsigned i = 1; i < numOpGPRs; ++i) {
+ m_jit.and32(JITCompiler::Address(opGPRs[i], JSString::offsetOfFlags()), scratchGPR);
+ m_jit.add32(JITCompiler::Address(opGPRs[i], JSString::offsetOfLength()), allocatorGPR);
+ }
+ m_jit.and32(JITCompiler::TrustedImm32(JSString::Is8Bit), scratchGPR);
+ m_jit.store32(scratchGPR, JITCompiler::Address(resultGPR, JSString::offsetOfFlags()));
+ m_jit.store32(allocatorGPR, JITCompiler::Address(resultGPR, JSString::offsetOfLength()));
+
+ switch (numOpGPRs) {
+ case 2:
+ addSlowPathGenerator(slowPathCall(
+ slowPath, this, operationMakeRope2, resultGPR, opGPRs[0], opGPRs[1]));
+ break;
+ case 3:
+ addSlowPathGenerator(slowPathCall(
+ slowPath, this, operationMakeRope3, resultGPR, opGPRs[0], opGPRs[1], opGPRs[2]));
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+
+ cellResult(resultGPR, node);
}
-void SpeculativeJIT::compileArithSub(Node& node)
+void SpeculativeJIT::compileArithSub(Node* node)
{
- if (m_jit.graph().addShouldSpeculateInteger(node)) {
- if (isNumberConstant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
- int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
+ if (isNumberConstant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
+ int32_t imm2 = valueOfInt32Constant(node->child2().node());
GPRTemporary result(this);
- if (nodeCanTruncateInteger(node.arithNodeFlags())) {
+ if (nodeCanTruncateInteger(node->arithNodeFlags())) {
m_jit.move(op1.gpr(), result.gpr());
m_jit.sub32(Imm32(imm2), result.gpr());
} 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()));
+ speculationCheck(Overflow, JSValueRegs(), 0, 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()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
#endif
}
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
- if (isNumberConstant(node.child1().index())) {
- int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
- SpeculateIntegerOperand op2(this, node.child2());
+ if (isNumberConstant(node->child1().node())) {
+ int32_t imm1 = valueOfInt32Constant(node->child1().node());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this);
m_jit.move(Imm32(imm1), result.gpr());
- if (nodeCanTruncateInteger(node.arithNodeFlags()))
+ if (nodeCanTruncateInteger(node->arithNodeFlags()))
m_jit.sub32(op2.gpr(), result.gpr());
else
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchSub32(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this);
- if (nodeCanTruncateInteger(node.arithNodeFlags())) {
+ if (nodeCanTruncateInteger(node->arithNodeFlags())) {
m_jit.move(op1.gpr(), result.gpr());
m_jit.sub32(op2.gpr(), result.gpr());
} else
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1);
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
+ FPRTemporary result(this, op1);
- FPRReg reg1 = op1.fpr();
- FPRReg reg2 = op2.fpr();
- m_jit.subDouble(reg1, reg2, result.fpr());
+ FPRReg reg1 = op1.fpr();
+ FPRReg reg2 = op2.fpr();
+ m_jit.subDouble(reg1, reg2, result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(result.fpr(), node);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
}
-void SpeculativeJIT::compileArithNegate(Node& node)
+void SpeculativeJIT::compileArithNegate(Node* node)
{
- if (m_jit.graph().negateShouldSpeculateInteger(node)) {
- SpeculateIntegerOperand op1(this, node.child1());
+ switch (node->child1().useKind()) {
+ case Int32Use: {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this);
m_jit.move(op1.gpr(), result.gpr());
- if (nodeCanTruncateInteger(node.arithNodeFlags()))
+ 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()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags()))
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
}
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this);
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRTemporary result(this);
+
+ m_jit.negateDouble(op1.fpr(), result.fpr());
+
+ doubleResult(result.fpr(), node);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
+}
+void SpeculativeJIT::compileArithIMul(Node* node)
+{
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
+ GPRTemporary result(this);
- m_jit.negateDouble(op1.fpr(), result.fpr());
+ GPRReg reg1 = op1.gpr();
+ GPRReg reg2 = op2.gpr();
- doubleResult(result.fpr(), m_compileIndex);
+ m_jit.move(reg1, result.gpr());
+ m_jit.mul32(reg2, result.gpr());
+ integerResult(result.gpr(), node);
+ return;
}
-void SpeculativeJIT::compileArithMul(Node& node)
+void SpeculativeJIT::compileArithMul(Node* node)
{
- if (m_jit.graph().mulShouldSpeculateInteger(node)) {
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this);
GPRReg reg1 = op1.gpr();
@@ -3027,44 +3361,52 @@ void SpeculativeJIT::compileArithMul(Node& node)
// We can perform truncated multiplications if we get to this point, because if the
// fixup phase could not prove that it would be safe, it would have turned us into
// a double multiplication.
- if (nodeCanTruncateInteger(node.arithNodeFlags())) {
+ if (nodeCanTruncateInteger(node->arithNodeFlags())) {
m_jit.move(reg1, result.gpr());
m_jit.mul32(reg2, result.gpr());
} else {
speculationCheck(
- Overflow, JSValueRegs(), NoNode,
+ Overflow, JSValueRegs(), 0,
m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
}
// Check for negative zero, if the users of this node care about such things.
- if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
- speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
- speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
resultNonZero.link(&m_jit);
}
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
return;
}
-
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1, op2);
-
- FPRReg reg1 = op1.fpr();
- FPRReg reg2 = op2.fpr();
- m_jit.mulDouble(reg1, reg2, result.fpr());
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
+ FPRTemporary result(this, op1, op2);
+
+ FPRReg reg1 = op1.fpr();
+ FPRReg reg2 = op2.fpr();
+
+ m_jit.mulDouble(reg1, reg2, result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(result.fpr(), node);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
}
#if CPU(X86) || CPU(X86_64)
-void SpeculativeJIT::compileIntegerArithDivForX86(Node& node)
+void SpeculativeJIT::compileIntegerArithDivForX86(Node* node)
{
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary eax(this, X86Registers::eax);
GPRTemporary edx(this, X86Registers::edx);
GPRReg op1GPR = op1.gpr();
@@ -3090,26 +3432,38 @@ void SpeculativeJIT::compileIntegerArithDivForX86(Node& node)
JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
- JITCompiler::Jump done;
- if (nodeUsedAsNumber(node.arithNodeFlags())) {
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
+ JITCompiler::JumpList done;
+ if (nodeUsedAsNumber(node->arithNodeFlags())) {
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
} else {
- JITCompiler::Jump zero = m_jit.branchTest32(JITCompiler::Zero, op2GPR);
- JITCompiler::Jump isNeg2ToThe31 = m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1));
- zero.link(&m_jit);
+ // This is the case where we convert the result to an int after we're done, and we
+ // already know that the denominator is either -1 or 0. So, if the denominator is
+ // zero, then the result should be zero. If the denominator is not zero (i.e. it's
+ // -1) and the numerator is -2^31 then the result should be -2^31. Otherwise we
+ // are happy to fall through to a normal division, since we're just dividing
+ // something by negative 1.
+
+ JITCompiler::Jump notZero = m_jit.branchTest32(JITCompiler::NonZero, op2GPR);
m_jit.move(TrustedImm32(0), eax.gpr());
- isNeg2ToThe31.link(&m_jit);
- done = m_jit.jump();
+ done.append(m_jit.jump());
+
+ notZero.link(&m_jit);
+ JITCompiler::Jump notNeg2ToThe31 =
+ m_jit.branch32(JITCompiler::NotEqual, op1GPR, TrustedImm32(-2147483647-1));
+ m_jit.move(op1GPR, eax.gpr());
+ done.append(m_jit.jump());
+
+ notNeg2ToThe31.link(&m_jit);
}
safeDenominator.link(&m_jit);
-
+
// If the user cares about negative zero, then speculate that we're not about
// to produce negative zero.
- if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
- speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
numeratorNonZero.link(&m_jit);
}
@@ -3127,72 +3481,114 @@ void SpeculativeJIT::compileIntegerArithDivForX86(Node& node)
// Check that there was no remainder. If there had been, then we'd be obligated to
// produce a double result instead.
- if (nodeUsedAsNumber(node.arithNodeFlags()))
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
+ if (nodeUsedAsNumber(node->arithNodeFlags()))
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
else
done.link(&m_jit);
- integerResult(eax.gpr(), m_compileIndex);
+ integerResult(eax.gpr(), node);
}
-#endif // CPU(X86) || CPU(X86_64)
+#elif CPU(APPLE_ARMV7S)
+void SpeculativeJIT::compileIntegerArithDivForARMv7s(Node* node)
+{
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
+ GPRReg op1GPR = op1.gpr();
+ GPRReg op2GPR = op2.gpr();
+ GPRTemporary quotient(this);
+ GPRTemporary multiplyAnswer(this);
+
+ // If the user cares about negative zero, then speculate that we're not about
+ // to produce negative zero.
+ if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+ MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
+ speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
+ numeratorNonZero.link(&m_jit);
+ }
-void SpeculativeJIT::compileArithMod(Node& node)
+ m_jit.assembler().sdiv(quotient.gpr(), op1GPR, op2GPR);
+
+ // Check that there was no remainder. If there had been, then we'd be obligated to
+ // produce a double result instead.
+ if (nodeUsedAsNumber(node->arithNodeFlags())) {
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotient.gpr(), op2GPR, multiplyAnswer.gpr()));
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::NotEqual, multiplyAnswer.gpr(), op1GPR));
+ }
+
+ integerResult(quotient.gpr(), node);
+}
+#endif
+
+void SpeculativeJIT::compileArithMod(Node* node)
{
- if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2()))
- && node.canSpeculateInteger()) {
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
compileSoftModulo(node);
return;
}
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
- FPRReg op1FPR = op1.fpr();
- FPRReg op2FPR = op2.fpr();
+ FPRReg op1FPR = op1.fpr();
+ FPRReg op2FPR = op2.fpr();
- flushRegisters();
+ flushRegisters();
- FPRResult result(this);
-
- callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
+ FPRResult result(this);
+
+ callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
+
+ doubleResult(result.fpr(), node);
+ return;
+ }
- doubleResult(result.fpr(), m_compileIndex);
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
}
// Returns true if the compare is fused with a subsequent branch.
-bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
+bool SpeculativeJIT::compare(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
{
if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
return true;
- if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
+ if (node->isBinaryUseKind(Int32Use)) {
compileIntegerCompare(node, condition);
return false;
}
-
- if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
+
+ if (node->isBinaryUseKind(NumberUse)) {
compileDoubleCompare(node, doubleCondition);
return false;
}
- if (node.op() == CompareEq) {
- if (at(node.child1()).shouldSpeculateString() || at(node.child2()).shouldSpeculateString()) {
- nonSpeculativeNonPeepholeCompare(node, condition, operation);
+ if (node->op() == CompareEq) {
+ if (node->isBinaryUseKind(StringUse)) {
+ compileStringEquality(node);
return false;
}
- if (at(node.child1()).shouldSpeculateNonStringCell() && at(node.child2()).shouldSpeculateNonStringCellOrOther()) {
- compileObjectToObjectOrOtherEquality(node.child1(), node.child2());
+ if (node->isBinaryUseKind(BooleanUse)) {
+ compileBooleanCompare(node, condition);
+ return false;
+ }
+
+ if (node->isBinaryUseKind(ObjectUse)) {
+ compileObjectEquality(node);
return false;
}
- if (at(node.child1()).shouldSpeculateNonStringCellOrOther() && at(node.child2()).shouldSpeculateNonStringCell()) {
- compileObjectToObjectOrOtherEquality(node.child2(), node.child1());
+ if (node->child1().useKind() == ObjectUse && node->child2().useKind() == ObjectOrOtherUse) {
+ compileObjectToObjectOrOtherEquality(node->child1(), node->child2());
return false;
}
-
- if (at(node.child1()).shouldSpeculateNonStringCell() && at(node.child2()).shouldSpeculateNonStringCell()) {
- compileObjectEquality(node);
+
+ if (node->child1().useKind() == ObjectOrOtherUse && node->child2().useKind() == ObjectUse) {
+ compileObjectToObjectOrOtherEquality(node->child2(), node->child1());
return false;
}
}
@@ -3201,16 +3597,19 @@ bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition con
return false;
}
-bool SpeculativeJIT::compileStrictEqForConstant(Node& node, Edge value, JSValue constant)
+bool SpeculativeJIT::compileStrictEqForConstant(Node* node, Edge value, JSValue constant)
{
JSValueOperand op1(this, value);
+ // FIXME: This code is wrong for the case that the constant is null or undefined,
+ // and the value is an object that MasqueradesAsUndefined.
+ // https://bugs.webkit.org/show_bug.cgi?id=109487
+
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();
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
// The branch instruction will branch to the taken block.
@@ -3241,10 +3640,10 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, Edge value, JSValue
jump(notTaken);
- use(node.child1());
- use(node.child2());
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
@@ -3257,7 +3656,7 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, Edge value, JSValue
MacroAssembler::Jump notEqual = m_jit.branch64(MacroAssembler::NotEqual, op1GPR, MacroAssembler::TrustedImm64(JSValue::encode(constant)));
m_jit.or32(MacroAssembler::TrustedImm32(1), resultGPR);
notEqual.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(resultGPR, node, DataFormatJSBoolean);
#else
GPRReg op1PayloadGPR = op1.payloadGPR();
GPRReg op1TagGPR = op1.tagGPR();
@@ -3268,101 +3667,230 @@ bool SpeculativeJIT::compileStrictEqForConstant(Node& node, Edge value, JSValue
notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1PayloadGPR, MacroAssembler::Imm32(constant.payload())));
m_jit.move(TrustedImm32(1), resultGPR);
notEqual.link(&m_jit);
- booleanResult(resultGPR, m_compileIndex);
+ booleanResult(resultGPR, node);
#endif
return false;
}
-bool SpeculativeJIT::compileStrictEq(Node& node)
+bool SpeculativeJIT::compileStrictEq(Node* node)
{
- // 1) If either operand is a constant and that constant is not a double, integer,
- // or string, then do a JSValue comparison.
-
- if (isJSConstant(node.child1().index())) {
- JSValue value = valueOfJSConstant(node.child1().index());
- if (!value.isNumber() && !value.isString())
- return compileStrictEqForConstant(node, node.child2(), value);
- }
-
- if (isJSConstant(node.child2().index())) {
- JSValue value = valueOfJSConstant(node.child2().index());
- if (!value.isNumber() && !value.isString())
- return compileStrictEqForConstant(node, node.child1(), value);
+ switch (node->binaryUseKind()) {
+ case BooleanUse: {
+ unsigned branchIndexInBlock = detectPeepHoleBranch();
+ if (branchIndexInBlock != UINT_MAX) {
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ compilePeepHoleBooleanBranch(node, branchNode, MacroAssembler::Equal);
+ use(node->child1());
+ use(node->child2());
+ m_indexInBlock = branchIndexInBlock;
+ m_currentNode = branchNode;
+ return true;
+ }
+ compileBooleanCompare(node, MacroAssembler::Equal);
+ return false;
}
-
- // 2) If the operands are predicted integer, do an integer comparison.
-
- if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
+
+ case Int32Use: {
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());
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ compilePeepHoleIntegerBranch(node, branchNode, MacroAssembler::Equal);
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
compileIntegerCompare(node, MacroAssembler::Equal);
return false;
}
-
- // 3) If the operands are predicted double, do a double comparison.
-
- if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
+
+ case NumberUse: {
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());
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ compilePeepHoleDoubleBranch(node, branchNode, MacroAssembler::DoubleEqual);
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
compileDoubleCompare(node, MacroAssembler::DoubleEqual);
return false;
}
-
- if (at(node.child1()).shouldSpeculateString() || at(node.child2()).shouldSpeculateString())
- return nonSpeculativeStrictEq(node);
- if (at(node.child1()).shouldSpeculateNonStringCell() && at(node.child2()).shouldSpeculateNonStringCell()) {
+
+ case StringUse: {
+ compileStringEquality(node);
+ return false;
+ }
+
+ case ObjectUse: {
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
- compilePeepHoleObjectEquality(node, branchNodeIndex);
- use(node.child1());
- use(node.child2());
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ compilePeepHoleObjectEquality(node, branchNode);
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
compileObjectEquality(node);
return false;
}
+
+ case UntypedUse: {
+ return nonSpeculativeStrictEq(node);
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return false;
+ }
+}
+
+void SpeculativeJIT::compileBooleanCompare(Node* node, MacroAssembler::RelationalCondition condition)
+{
+ SpeculateBooleanOperand op1(this, node->child1());
+ SpeculateBooleanOperand op2(this, node->child2());
+ GPRTemporary result(this);
- // 5) Fall back to non-speculative strict equality.
+ m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
- return nonSpeculativeStrictEq(node);
+ // If we add a DataFormatBool, we should use it here.
+#if USE(JSVALUE32_64)
+ booleanResult(result.gpr(), node);
+#else
+ m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+ jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
+#endif
}
-void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
+void SpeculativeJIT::compileStringEquality(Node* node)
{
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand left(this, node->child1());
+ SpeculateCellOperand right(this, node->child2());
+ GPRTemporary length(this);
+ GPRTemporary leftTemp(this);
+ GPRTemporary rightTemp(this);
+ GPRTemporary leftTemp2(this, left);
+ GPRTemporary rightTemp2(this, right);
+
+ GPRReg leftGPR = left.gpr();
+ GPRReg rightGPR = right.gpr();
+ GPRReg lengthGPR = length.gpr();
+ GPRReg leftTempGPR = leftTemp.gpr();
+ GPRReg rightTempGPR = rightTemp.gpr();
+ GPRReg leftTemp2GPR = leftTemp2.gpr();
+ GPRReg rightTemp2GPR = rightTemp2.gpr();
+
+ JITCompiler::JumpList trueCase;
+ JITCompiler::JumpList falseCase;
+ JITCompiler::JumpList slowCase;
+
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(leftGPR), node->child1(), SpecString, m_jit.branchPtr(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(leftGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+
+ // It's safe to branch around the type check below, since proving that the values are
+ // equal does indeed prove that the right value is a string.
+ trueCase.append(m_jit.branchPtr(MacroAssembler::Equal, leftGPR, rightGPR));
+
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(rightGPR), node->child2(), SpecString, m_jit.branchPtr(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(rightGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+
+ m_jit.load32(MacroAssembler::Address(leftGPR, JSString::offsetOfLength()), lengthGPR);
+
+ falseCase.append(m_jit.branch32(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(rightGPR, JSString::offsetOfLength()),
+ lengthGPR));
+
+ trueCase.append(m_jit.branchTest32(MacroAssembler::Zero, lengthGPR));
+
+ m_jit.loadPtr(MacroAssembler::Address(leftGPR, JSString::offsetOfValue()), leftTempGPR);
+ m_jit.loadPtr(MacroAssembler::Address(rightGPR, JSString::offsetOfValue()), rightTempGPR);
+
+ slowCase.append(m_jit.branchTestPtr(MacroAssembler::Zero, leftTempGPR));
+ slowCase.append(m_jit.branchTestPtr(MacroAssembler::Zero, rightTempGPR));
+
+ slowCase.append(m_jit.branchTest32(
+ MacroAssembler::Zero,
+ MacroAssembler::Address(leftTempGPR, StringImpl::flagsOffset()),
+ TrustedImm32(StringImpl::flagIs8Bit())));
+ slowCase.append(m_jit.branchTest32(
+ MacroAssembler::Zero,
+ MacroAssembler::Address(rightTempGPR, StringImpl::flagsOffset()),
+ TrustedImm32(StringImpl::flagIs8Bit())));
+
+ m_jit.loadPtr(MacroAssembler::Address(leftTempGPR, StringImpl::dataOffset()), leftTempGPR);
+ m_jit.loadPtr(MacroAssembler::Address(rightTempGPR, StringImpl::dataOffset()), rightTempGPR);
+
+ MacroAssembler::Label loop = m_jit.label();
+
+ m_jit.sub32(TrustedImm32(1), lengthGPR);
+
+ // This isn't going to generate the best code on x86. But that's OK, it's still better
+ // than not inlining.
+ m_jit.load8(MacroAssembler::BaseIndex(leftTempGPR, lengthGPR, MacroAssembler::TimesOne), leftTemp2GPR);
+ m_jit.load8(MacroAssembler::BaseIndex(rightTempGPR, lengthGPR, MacroAssembler::TimesOne), rightTemp2GPR);
+ falseCase.append(m_jit.branch32(MacroAssembler::NotEqual, leftTemp2GPR, rightTemp2GPR));
+
+ m_jit.branchTest32(MacroAssembler::NonZero, lengthGPR).linkTo(loop, &m_jit);
+
+ trueCase.link(&m_jit);
+#if USE(JSVALUE64)
+ m_jit.move(TrustedImm64(ValueTrue), leftTempGPR);
+#else
+ m_jit.move(TrustedImm32(true), leftTempGPR);
+#endif
+
+ JITCompiler::Jump done = m_jit.jump();
+
+ falseCase.link(&m_jit);
+#if USE(JSVALUE64)
+ m_jit.move(TrustedImm64(ValueFalse), leftTempGPR);
+#else
+ m_jit.move(TrustedImm32(false), leftTempGPR);
+#endif
+
+ done.link(&m_jit);
+ addSlowPathGenerator(
+ slowPathCall(
+ slowCase, this, operationCompareStringEq, leftTempGPR, leftGPR, rightGPR));
+
+#if USE(JSVALUE64)
+ jsValueResult(leftTempGPR, node, DataFormatJSBoolean);
+#else
+ booleanResult(leftTempGPR, node);
+#endif
+}
+
+void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node)
+{
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseReg = base.gpr();
GPRTemporary storage(this);
GPRReg storageReg = storage.gpr();
- const TypedArrayDescriptor* descriptor = typedArrayDescriptor(node.arrayMode());
+ const TypedArrayDescriptor* descriptor = typedArrayDescriptor(node->arrayMode());
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::String:
m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
- // Speculate that we're not accessing a rope
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, storageReg));
+ addSlowPathGenerator(
+ slowPathCall(
+ m_jit.branchTest32(MacroAssembler::Zero, storageReg),
+ this, operationResolveRope, storageReg, baseReg));
m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
break;
@@ -3373,13 +3901,13 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
break;
}
- storageResult(storageReg, m_compileIndex);
+ storageResult(storageReg, node);
}
-void SpeculativeJIT::compileGetByValOnArguments(Node& node)
+void SpeculativeJIT::compileGetByValOnArguments(Node* node)
{
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
GPRTemporary result(this);
#if USE(JSVALUE32_64)
GPRTemporary resultTag(this);
@@ -3397,16 +3925,16 @@ void SpeculativeJIT::compileGetByValOnArguments(Node& node)
if (!m_compileOkay)
return;
- ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node.child1())));
+ ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
// Two really lame checks.
speculationCheck(
- Uncountable, JSValueSource(), NoNode,
- m_jit.branchPtr(
+ Uncountable, JSValueSource(), 0,
+ m_jit.branch32(
MacroAssembler::AboveOrEqual, propertyReg,
MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments))));
speculationCheck(
- Uncountable, JSValueSource(), NoNode,
+ Uncountable, JSValueSource(), 0,
m_jit.branchTestPtr(
MacroAssembler::NonZero,
MacroAssembler::Address(
@@ -3432,20 +3960,20 @@ void SpeculativeJIT::compileGetByValOnArguments(Node& node)
CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register) +
OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
resultReg);
- jsValueResult(resultTagReg, resultReg, m_compileIndex);
+ jsValueResult(resultTagReg, resultReg, node);
#else
m_jit.load64(
MacroAssembler::BaseIndex(
scratchReg, resultReg, MacroAssembler::TimesEight,
CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register)),
resultReg);
- jsValueResult(resultReg, m_compileIndex);
+ jsValueResult(resultReg, node);
#endif
}
-void SpeculativeJIT::compileGetArgumentsLength(Node& node)
+void SpeculativeJIT::compileGetArgumentsLength(Node* node)
{
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary result(this, base);
GPRReg baseReg = base.gpr();
@@ -3454,10 +3982,10 @@ void SpeculativeJIT::compileGetArgumentsLength(Node& node)
if (!m_compileOkay)
return;
- ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node.child1())));
+ ASSERT(ArrayMode(Array::Arguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
speculationCheck(
- Uncountable, JSValueSource(), NoNode,
+ Uncountable, JSValueSource(), 0,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_overrodeLength))));
@@ -3465,46 +3993,46 @@ void SpeculativeJIT::compileGetArgumentsLength(Node& node)
m_jit.load32(
MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments)),
resultReg);
- integerResult(resultReg, m_compileIndex);
+ integerResult(resultReg, node);
}
-void SpeculativeJIT::compileGetArrayLength(Node& node)
+void SpeculativeJIT::compileGetArrayLength(Node* node)
{
- const TypedArrayDescriptor* descriptor = typedArrayDescriptor(node.arrayMode());
+ const TypedArrayDescriptor* descriptor = typedArrayDescriptor(node->arrayMode());
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::Int32:
case Array::Double:
case Array::Contiguous: {
- StorageOperand storage(this, node.child2());
+ StorageOperand storage(this, node->child2());
GPRTemporary result(this, storage);
GPRReg storageReg = storage.gpr();
GPRReg resultReg = result.gpr();
m_jit.load32(MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()), resultReg);
- integerResult(resultReg, m_compileIndex);
+ integerResult(resultReg, node);
break;
}
case Array::ArrayStorage:
case Array::SlowPutArrayStorage: {
- StorageOperand storage(this, node.child2());
+ StorageOperand storage(this, node->child2());
GPRTemporary result(this, storage);
GPRReg storageReg = storage.gpr();
GPRReg resultReg = result.gpr();
m_jit.load32(MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()), resultReg);
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultReg, MacroAssembler::TrustedImm32(0)));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, resultReg, MacroAssembler::TrustedImm32(0)));
- integerResult(resultReg, m_compileIndex);
+ integerResult(resultReg, node);
break;
}
case Array::String: {
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary result(this, base);
GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
- integerResult(resultGPR, m_compileIndex);
+ integerResult(resultGPR, node);
break;
}
case Array::Arguments: {
@@ -3512,28 +4040,28 @@ void SpeculativeJIT::compileGetArrayLength(Node& node)
break;
}
default:
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary result(this, base);
GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
ASSERT(descriptor);
m_jit.load32(MacroAssembler::Address(baseGPR, descriptor->m_lengthOffset), resultGPR);
- integerResult(resultGPR, m_compileIndex);
+ integerResult(resultGPR, node);
break;
}
}
-void SpeculativeJIT::compileNewFunctionNoCheck(Node& node)
+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);
+ operationNewFunctionNoCheck, resultGPR, m_jit.codeBlock()->functionDecl(node->functionDeclIndex()));
+ cellResult(resultGPR, node);
}
-void SpeculativeJIT::compileNewFunctionExpression(Node& node)
+void SpeculativeJIT::compileNewFunctionExpression(Node* node)
{
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -3541,21 +4069,20 @@ void SpeculativeJIT::compileNewFunctionExpression(Node& node)
callOperation(
operationNewFunctionExpression,
resultGPR,
- m_jit.codeBlock()->functionExpr(node.functionExprIndex()));
- cellResult(resultGPR, m_compileIndex);
+ m_jit.codeBlock()->functionExpr(node->functionExprIndex()));
+ cellResult(resultGPR, node);
}
-bool SpeculativeJIT::compileRegExpExec(Node& node)
+bool SpeculativeJIT::compileRegExpExec(Node* node)
{
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock == UINT_MAX)
return false;
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
- ASSERT(node.adjustedRefCount() == 1);
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ ASSERT(node->adjustedRefCount() == 1);
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
bool invert = false;
if (taken == nextBlock()) {
@@ -3565,8 +4092,8 @@ bool SpeculativeJIT::compileRegExpExec(Node& node)
notTaken = tmp;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3577,18 +4104,18 @@ bool SpeculativeJIT::compileRegExpExec(Node& node)
branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, result.gpr(), taken);
jump(notTaken);
- use(node.child1());
- use(node.child2());
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
-void SpeculativeJIT::compileAllocatePropertyStorage(Node& node)
+void SpeculativeJIT::compileAllocatePropertyStorage(Node* node)
{
- if (hasIndexingHeader(node.structureTransitionData().previousStructure->indexingType())) {
- SpeculateCellOperand base(this, node.child1());
+ if (hasIndexingHeader(node->structureTransitionData().previousStructure->indexingType())) {
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseGPR = base.gpr();
@@ -3597,18 +4124,18 @@ void SpeculativeJIT::compileAllocatePropertyStorage(Node& node)
GPRResult result(this);
callOperation(operationReallocateButterflyToHavePropertyStorageWithInitialCapacity, result.gpr(), baseGPR);
- storageResult(result.gpr(), m_compileIndex);
+ storageResult(result.gpr(), node);
return;
}
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary scratch(this);
GPRReg baseGPR = base.gpr();
GPRReg scratchGPR = scratch.gpr();
- ASSERT(!node.structureTransitionData().previousStructure->outOfLineCapacity());
- ASSERT(initialOutOfLineCapacity == node.structureTransitionData().newStructure->outOfLineCapacity());
+ ASSERT(!node->structureTransitionData().previousStructure->outOfLineCapacity());
+ ASSERT(initialOutOfLineCapacity == node->structureTransitionData().newStructure->outOfLineCapacity());
JITCompiler::Jump slowPath =
emitAllocateBasicStorage(
@@ -3621,17 +4148,17 @@ void SpeculativeJIT::compileAllocatePropertyStorage(Node& node)
m_jit.storePtr(scratchGPR, JITCompiler::Address(baseGPR, JSObject::butterflyOffset()));
- storageResult(scratchGPR, m_compileIndex);
+ storageResult(scratchGPR, node);
}
-void SpeculativeJIT::compileReallocatePropertyStorage(Node& node)
+void SpeculativeJIT::compileReallocatePropertyStorage(Node* node)
{
- size_t oldSize = node.structureTransitionData().previousStructure->outOfLineCapacity() * sizeof(JSValue);
+ size_t oldSize = node->structureTransitionData().previousStructure->outOfLineCapacity() * sizeof(JSValue);
size_t newSize = oldSize * outOfLineGrowthFactor;
- ASSERT(newSize == node.structureTransitionData().newStructure->outOfLineCapacity() * sizeof(JSValue));
+ ASSERT(newSize == node->structureTransitionData().newStructure->outOfLineCapacity() * sizeof(JSValue));
- if (hasIndexingHeader(node.structureTransitionData().previousStructure->indexingType())) {
- SpeculateCellOperand base(this, node.child1());
+ if (hasIndexingHeader(node->structureTransitionData().previousStructure->indexingType())) {
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseGPR = base.gpr();
@@ -3640,12 +4167,12 @@ void SpeculativeJIT::compileReallocatePropertyStorage(Node& node)
GPRResult result(this);
callOperation(operationReallocateButterflyToGrowPropertyStorage, result.gpr(), baseGPR, newSize / sizeof(JSValue));
- storageResult(result.gpr(), m_compileIndex);
+ storageResult(result.gpr(), node);
return;
}
- SpeculateCellOperand base(this, node.child1());
- StorageOperand oldStorage(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ StorageOperand oldStorage(this, node->child2());
GPRTemporary scratch1(this);
GPRTemporary scratch2(this);
@@ -3668,7 +4195,7 @@ void SpeculativeJIT::compileReallocatePropertyStorage(Node& node)
}
m_jit.storePtr(scratchGPR2, JITCompiler::Address(baseGPR, JSObject::butterflyOffset()));
- storageResult(scratchGPR2, m_compileIndex);
+ storageResult(scratchGPR2, node);
}
GPRReg SpeculativeJIT::temporaryRegisterForPutByVal(GPRTemporary& temporary, ArrayMode arrayMode)
@@ -3681,6 +4208,392 @@ GPRReg SpeculativeJIT::temporaryRegisterForPutByVal(GPRTemporary& temporary, Arr
return temporary.gpr();
}
+void SpeculativeJIT::compileToStringOnCell(Node* node)
+{
+ SpeculateCellOperand op1(this, node->child1());
+ GPRReg op1GPR = op1.gpr();
+
+ switch (node->child1().useKind()) {
+ case StringObjectUse: {
+ GPRTemporary result(this);
+ GPRReg resultGPR = result.gpr();
+
+ speculateStringObject(node->child1(), op1GPR);
+ m_state.forNode(node->child1()).filter(SpecStringObject);
+ m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
+ cellResult(resultGPR, node);
+ break;
+ }
+
+ case StringOrStringObjectUse: {
+ GPRTemporary result(this);
+ GPRReg resultGPR = result.gpr();
+
+ m_jit.loadPtr(JITCompiler::Address(op1GPR, JSCell::structureOffset()), resultGPR);
+ JITCompiler::Jump isString = m_jit.branchPtr(
+ JITCompiler::Equal, resultGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+
+ speculateStringObjectForStructure(node->child1(), resultGPR);
+
+ m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
+
+ JITCompiler::Jump done = m_jit.jump();
+ isString.link(&m_jit);
+ m_jit.move(op1GPR, resultGPR);
+ done.link(&m_jit);
+
+ m_state.forNode(node->child1()).filter(SpecString | SpecStringObject);
+
+ cellResult(resultGPR, node);
+ break;
+ }
+
+ case CellUse: {
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+
+ // We flush registers instead of silent spill/fill because in this mode we
+ // believe that most likely the input is not a string, and we need to take
+ // slow path.
+ flushRegisters();
+ JITCompiler::Jump done;
+ if (node->child1()->prediction() & SpecString) {
+ JITCompiler::Jump needCall = m_jit.branchPtr(
+ JITCompiler::NotEqual,
+ JITCompiler::Address(op1GPR, JSCell::structureOffset()),
+ TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+ m_jit.move(op1GPR, resultGPR);
+ done = m_jit.jump();
+ needCall.link(&m_jit);
+ }
+ callOperation(operationToStringOnCell, resultGPR, op1GPR);
+ if (done.isSet())
+ done.link(&m_jit);
+ cellResult(resultGPR, node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+}
+
+void SpeculativeJIT::compileNewStringObject(Node* node)
+{
+ SpeculateCellOperand operand(this, node->child1());
+
+ GPRTemporary result(this);
+ GPRTemporary scratch1(this);
+ GPRTemporary scratch2(this);
+
+ GPRReg operandGPR = operand.gpr();
+ GPRReg resultGPR = result.gpr();
+ GPRReg scratch1GPR = scratch1.gpr();
+ GPRReg scratch2GPR = scratch2.gpr();
+
+ JITCompiler::JumpList slowPath;
+
+ emitAllocateJSObject<StringObject>(
+ resultGPR, TrustedImmPtr(node->structure()), TrustedImmPtr(0), scratch1GPR, scratch2GPR,
+ slowPath);
+
+ m_jit.storePtr(
+ TrustedImmPtr(&StringObject::s_info),
+ JITCompiler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
+#if USE(JSVALUE64)
+ m_jit.store64(
+ operandGPR, JITCompiler::Address(resultGPR, JSWrapperObject::internalValueOffset()));
+#else
+ m_jit.store32(
+ TrustedImm32(JSValue::CellTag),
+ JITCompiler::Address(resultGPR, JSWrapperObject::internalValueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ m_jit.store32(
+ operandGPR,
+ JITCompiler::Address(resultGPR, JSWrapperObject::internalValueOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+#endif
+
+ addSlowPathGenerator(slowPathCall(
+ slowPath, this, operationNewStringObject, resultGPR, operandGPR, node->structure()));
+
+ cellResult(resultGPR, node);
+}
+
+void SpeculativeJIT::speculateInt32(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecInt32))
+ return;
+
+ (SpeculateIntegerOperand(this, edge)).gpr();
+}
+
+void SpeculativeJIT::speculateNumber(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecNumber))
+ return;
+
+ (SpeculateDoubleOperand(this, edge)).fpr();
+}
+
+void SpeculativeJIT::speculateRealNumber(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecRealNumber))
+ return;
+
+ SpeculateDoubleOperand operand(this, edge);
+ FPRReg fpr = operand.fpr();
+ DFG_TYPE_CHECK(
+ JSValueRegs(), edge, SpecRealNumber,
+ m_jit.branchDouble(
+ MacroAssembler::DoubleNotEqualOrUnordered, fpr, fpr));
+}
+
+void SpeculativeJIT::speculateBoolean(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecBoolean))
+ return;
+
+ (SpeculateBooleanOperand(this, edge)).gpr();
+}
+
+void SpeculativeJIT::speculateCell(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecCell))
+ return;
+
+ (SpeculateCellOperand(this, edge)).gpr();
+}
+
+void SpeculativeJIT::speculateObject(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecObject))
+ return;
+
+ SpeculateCellOperand operand(this, edge);
+ GPRReg gpr = operand.gpr();
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(gpr), edge, SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(gpr, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+}
+
+void SpeculativeJIT::speculateObjectOrOther(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecObject | SpecOther))
+ return;
+
+ JSValueOperand operand(this, edge, ManualOperandSpeculation);
+ GPRTemporary temp(this);
+ GPRReg tempGPR = temp.gpr();
+#if USE(JSVALUE64)
+ GPRReg gpr = operand.gpr();
+ MacroAssembler::Jump notCell = m_jit.branchTest64(
+ MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister);
+ DFG_TYPE_CHECK(
+ JSValueRegs(gpr), edge, (~SpecCell) | SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(gpr, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ MacroAssembler::Jump done = m_jit.jump();
+ notCell.link(&m_jit);
+ if (needsTypeCheck(edge, SpecCell | SpecOther)) {
+ m_jit.move(gpr, tempGPR);
+ m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), tempGPR);
+
+ typeCheck(
+ JSValueRegs(gpr), edge, SpecCell | SpecOther,
+ m_jit.branch64(
+ MacroAssembler::NotEqual, tempGPR,
+ MacroAssembler::TrustedImm64(ValueNull)));
+ }
+ done.link(&m_jit);
+#else
+ GPRReg tagGPR = operand.tagGPR();
+ GPRReg payloadGPR = operand.payloadGPR();
+ MacroAssembler::Jump notCell =
+ m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag));
+ DFG_TYPE_CHECK(
+ JSValueRegs(tagGPR, payloadGPR), edge, (~SpecCell) | SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(payloadGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ MacroAssembler::Jump done = m_jit.jump();
+ notCell.link(&m_jit);
+ if (needsTypeCheck(edge, SpecCell | SpecOther)) {
+ m_jit.move(tagGPR, tempGPR);
+ m_jit.or32(TrustedImm32(1), tempGPR);
+
+ typeCheck(
+ JSValueRegs(tagGPR, payloadGPR), edge, SpecCell | SpecOther,
+ m_jit.branch32(
+ MacroAssembler::NotEqual, tempGPR,
+ MacroAssembler::TrustedImm32(JSValue::NullTag)));
+ }
+ done.link(&m_jit);
+#endif
+}
+
+void SpeculativeJIT::speculateString(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecString))
+ return;
+
+ SpeculateCellOperand operand(this, edge);
+ GPRReg gpr = operand.gpr();
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(gpr), edge, SpecString, m_jit.branchPtr(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(gpr, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+}
+
+void SpeculativeJIT::speculateStringObject(Edge edge, GPRReg gpr)
+{
+ speculateStringObjectForStructure(edge, JITCompiler::Address(gpr, JSCell::structureOffset()));
+}
+
+void SpeculativeJIT::speculateStringObject(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecStringObject))
+ return;
+
+ SpeculateCellOperand operand(this, edge);
+ GPRReg gpr = operand.gpr();
+ if (!needsTypeCheck(edge, SpecStringObject))
+ return;
+
+ speculateStringObject(edge, gpr);
+ m_state.forNode(edge).filter(SpecStringObject);
+}
+
+void SpeculativeJIT::speculateStringOrStringObject(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecString | SpecStringObject))
+ return;
+
+ SpeculateCellOperand operand(this, edge);
+ GPRReg gpr = operand.gpr();
+ if (!needsTypeCheck(edge, SpecString | SpecStringObject))
+ return;
+
+ GPRTemporary structure(this);
+ GPRReg structureGPR = structure.gpr();
+
+ m_jit.loadPtr(JITCompiler::Address(gpr, JSCell::structureOffset()), structureGPR);
+
+ JITCompiler::Jump isString = m_jit.branchPtr(
+ JITCompiler::Equal, structureGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+
+ speculateStringObjectForStructure(edge, structureGPR);
+
+ isString.link(&m_jit);
+
+ m_state.forNode(edge).filter(SpecString | SpecStringObject);
+}
+
+void SpeculativeJIT::speculateNotCell(Edge edge)
+{
+ if (!needsTypeCheck(edge, ~SpecCell))
+ return;
+
+ JSValueOperand operand(this, edge, ManualOperandSpeculation);
+#if USE(JSVALUE64)
+ typeCheck(
+ JSValueRegs(operand.gpr()), edge, ~SpecCell,
+ m_jit.branchTest64(
+ JITCompiler::Zero, operand.gpr(), GPRInfo::tagMaskRegister));
+#else
+ typeCheck(
+ JSValueRegs(operand.tagGPR(), operand.payloadGPR()), edge, ~SpecCell,
+ m_jit.branch32(
+ JITCompiler::Equal, operand.tagGPR(), TrustedImm32(JSValue::CellTag)));
+#endif
+}
+
+void SpeculativeJIT::speculateOther(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecOther))
+ return;
+
+ JSValueOperand operand(this, edge, ManualOperandSpeculation);
+ GPRTemporary temp(this);
+ GPRReg tempGPR = temp.gpr();
+#if USE(JSVALUE64)
+ m_jit.move(operand.gpr(), tempGPR);
+ m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), tempGPR);
+ typeCheck(
+ JSValueRegs(operand.gpr()), edge, SpecOther,
+ m_jit.branch64(
+ MacroAssembler::NotEqual, tempGPR,
+ MacroAssembler::TrustedImm64(ValueNull)));
+#else
+ m_jit.move(operand.tagGPR(), tempGPR);
+ m_jit.or32(TrustedImm32(1), tempGPR);
+ typeCheck(
+ JSValueRegs(operand.tagGPR(), operand.payloadGPR()), edge, SpecOther,
+ m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(JSValue::NullTag)));
+#endif
+}
+
+void SpeculativeJIT::speculate(Node*, Edge edge)
+{
+ switch (edge.useKind()) {
+ case UntypedUse:
+ break;
+ case KnownInt32Use:
+ ASSERT(!needsTypeCheck(edge, SpecInt32));
+ break;
+ case KnownNumberUse:
+ ASSERT(!needsTypeCheck(edge, SpecNumber));
+ break;
+ case KnownCellUse:
+ ASSERT(!needsTypeCheck(edge, SpecCell));
+ break;
+ case KnownStringUse:
+ ASSERT(!needsTypeCheck(edge, SpecString));
+ break;
+ case Int32Use:
+ speculateInt32(edge);
+ break;
+ case RealNumberUse:
+ speculateRealNumber(edge);
+ break;
+ case NumberUse:
+ speculateNumber(edge);
+ break;
+ case BooleanUse:
+ speculateBoolean(edge);
+ break;
+ case CellUse:
+ speculateCell(edge);
+ break;
+ case ObjectUse:
+ speculateObject(edge);
+ break;
+ case ObjectOrOtherUse:
+ speculateObjectOrOther(edge);
+ break;
+ case StringUse:
+ speculateString(edge);
+ break;
+ case StringObjectUse:
+ speculateStringObject(edge);
+ break;
+ case StringOrStringObjectUse:
+ speculateStringOrStringObject(edge);
+ break;
+ case NotCellUse:
+ speculateNotCell(edge);
+ break;
+ case OtherUse:
+ speculateOther(edge);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
} } // namespace JSC::DFG
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index 949ddfe20..c6fd0d4d6 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#include "DFGGenerationInfo.h"
#include "DFGJITCompiler.h"
#include "DFGOSRExit.h"
+#include "DFGOSRExitJumpPlaceholder.h"
#include "DFGOperations.h"
#include "DFGSilentRegisterSavePlan.h"
#include "DFGValueSource.h"
@@ -53,7 +54,6 @@ class SpeculateCellOperand;
class SpeculateBooleanOperand;
enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandDouble, GeneratedOperandJSValue};
-enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
// === SpeculativeJIT ===
//
@@ -111,15 +111,6 @@ public:
void createOSREntries();
void linkOSREntries(LinkBuffer&);
- Node& at(NodeIndex nodeIndex)
- {
- return m_jit.graph()[nodeIndex];
- }
- Node& at(Edge nodeUse)
- {
- return at(nodeUse.index());
- }
-
BlockIndex nextBlock()
{
for (BlockIndex result = m_block + 1; ; result++) {
@@ -130,14 +121,13 @@ public:
}
}
- GPRReg fillInteger(NodeIndex, DataFormat& returnFormat);
- FPRReg fillDouble(NodeIndex);
+ GPRReg fillInteger(Edge, DataFormat& returnFormat);
#if USE(JSVALUE64)
- GPRReg fillJSValue(NodeIndex);
+ GPRReg fillJSValue(Edge);
#elif USE(JSVALUE32_64)
- bool fillJSValue(NodeIndex, GPRReg&, GPRReg&, FPRReg&);
+ bool fillJSValue(Edge, GPRReg&, GPRReg&, FPRReg&);
#endif
- GPRReg fillStorage(NodeIndex);
+ GPRReg fillStorage(Edge);
// lock and unlock GPR & FPR registers.
void lock(GPRReg reg)
@@ -159,15 +149,15 @@ public:
// Used to check whether a child node is on its last use,
// and its machine registers may be reused.
- bool canReuse(NodeIndex nodeIndex)
+ bool canReuse(Node* node)
{
- VirtualRegister virtualRegister = at(nodeIndex).virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
return info.canReuse();
}
bool canReuse(Edge nodeUse)
{
- return canReuse(nodeUse.index());
+ return canReuse(nodeUse.node());
}
GPRReg reuse(GPRReg reg)
{
@@ -183,12 +173,15 @@ public:
// Allocate a gpr/fpr.
GPRReg allocate()
{
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
+#endif
VirtualRegister spillMe;
GPRReg gpr = m_gprs.allocate(spillMe);
if (spillMe != InvalidVirtualRegister) {
#if USE(JSVALUE32_64)
GenerationInfo& info = m_generationInfo[spillMe];
- ASSERT(info.registerFormat() != DataFormatJSDouble);
+ RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
if ((info.registerFormat() & DataFormatJS))
m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
#endif
@@ -198,11 +191,14 @@ public:
}
GPRReg allocate(GPRReg specific)
{
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
+#endif
VirtualRegister spillMe = m_gprs.allocateSpecific(specific);
if (spillMe != InvalidVirtualRegister) {
#if USE(JSVALUE32_64)
GenerationInfo& info = m_generationInfo[spillMe];
- ASSERT(info.registerFormat() != DataFormatJSDouble);
+ RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
if ((info.registerFormat() & DataFormatJS))
m_gprs.release(info.tagGPR() == specific ? info.payloadGPR() : info.tagGPR());
#endif
@@ -216,6 +212,9 @@ public:
}
FPRReg fprAllocate()
{
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
+#endif
VirtualRegister spillMe;
FPRReg fpr = m_fprs.allocate(spillMe);
if (spillMe != InvalidVirtualRegister)
@@ -228,26 +227,25 @@ public:
// machine registers first (by locking VirtualRegsiters that are already
// in machine register before filling those that are not we attempt to
// avoid spilling values we will need immediately).
- bool isFilled(NodeIndex nodeIndex)
+ bool isFilled(Node* node)
{
- VirtualRegister virtualRegister = at(nodeIndex).virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
return info.registerFormat() != DataFormatNone;
}
- bool isFilledDouble(NodeIndex nodeIndex)
+ bool isFilledDouble(Node* node)
{
- VirtualRegister virtualRegister = at(nodeIndex).virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
return info.registerFormat() == DataFormatDouble;
}
// Called on an operand once it has been consumed by a parent node.
- void use(NodeIndex nodeIndex)
+ void use(Node* node)
{
- Node& node = at(nodeIndex);
- if (!node.hasResult())
+ if (!node->hasResult())
return;
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
// use() returns true when the value becomes dead, and any
@@ -274,7 +272,7 @@ public:
}
void use(Edge nodeUse)
{
- use(nodeUse.index());
+ use(nodeUse.node());
}
RegisterSet usedRegisters()
@@ -293,7 +291,6 @@ public:
return result;
}
- static void markCellCard(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2);
static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, WriteBarrierUseKind);
void writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg);
@@ -307,19 +304,18 @@ public:
// Called by the speculative operand types, below, to fill operand to
// machine registers, implicitly generating speculation checks as needed.
- GPRReg fillSpeculateInt(NodeIndex, DataFormat& returnFormat, SpeculationDirection);
- GPRReg fillSpeculateIntStrict(NodeIndex);
- FPRReg fillSpeculateDouble(NodeIndex, SpeculationDirection);
- GPRReg fillSpeculateCell(NodeIndex, SpeculationDirection);
- GPRReg fillSpeculateBoolean(NodeIndex, SpeculationDirection);
- GeneratedOperandType checkGeneratedTypeForToInt32(NodeIndex);
+ GPRReg fillSpeculateInt(Edge, DataFormat& returnFormat);
+ GPRReg fillSpeculateIntStrict(Edge);
+ FPRReg fillSpeculateDouble(Edge);
+ GPRReg fillSpeculateCell(Edge);
+ GPRReg fillSpeculateBoolean(Edge);
+ GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
void addSlowPathGenerator(PassOwnPtr<SlowPathGenerator>);
void runSlowPathGenerators();
- void compile(Node&);
- void noticeOSRBirth(NodeIndex, Node&);
- void compileMovHint(Node&);
+ void compile(Node*);
+ void noticeOSRBirth(Node*);
void compile(BasicBlock&);
void checkArgumentTypes();
@@ -331,275 +327,10 @@ public:
// they spill all live values to the appropriate
// slots in the JSStack without changing any state
// in the GenerationInfo.
- SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source)
- {
- GenerationInfo& info = m_generationInfo[spillMe];
- NodeIndex nodeIndex = info.nodeIndex();
- Node& node = at(nodeIndex);
- DataFormat registerFormat = info.registerFormat();
- ASSERT(registerFormat != DataFormatNone);
- ASSERT(registerFormat != DataFormatDouble);
-
- SilentSpillAction spillAction;
- SilentFillAction fillAction;
-
- if (!info.needsSpill())
- spillAction = DoNothingForSpill;
- else {
-#if USE(JSVALUE64)
- ASSERT(info.gpr() == source);
- if (registerFormat == DataFormatInteger)
- spillAction = Store32Payload;
- else if (registerFormat == DataFormatCell || registerFormat == DataFormatStorage)
- spillAction = StorePtr;
- else {
- ASSERT(registerFormat & DataFormatJS);
- spillAction = Store64;
- }
-#elif USE(JSVALUE32_64)
- if (registerFormat & DataFormatJS) {
- ASSERT(info.tagGPR() == source || info.payloadGPR() == source);
- spillAction = source == info.tagGPR() ? Store32Tag : Store32Payload;
- } else {
- ASSERT(info.gpr() == source);
- spillAction = Store32Payload;
- }
-#endif
- }
-
- if (registerFormat == DataFormatInteger) {
- ASSERT(info.gpr() == source);
- ASSERT(isJSInteger(info.registerFormat()));
- if (node.hasConstant()) {
- ASSERT(isInt32Constant(nodeIndex));
- fillAction = SetInt32Constant;
- } else
- fillAction = Load32Payload;
- } else if (registerFormat == DataFormatBoolean) {
-#if USE(JSVALUE64)
- ASSERT_NOT_REACHED();
- fillAction = DoNothingForFill;
-#elif USE(JSVALUE32_64)
- ASSERT(info.gpr() == source);
- if (node.hasConstant()) {
- ASSERT(isBooleanConstant(nodeIndex));
- fillAction = SetBooleanConstant;
- } else
- fillAction = Load32Payload;
-#endif
- } else if (registerFormat == DataFormatCell) {
- ASSERT(info.gpr() == source);
- if (node.hasConstant()) {
- JSValue value = valueOfJSConstant(nodeIndex);
- ASSERT_UNUSED(value, value.isCell());
- fillAction = SetCellConstant;
- } else {
-#if USE(JSVALUE64)
- fillAction = LoadPtr;
-#else
- fillAction = Load32Payload;
-#endif
- }
- } else if (registerFormat == DataFormatStorage) {
- ASSERT(info.gpr() == source);
- fillAction = LoadPtr;
- } else {
- ASSERT(registerFormat & DataFormatJS);
-#if USE(JSVALUE64)
- ASSERT(info.gpr() == source);
- if (node.hasConstant()) {
- if (valueOfJSConstant(nodeIndex).isCell())
- fillAction = SetTrustedJSConstant;
- else
- fillAction = SetJSConstant;
- } else if (info.spillFormat() == DataFormatInteger) {
- ASSERT(registerFormat == DataFormatJSInteger);
- fillAction = Load32PayloadBoxInt;
- } else if (info.spillFormat() == DataFormatDouble) {
- ASSERT(registerFormat == DataFormatJSDouble);
- fillAction = LoadDoubleBoxDouble;
- } else
- fillAction = Load64;
-#else
- ASSERT(info.tagGPR() == source || info.payloadGPR() == source);
- if (node.hasConstant())
- fillAction = info.tagGPR() == source ? SetJSConstantTag : SetJSConstantPayload;
- else if (info.payloadGPR() == source)
- fillAction = Load32Payload;
- else { // Fill the Tag
- switch (info.spillFormat()) {
- case DataFormatInteger:
- ASSERT(registerFormat == DataFormatJSInteger);
- fillAction = SetInt32Tag;
- break;
- case DataFormatCell:
- ASSERT(registerFormat == DataFormatJSCell);
- fillAction = SetCellTag;
- break;
- case DataFormatBoolean:
- ASSERT(registerFormat == DataFormatJSBoolean);
- fillAction = SetBooleanTag;
- break;
- default:
- fillAction = Load32Tag;
- break;
- }
- }
-#endif
- }
-
- return SilentRegisterSavePlan(spillAction, fillAction, nodeIndex, source);
- }
-
- SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source)
- {
- GenerationInfo& info = m_generationInfo[spillMe];
- NodeIndex nodeIndex = info.nodeIndex();
- Node& node = at(nodeIndex);
- ASSERT(info.registerFormat() == DataFormatDouble);
-
- SilentSpillAction spillAction;
- SilentFillAction fillAction;
-
- if (!info.needsSpill())
- spillAction = DoNothingForSpill;
- else {
- ASSERT(!at(info.nodeIndex()).hasConstant());
- ASSERT(info.spillFormat() == DataFormatNone);
- ASSERT(info.fpr() == source);
- spillAction = StoreDouble;
- }
-
-#if USE(JSVALUE64)
- if (node.hasConstant()) {
- ASSERT(isNumberConstant(nodeIndex));
- fillAction = SetDoubleConstant;
- } else if (info.spillFormat() != DataFormatNone && info.spillFormat() != DataFormatDouble) {
- // it was already spilled previously and not as a double, which means we need unboxing.
- ASSERT(info.spillFormat() & DataFormatJS);
- fillAction = LoadJSUnboxDouble;
- } else
- fillAction = LoadDouble;
-#elif USE(JSVALUE32_64)
- ASSERT(info.registerFormat() == DataFormatDouble || info.registerFormat() == DataFormatJSDouble);
- if (node.hasConstant()) {
- ASSERT(isNumberConstant(nodeIndex));
- fillAction = SetDoubleConstant;
- } else
- fillAction = LoadDouble;
-#endif
-
- return SilentRegisterSavePlan(spillAction, fillAction, nodeIndex, source);
- }
-
- void silentSpill(const SilentRegisterSavePlan& plan)
- {
- switch (plan.spillAction()) {
- case DoNothingForSpill:
- break;
- case Store32Tag:
- m_jit.store32(plan.gpr(), JITCompiler::tagFor(at(plan.nodeIndex()).virtualRegister()));
- break;
- case Store32Payload:
- m_jit.store32(plan.gpr(), JITCompiler::payloadFor(at(plan.nodeIndex()).virtualRegister()));
- break;
- case StorePtr:
- m_jit.storePtr(plan.gpr(), JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()));
- break;
-#if USE(JSVALUE64)
- case Store64:
- m_jit.store64(plan.gpr(), JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()));
- break;
-#endif
- case StoreDouble:
- m_jit.storeDouble(plan.fpr(), JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()));
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- void silentFill(const SilentRegisterSavePlan& plan, GPRReg canTrample)
- {
-#if USE(JSVALUE32_64)
- UNUSED_PARAM(canTrample);
-#endif
- switch (plan.fillAction()) {
- case DoNothingForFill:
- break;
- case SetInt32Constant:
- m_jit.move(Imm32(valueOfInt32Constant(plan.nodeIndex())), plan.gpr());
- break;
- case SetBooleanConstant:
- m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.nodeIndex())), plan.gpr());
- break;
- case SetCellConstant:
- m_jit.move(TrustedImmPtr(valueOfJSConstant(plan.nodeIndex()).asCell()), plan.gpr());
- break;
-#if USE(JSVALUE64)
- case SetTrustedJSConstant:
- m_jit.move(valueOfJSConstantAsImm64(plan.nodeIndex()).asTrustedImm64(), plan.gpr());
- break;
- case SetJSConstant:
- m_jit.move(valueOfJSConstantAsImm64(plan.nodeIndex()), plan.gpr());
- break;
- case SetDoubleConstant:
- m_jit.move(Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(plan.nodeIndex()))), canTrample);
- m_jit.move64ToDouble(canTrample, plan.fpr());
- break;
- case Load32PayloadBoxInt:
- m_jit.load32(JITCompiler::payloadFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
- m_jit.or64(GPRInfo::tagTypeNumberRegister, plan.gpr());
- break;
- case LoadDoubleBoxDouble:
- m_jit.load64(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
- m_jit.sub64(GPRInfo::tagTypeNumberRegister, plan.gpr());
- break;
- case LoadJSUnboxDouble:
- m_jit.load64(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), canTrample);
- unboxDouble(canTrample, plan.fpr());
- break;
-#else
- case SetJSConstantTag:
- m_jit.move(Imm32(valueOfJSConstant(plan.nodeIndex()).tag()), plan.gpr());
- break;
- case SetJSConstantPayload:
- m_jit.move(Imm32(valueOfJSConstant(plan.nodeIndex()).payload()), plan.gpr());
- break;
- case SetInt32Tag:
- m_jit.move(TrustedImm32(JSValue::Int32Tag), plan.gpr());
- break;
- case SetCellTag:
- m_jit.move(TrustedImm32(JSValue::CellTag), plan.gpr());
- break;
- case SetBooleanTag:
- m_jit.move(TrustedImm32(JSValue::BooleanTag), plan.gpr());
- break;
- case SetDoubleConstant:
- m_jit.loadDouble(addressOfDoubleConstant(plan.nodeIndex()), plan.fpr());
- break;
-#endif
- case Load32Tag:
- m_jit.load32(JITCompiler::tagFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
- break;
- case Load32Payload:
- m_jit.load32(JITCompiler::payloadFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
- break;
- case LoadPtr:
- m_jit.loadPtr(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
- break;
-#if USE(JSVALUE64)
- case Load64:
- m_jit.load64(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
- break;
-#endif
- case LoadDouble:
- m_jit.loadDouble(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.fpr());
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
+ SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source);
+ SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source);
+ void silentSpill(const SilentRegisterSavePlan&);
+ void silentFill(const SilentRegisterSavePlan&, GPRReg canTrample);
template<typename CollectionType>
void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
@@ -761,7 +492,7 @@ public:
default:
// The following code handles JSValues, int32s, and cells.
- ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
+ RELEASE_ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
GPRReg reg = info.gpr();
// We need to box int32 and cell values ...
@@ -791,7 +522,7 @@ public:
default:
// The following code handles JSValues.
- ASSERT(spillFormat & DataFormatJS);
+ RELEASE_ASSERT(spillFormat & DataFormatJS);
m_jit.store32(info.tagGPR(), JITCompiler::tagFor(spillMe));
m_jit.store32(info.payloadGPR(), JITCompiler::payloadFor(spillMe));
info.spill(*m_stream, spillMe, spillFormat);
@@ -800,44 +531,34 @@ public:
}
}
- bool isStrictInt32(NodeIndex);
+ bool isKnownInteger(Node* node) { return !(m_state.forNode(node).m_type & ~SpecInt32); }
+ bool isKnownCell(Node* node) { return !(m_state.forNode(node).m_type & ~SpecCell); }
- bool isKnownInteger(NodeIndex);
- bool isKnownNumeric(NodeIndex);
- bool isKnownCell(NodeIndex);
-
- bool isKnownNotInteger(NodeIndex);
- bool isKnownNotNumber(NodeIndex);
-
- bool isKnownNotCell(NodeIndex);
+ bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); }
+ bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecNumber); }
+ bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
// Checks/accessors for constant values.
- bool isConstant(NodeIndex nodeIndex) { return m_jit.graph().isConstant(nodeIndex); }
- bool isJSConstant(NodeIndex nodeIndex) { return m_jit.graph().isJSConstant(nodeIndex); }
- bool isInt32Constant(NodeIndex nodeIndex) { return m_jit.graph().isInt32Constant(nodeIndex); }
- bool isDoubleConstant(NodeIndex nodeIndex) { return m_jit.graph().isDoubleConstant(nodeIndex); }
- bool isNumberConstant(NodeIndex nodeIndex) { return m_jit.graph().isNumberConstant(nodeIndex); }
- bool isBooleanConstant(NodeIndex nodeIndex) { return m_jit.graph().isBooleanConstant(nodeIndex); }
- bool isFunctionConstant(NodeIndex nodeIndex) { return m_jit.graph().isFunctionConstant(nodeIndex); }
- int32_t valueOfInt32Constant(NodeIndex nodeIndex) { return m_jit.graph().valueOfInt32Constant(nodeIndex); }
- double valueOfNumberConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfNumberConstant(nodeIndex); }
- int32_t valueOfNumberConstantAsInt32(NodeIndex nodeIndex)
- {
- if (isInt32Constant(nodeIndex))
- return valueOfInt32Constant(nodeIndex);
- return JSC::toInt32(valueOfNumberConstant(nodeIndex));
- }
+ bool isConstant(Node* node) { return m_jit.graph().isConstant(node); }
+ bool isJSConstant(Node* node) { return m_jit.graph().isJSConstant(node); }
+ bool isInt32Constant(Node* node) { return m_jit.graph().isInt32Constant(node); }
+ bool isDoubleConstant(Node* node) { return m_jit.graph().isDoubleConstant(node); }
+ bool isNumberConstant(Node* node) { return m_jit.graph().isNumberConstant(node); }
+ bool isBooleanConstant(Node* node) { return m_jit.graph().isBooleanConstant(node); }
+ bool isFunctionConstant(Node* node) { return m_jit.graph().isFunctionConstant(node); }
+ int32_t valueOfInt32Constant(Node* node) { return m_jit.graph().valueOfInt32Constant(node); }
+ double valueOfNumberConstant(Node* node) { return m_jit.graph().valueOfNumberConstant(node); }
#if USE(JSVALUE32_64)
- void* addressOfDoubleConstant(NodeIndex nodeIndex) { return m_jit.addressOfDoubleConstant(nodeIndex); }
+ void* addressOfDoubleConstant(Node* node) { return m_jit.addressOfDoubleConstant(node); }
#endif
- JSValue valueOfJSConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfJSConstant(nodeIndex); }
- bool valueOfBooleanConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfBooleanConstant(nodeIndex); }
- JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfFunctionConstant(nodeIndex); }
- bool isNullConstant(NodeIndex nodeIndex)
+ JSValue valueOfJSConstant(Node* node) { return m_jit.graph().valueOfJSConstant(node); }
+ bool valueOfBooleanConstant(Node* node) { return m_jit.graph().valueOfBooleanConstant(node); }
+ JSFunction* valueOfFunctionConstant(Node* node) { return m_jit.graph().valueOfFunctionConstant(node); }
+ bool isNullConstant(Node* node)
{
- if (!isConstant(nodeIndex))
+ if (!isConstant(node))
return false;
- return valueOfJSConstant(nodeIndex).isNull();
+ return valueOfJSConstant(node).isNull();
}
Identifier* identifier(unsigned index)
@@ -845,16 +566,6 @@ public:
return &m_jit.codeBlock()->identifier(index);
}
- ResolveOperations* resolveOperations(unsigned index)
- {
- return m_jit.codeBlock()->resolveOperations(index);
- }
-
- PutToBaseOperation* putToBaseOperation(unsigned index)
- {
- return m_jit.codeBlock()->putToBaseOperation(index);
- }
-
// Spill all VirtualRegisters back to the JSStack.
void flushRegisters()
{
@@ -890,9 +601,9 @@ public:
#endif
#if USE(JSVALUE64)
- MacroAssembler::Imm64 valueOfJSConstantAsImm64(NodeIndex nodeIndex)
+ MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
{
- return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(nodeIndex)));
+ return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(node)));
}
#endif
@@ -910,7 +621,7 @@ public:
m_jit.xor32(Imm32(imm), op1, result);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
@@ -926,7 +637,7 @@ public:
m_jit.xor32(op1, op2, result);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
@@ -942,7 +653,7 @@ public:
m_jit.urshift32(op1, Imm32(shiftAmount), result);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
@@ -958,7 +669,7 @@ public:
m_jit.urshift32(op1, shiftAmount, result);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -969,19 +680,21 @@ public:
// Check that no intervening nodes will be generated.
for (unsigned index = m_indexInBlock + 1; index < block->size() - 1; ++index) {
- NodeIndex nodeIndex = block->at(index);
- if (at(nodeIndex).shouldGenerate())
+ Node* node = block->at(index);
+ if (node->shouldGenerate())
return UINT_MAX;
}
// Check if the lastNode is a branch on this node.
- Node& lastNode = at(block->last());
- return lastNode.op() == Branch && lastNode.child1().index() == m_compileIndex ? block->size() - 1 : UINT_MAX;
+ Node* lastNode = block->last();
+ return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? block->size() - 1 : UINT_MAX;
}
- void nonSpeculativeValueToNumber(Node&);
- void nonSpeculativeValueToInt32(Node&);
- void nonSpeculativeUInt32ToNumber(Node&);
+ void compileMovHint(Node*);
+ void compileMovHintAndCheck(Node*);
+ void compileInlineStart(Node*);
+
+ void nonSpeculativeUInt32ToNumber(Node*);
#if USE(JSVALUE64)
void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
@@ -992,19 +705,19 @@ public:
#endif
void nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert = false);
- void nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex branchNodeIndex, bool invert = false);
- bool nonSpeculativeCompareNull(Node&, Edge operand, bool invert = false);
+ void nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert = false);
+ bool nonSpeculativeCompareNull(Node*, Edge operand, bool invert = false);
- void nonSpeculativePeepholeBranch(Node&, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
- void nonSpeculativeNonPeepholeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
- bool nonSpeculativeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
+ void nonSpeculativePeepholeBranch(Node*, Node* branchNode, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
+ void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
+ bool nonSpeculativeCompare(Node*, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
- void nonSpeculativePeepholeStrictEq(Node&, NodeIndex branchNodeIndex, bool invert = false);
- void nonSpeculativeNonPeepholeStrictEq(Node&, bool invert = false);
- bool nonSpeculativeStrictEq(Node&, bool invert = false);
+ void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
+ void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false);
+ bool nonSpeculativeStrictEq(Node*, bool invert = false);
- void compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg);
- void compileInstanceOf(Node&);
+ void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg);
+ void compileInstanceOf(Node*);
// Access to our fixed callee CallFrame.
MacroAssembler::Address callFrameSlot(int slot)
@@ -1038,137 +751,128 @@ public:
return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
}
- void emitCall(Node&);
+ void emitCall(Node*);
// Called once a node has completed code generation but prior to setting
// its result, to free up its children. (This must happen prior to setting
// the nodes result, since the node may have the same VirtualRegister as
// a child, and as such will use the same GeneratioInfo).
- void useChildren(Node&);
+ void useChildren(Node*);
// These method called to initialize the the GenerationInfo
// to describe the result of an operation.
- void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger, UseChildrenMode mode = CallUseChildren)
+ void integerResult(GPRReg reg, Node* node, DataFormat format = DataFormatInteger, UseChildrenMode mode = CallUseChildren)
{
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
if (format == DataFormatInteger) {
m_jit.jitAssertIsInt32(reg);
m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
- info.initInteger(nodeIndex, node.refCount(), reg);
+ info.initInteger(node, node->refCount(), reg);
} else {
#if USE(JSVALUE64)
- ASSERT(format == DataFormatJSInteger);
+ RELEASE_ASSERT(format == DataFormatJSInteger);
m_jit.jitAssertIsJSInt32(reg);
m_gprs.retain(reg, virtualRegister, SpillOrderJS);
- info.initJSValue(nodeIndex, node.refCount(), reg, format);
+ info.initJSValue(node, node->refCount(), reg, format);
#elif USE(JSVALUE32_64)
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif
}
}
- void integerResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
+ void integerResult(GPRReg reg, Node* node, UseChildrenMode mode)
{
- integerResult(reg, nodeIndex, DataFormatInteger, mode);
+ integerResult(reg, node, DataFormatInteger, mode);
}
- void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
+ void noResult(Node* node, UseChildrenMode mode = CallUseChildren)
{
if (mode == UseChildrenCalledExplicitly)
return;
- Node& node = at(nodeIndex);
useChildren(node);
}
- void cellResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
+ void cellResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
{
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(reg, virtualRegister, SpillOrderCell);
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.initCell(nodeIndex, node.refCount(), reg);
+ info.initCell(node, node->refCount(), reg);
}
- void booleanResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
+ void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
{
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.initBoolean(nodeIndex, node.refCount(), reg);
+ info.initBoolean(node, node->refCount(), reg);
}
#if USE(JSVALUE64)
- void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
+ void jsValueResult(GPRReg reg, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
{
if (format == DataFormatJSInteger)
m_jit.jitAssertIsJSInt32(reg);
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(reg, virtualRegister, SpillOrderJS);
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.initJSValue(nodeIndex, node.refCount(), reg, format);
+ info.initJSValue(node, node->refCount(), reg, format);
}
- void jsValueResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
+ void jsValueResult(GPRReg reg, Node* node, UseChildrenMode mode)
{
- jsValueResult(reg, nodeIndex, DataFormatJS, mode);
+ jsValueResult(reg, node, DataFormatJS, mode);
}
#elif USE(JSVALUE32_64)
- void jsValueResult(GPRReg tag, GPRReg payload, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
+ void jsValueResult(GPRReg tag, GPRReg payload, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
{
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(tag, virtualRegister, SpillOrderJS);
m_gprs.retain(payload, virtualRegister, SpillOrderJS);
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.initJSValue(nodeIndex, node.refCount(), tag, payload, format);
+ info.initJSValue(node, node->refCount(), tag, payload, format);
}
- void jsValueResult(GPRReg tag, GPRReg payload, NodeIndex nodeIndex, UseChildrenMode mode)
+ void jsValueResult(GPRReg tag, GPRReg payload, Node* node, UseChildrenMode mode)
{
- jsValueResult(tag, payload, nodeIndex, DataFormatJS, mode);
+ jsValueResult(tag, payload, node, DataFormatJS, mode);
}
#endif
- void storageResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
+ void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
{
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.initStorage(nodeIndex, node.refCount(), reg);
+ info.initStorage(node, node->refCount(), reg);
}
- void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
+ void doubleResult(FPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
{
- Node& node = at(nodeIndex);
if (mode == CallUseChildren)
useChildren(node);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
GenerationInfo& info = m_generationInfo[virtualRegister];
- info.initDouble(nodeIndex, node.refCount(), reg);
+ info.initDouble(node, node->refCount(), reg);
}
- void initConstantInfo(NodeIndex nodeIndex)
+ void initConstantInfo(Node* node)
{
- ASSERT(isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex) || isJSConstant(nodeIndex));
- Node& node = at(nodeIndex);
- m_generationInfo[node.virtualRegister()].initConstant(nodeIndex, node.refCount());
+ ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node));
+ m_generationInfo[node->virtualRegister()].initConstant(node, node->refCount());
}
// These methods add calls to C++ helper functions.
@@ -1176,12 +880,17 @@ public:
// deal with the fact that a JSValue may be passed in one or two
// machine registers, and delegate the calling convention specific
// decision as to how to fill the regsiters to setupArguments* methods.
-#if USE(JSVALUE64)
+
JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
{
m_jit.setupArgumentsExecState();
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(P_DFGOperation_EC operation, GPRReg result, GPRReg cell)
+ {
+ m_jit.setupArgumentsWithExecState(cell);
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(P_DFGOperation_EO operation, GPRReg result, GPRReg object)
{
m_jit.setupArgumentsWithExecState(object);
@@ -1197,6 +906,11 @@ public:
m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(C_DFGOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
+ {
+ m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(static_cast<size_t>(size)));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
{
m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
@@ -1207,81 +921,223 @@ public:
m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result)
+ JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure)
{
- m_jit.setupArgumentsExecState();
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, void* pointer)
+ JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
+ JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
{
- m_jit.setupArguments(arg1);
- JITCompiler::Call call = m_jit.appendCall(operation);
- m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
- return call;
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
+ return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
+ JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
+ m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg result, Identifier* identifier)
+ JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EIRo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations)
+ JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations));
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EIRoPtbo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
+
+ JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations), TrustedImmPtr(putToBaseOperations));
+ m_jit.setupArgumentsExecState();
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg result, GPRReg arg1)
+ JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
{
m_jit.setupArgumentsWithExecState(arg1);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2);
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure)
+ JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(C_DFGOperation_ESt operation, GPRReg result, Structure* structure)
{
m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
+ JITCompiler::Call callOperation(C_DFGOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
+ m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
+ JITCompiler::Call callOperation(C_DFGOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
+ m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(C_DFGOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+
+ JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
{
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
+
+ JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
+ m_jit.setupArgumentsWithExecState(arg1);
+ return appendCallWithExceptionCheck(operation);
+ }
+
+ JITCompiler::Call callOperation(V_DFGOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
+ return appendCallWithExceptionCheck(operation);
+ }
+ JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
+ return appendCallWithExceptionCheck(operation);
+ }
+
+ JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
+ return appendCallWithExceptionCheck(operation);
+ }
+
+ JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2);
+ return appendCallWithExceptionCheck(operation);
+ }
+
+ JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallWithExceptionCheck(operation);
+ }
+
+ JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
+ {
+ m_jit.setupArguments(TrustedImmPtr(watchpointSet));
+ return appendCall(operation);
+ }
+
+ template<typename FunctionType, typename ArgumentType1>
+ JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
+ {
+ return callOperation(operation, arg1);
+ }
+ template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
+ JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
+ {
+ return callOperation(operation, arg1, arg2);
+ }
+ template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
+ JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
+ {
+ return callOperation(operation, arg1, arg2, arg3);
+ }
+ template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4>
+ JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4)
+ {
+ return callOperation(operation, arg1, arg2, arg3, arg4);
+ }
+ template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
+ JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
+ {
+ return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
+ }
+
+ JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
+ {
+ m_jit.setupArguments(arg1, arg2);
+ return appendCallSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
+ {
+ m_jit.setupArguments(arg1, arg2);
+ return appendCallSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(Str_DFGOperation_EJss operation, GPRReg result, GPRReg arg1)
+ {
+ m_jit.setupArgumentsWithExecState(arg1);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
+ JITCompiler::Call callOperation(C_DFGOperation_EZ operation, GPRReg result, GPRReg arg1)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
+ m_jit.setupArgumentsWithExecState(arg1);
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+
+#if USE(JSVALUE64)
+ JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result)
+ {
+ m_jit.setupArgumentsExecState();
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, void* pointer)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
+ {
+ m_jit.setupArguments(arg1);
+ JITCompiler::Call call = m_jit.appendCall(operation);
+ m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
+ return call;
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg result, Identifier* identifier)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EIRo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EIRoPtbo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations), TrustedImmPtr(putToBaseOperations));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg result, GPRReg arg1)
+ {
+ m_jit.setupArgumentsWithExecState(arg1);
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+ JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg result, void* pointer, size_t size)
@@ -1299,6 +1155,11 @@ public:
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(J_DFGOperation_EC operation, GPRReg result, JSCell* cell)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
{
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
@@ -1344,36 +1205,13 @@ public:
m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
- {
- m_jit.setupArgumentsExecState();
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
+
+
+ JITCompiler::Call callOperation(C_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
{
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));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(C_DFGOperation_ESt operation, GPRReg result, Structure* structure)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1)
{
m_jit.setupArguments(arg1);
@@ -1394,11 +1232,7 @@ public:
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2);
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
+
JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
{
m_jit.setupArgumentsWithExecState(arg1, arg2);
@@ -1429,21 +1263,7 @@ public:
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_ECIcf operation, GPRReg arg1, InlineCallFrame* arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
- return appendCallWithExceptionCheck(operation);
- }
- JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* arg3)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arg3));
- return appendCallWithExceptionCheck(operation);
- }
+
JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
{
m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
@@ -1464,11 +1284,7 @@ public:
m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallWithExceptionCheck(operation);
}
- JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
- return appendCallWithExceptionCheck(operation);
- }
+
JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
@@ -1479,52 +1295,14 @@ public:
m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallWithExceptionCheck(operation);
}
- JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
- return appendCallWithExceptionCheck(operation);
- }
- JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2);
- return appendCallWithExceptionCheck(operation);
- }
- JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
- {
- m_jit.setupArguments(TrustedImmPtr(watchpointSet));
- return appendCall(operation);
- }
- template<typename FunctionType, typename ArgumentType1>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
- {
- return callOperation(operation, arg1);
- }
- template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
- {
- return callOperation(operation, arg1, arg2);
- }
- template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
- {
- return callOperation(operation, arg1, arg2, arg3);
- }
+
JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1)
{
m_jit.setupArgumentsWithExecState(arg1);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArguments(arg1, arg2);
- return appendCallSetResult(operation, result);
- }
- JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
- {
- m_jit.setupArguments(arg1, arg2);
- return appendCallSetResult(operation, result);
- }
-#else
+
+#else // USE(JSVALUE32_64)
// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
// To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
@@ -1534,36 +1312,14 @@ public:
#define EABI_32BIT_DUMMY_ARG
#endif
- JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
- {
- m_jit.setupArgumentsExecState();
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EO operation, GPRReg result, GPRReg arg1)
- {
- m_jit.setupArgumentsWithExecState(arg1);
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EOS operation, GPRReg result, GPRReg arg1, size_t arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
- {
- m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
+// JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture.
+// To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary.
+#if CPU(SH4)
+#define SH4_32BIT_DUMMY_ARG TrustedImm32(0),
+#else
+#define SH4_32BIT_DUMMY_ARG
+#endif
+
JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
{
prepareForExternalCall();
@@ -1612,36 +1368,6 @@ public:
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
- JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2);
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
{
m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
@@ -1662,6 +1388,12 @@ public:
m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
+
+ JITCompiler::Call callOperation(J_DFGOperation_EC operation, GPRReg resultTag, GPRReg resultPayload, JSCell* cell)
+ {
+ m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
+ return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
+ }
JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, Identifier* identifier)
{
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
@@ -1717,34 +1449,11 @@ public:
m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
- JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
- {
- m_jit.setupArgumentsExecState();
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
- {
- 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));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
- {
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
- JITCompiler::Call callOperation(C_DFGOperation_ESt operation, GPRReg result, Structure* structure)
+
+
+ JITCompiler::Call callOperation(C_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
{
- m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
+ m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
return appendCallWithExceptionCheckSetResult(operation, result);
}
JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
@@ -1757,29 +1466,25 @@ public:
m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2);
- return appendCallWithExceptionCheckSetResult(operation, result);
- }
+
JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
{
- m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
+ m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
return appendCallWithExceptionCheckSetResult(operation, result);
}
JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
{
- m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
+ m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
{
- m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag));
+ m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag));
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
{
- m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag);
+ m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
}
@@ -1805,21 +1510,7 @@ public:
m_jit.setupArgumentsWithExecState(arg1, arg2);
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_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
- {
- m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
- return appendCallWithExceptionCheck(operation);
- }
- JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
- return appendCallWithExceptionCheck(operation);
- }
+
JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
{
m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
@@ -1835,66 +1526,23 @@ public:
m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
return appendCallWithExceptionCheck(operation);
}
- JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
- return appendCallWithExceptionCheck(operation);
- }
- JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2);
- return appendCallWithExceptionCheck(operation);
- }
+
JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
- return appendCallWithExceptionCheck(operation);
- }
- JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
return appendCallWithExceptionCheck(operation);
}
+
JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
return appendCallWithExceptionCheck(operation);
}
JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
return appendCallWithExceptionCheck(operation);
}
- JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
- {
- m_jit.setupArguments(TrustedImmPtr(watchpointSet));
- return appendCall(operation);
- }
- template<typename FunctionType, typename ArgumentType1>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
- {
- return callOperation(operation, arg1);
- }
- template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
- {
- return callOperation(operation, arg1, arg2);
- }
- template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
- {
- return callOperation(operation, arg1, arg2, arg3);
- }
- template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4)
- {
- return callOperation(operation, arg1, arg2, arg3, arg4);
- }
- template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
- JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
- {
- return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
- }
JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
{
@@ -1902,18 +1550,8 @@ public:
return appendCallWithExceptionCheckSetResult(operation, result);
}
- JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
- {
- m_jit.setupArguments(arg1, arg2);
- return appendCallSetResult(operation, result);
- }
- JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
- {
- m_jit.setupArguments(arg1, arg2);
- return appendCallSetResult(operation, result);
- }
-
#undef EABI_32BIT_DUMMY_ARG
+#undef SH4_32BIT_DUMMY_ARG
template<typename FunctionType>
JITCompiler::Call callOperation(
@@ -1961,9 +1599,9 @@ public:
return callOperation(
operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
}
-#endif
+#endif // USE(JSVALUE32_64)
-#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS)
+#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4)
void prepareForExternalCall()
{
// We're about to call out to a "native" helper function. The helper
@@ -1976,7 +1614,7 @@ public:
// anyway since it was not being updated by JIT'ed code by design.
for (unsigned i = 0; i < sizeof(void*) / 4; i++)
- m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.globalData()->topCallFrame) + i * 4);
+ m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.vm()->topCallFrame) + i * 4);
}
#else
void prepareForExternalCall() { }
@@ -1986,7 +1624,7 @@ public:
JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
{
prepareForExternalCall();
- CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
+ CodeOrigin codeOrigin = m_currentNode->codeOrigin;
CallBeginToken token;
m_jit.beginCall(codeOrigin, token);
JITCompiler::Call call = m_jit.appendCall(function);
@@ -2272,89 +1910,99 @@ public:
void checkConsistency() { }
#endif
- bool isInteger(NodeIndex nodeIndex)
+ bool isInteger(Node* node)
{
- Node& node = at(nodeIndex);
- if (node.hasInt32Result())
+ if (node->hasInt32Result())
return true;
- if (isInt32Constant(nodeIndex))
+ if (isInt32Constant(node))
return true;
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
return info.isJSInteger();
}
- bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
- bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
- void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
- void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition);
- void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex);
- void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, NodeIndex branchNodeIndex);
- void compileObjectEquality(Node&);
+ bool compare(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
+ bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
+ void compilePeepHoleIntegerBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
+ void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
+ void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
+ void compilePeepHoleObjectEquality(Node*, Node* branchNode);
+ void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
+ void compileObjectEquality(Node*);
void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
- void compileValueAdd(Node&);
- void compileNonStringCellOrOtherLogicalNot(Edge value, bool needSpeculationCheck);
- void compileLogicalNot(Node&);
- void emitNonStringCellOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck);
- void emitBranch(Node&);
+ void compileValueAdd(Node*);
+ void compileObjectOrOtherLogicalNot(Edge value);
+ void compileLogicalNot(Node*);
+ void compileStringEquality(Node*);
+ void emitObjectOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken);
+ void emitBranch(Node*);
+
+ void compileToStringOnCell(Node*);
+ void compileNewStringObject(Node*);
- void compileIntegerCompare(Node&, MacroAssembler::RelationalCondition);
- void compileDoubleCompare(Node&, MacroAssembler::DoubleCondition);
+ void compileIntegerCompare(Node*, MacroAssembler::RelationalCondition);
+ void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
+ void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
- bool compileStrictEqForConstant(Node&, Edge value, JSValue constant);
+ bool compileStrictEqForConstant(Node*, Edge value, JSValue constant);
- bool compileStrictEq(Node&);
+ bool compileStrictEq(Node*);
- void compileAllocatePropertyStorage(Node&);
- void compileReallocatePropertyStorage(Node&);
+ void compileAllocatePropertyStorage(Node*);
+ void compileReallocatePropertyStorage(Node*);
#if USE(JSVALUE32_64)
template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
- void compileContiguousPutByVal(Node&, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
+ void compileContiguousPutByVal(Node*, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
#endif
- void compileDoublePutByVal(Node&, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
+ void compileDoublePutByVal(Node*, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
{
return arrayMode.mayStoreToHole();
}
GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
- GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node& node)
+ GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node* node)
{
- return temporaryRegisterForPutByVal(temporary, node.arrayMode());
+ return temporaryRegisterForPutByVal(temporary, node->arrayMode());
}
- void compileGetCharCodeAt(Node&);
- void compileGetByValOnString(Node&);
+ void compileGetCharCodeAt(Node*);
+ void compileGetByValOnString(Node*);
+ void compileFromCharCode(Node*);
- void compileGetByValOnArguments(Node&);
- void compileGetArgumentsLength(Node&);
+ void compileGetByValOnArguments(Node*);
+ void compileGetArgumentsLength(Node*);
- void compileGetArrayLength(Node&);
+ void compileGetArrayLength(Node*);
- void compileValueToInt32(Node&);
- void compileUInt32ToNumber(Node&);
- void compileDoubleAsInt32(Node&);
- void compileInt32ToDouble(Node&);
- void compileAdd(Node&);
- void compileArithSub(Node&);
- void compileArithNegate(Node&);
- void compileArithMul(Node&);
+ void compileValueToInt32(Node*);
+ void compileUInt32ToNumber(Node*);
+ void compileDoubleAsInt32(Node*);
+ void compileInt32ToDouble(Node*);
+ void compileAdd(Node*);
+ void compileMakeRope(Node*);
+ void compileArithSub(Node*);
+ void compileArithNegate(Node*);
+ void compileArithMul(Node*);
+ void compileArithIMul(Node*);
#if CPU(X86) || CPU(X86_64)
- void compileIntegerArithDivForX86(Node&);
+ void compileIntegerArithDivForX86(Node*);
+#elif CPU(APPLE_ARMV7S)
+ void compileIntegerArithDivForARMv7s(Node*);
#endif
- void compileArithMod(Node&);
- void compileSoftModulo(Node&);
- void compileGetIndexedPropertyStorage(Node&);
- void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySignedness);
- void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
- void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize);
- void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize);
- void compileNewFunctionNoCheck(Node&);
- void compileNewFunctionExpression(Node&);
- bool compileRegExpExec(Node&);
+ void compileArithMod(Node*);
+ void compileSoftModulo(Node*);
+ void compileGetIndexedPropertyStorage(Node*);
+ void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node*, size_t elementSize, TypedArraySignedness);
+ void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node*, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
+ void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node*, size_t elementSize);
+ void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node*, size_t elementSize);
+ void compileNewFunctionNoCheck(Node*);
+ void compileNewFunctionExpression(Node*);
+ bool compileRegExpExec(Node*);
// size can be an immediate or a register, and must be in bytes. If size is a register,
// it must be a different register than resultGPR. Emits code that place a pointer to
@@ -2362,17 +2010,10 @@ public:
template<typename SizeType>
MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
{
- CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator();
+ CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
-#if 0
- MacroAssembler::Jump done = m_jit.jump();
- slowPath1.link(&m_jit);
- m_jit.breakpoint();
- MacroAssembler::Jump slowPath = m_jit.jump();
- done.link(&m_jit);
-#endif
m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
m_jit.negPtr(resultGPR);
m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
@@ -2380,63 +2021,81 @@ public:
return slowPath;
}
- // It is NOT okay for the structure and the scratch register to be the same thing because if they are then the Structure will
- // get clobbered.
- template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType, typename StorageType>
- void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, StorageType storage, size_t size, MacroAssembler::JumpList& slowPath)
+ // Allocator for a cell of a specific size.
+ template <typename StructureType> // StructureType can be GPR or ImmPtr.
+ void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
+ GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
{
- MarkedAllocator* allocator = 0;
- if (destructorType == MarkedBlock::Normal)
- allocator = &m_jit.globalData()->heap.allocatorForObjectWithNormalDestructor(size);
- else if (destructorType == MarkedBlock::ImmortalStructure)
- allocator = &m_jit.globalData()->heap.allocatorForObjectWithImmortalStructureDestructor(size);
- else
- allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(size);
-
- m_jit.loadPtr(&allocator->m_freeList.head, resultGPR);
+ m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
// The object is half-allocated: we have what we know is a fresh object, but
// it's still on the GC's free list.
m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
- m_jit.storePtr(scratchGPR, &allocator->m_freeList.head);
+ m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()));
// Initialize the object's Structure.
m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSCell::structureOffset()));
+ }
+
+ // Allocator for an object of a specific size.
+ template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
+ void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
+ StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
+ {
+ emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath);
// Initialize the object's property storage pointer.
m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
}
- template<typename T>
- void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
+ // Convenience allocator for a buit-in object.
+ template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
+ void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
+ GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
{
- return emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None>(structure, resultGPR, scratchGPR, TrustedImmPtr(0), JSFinalObject::allocationSize(INLINE_STORAGE_CAPACITY), slowPath);
+ MarkedAllocator* allocator = 0;
+ size_t size = ClassType::allocationSize(0);
+ if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
+ allocator = &m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(size);
+ else if (ClassType::needsDestruction)
+ allocator = &m_jit.vm()->heap.allocatorForObjectWithNormalDestructor(size);
+ else
+ allocator = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(size);
+ m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
+ emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
}
-
- void emitAllocateJSArray(Structure*, GPRReg resultGPR, GPRReg storageGPR, unsigned numElements);
+
+ void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
#if USE(JSVALUE64)
JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp);
#elif USE(JSVALUE32_64)
JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result);
#endif
+
+ // Add a backward speculation check.
+ void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
+ void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
// Add a speculation check without additional recovery.
- void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail);
+ void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
+ // Add a speculation check without additional recovery, and with a promise to supply a jump later.
+ OSRExitJumpPlaceholder backwardSpeculationCheck(ExitKind, JSValueSource, Node*);
+ OSRExitJumpPlaceholder backwardSpeculationCheck(ExitKind, JSValueSource, Edge);
// Add a set of speculation checks without additional recovery.
- void speculationCheck(ExitKind, JSValueSource, NodeIndex, const MacroAssembler::JumpList& jumpsToFail);
+ void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
// Add a speculation check with additional recovery.
- void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
- void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
+ void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
+ void backwardSpeculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
// Use this like you would use speculationCheck(), except that you don't pass it a jump
// (because you don't have to execute a branch; that's kind of the whole point), and you
// must register the returned Watchpoint with something relevant. In general, this should
// be used with extreme care. Use speculationCheck() unless you've got an amazing reason
// not to.
- JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, NodeIndex);
+ JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, Node*);
// The default for speculation watchpoints is that they're uncounted, because the
// act of firing a watchpoint invalidates it. So, future recompilations will not
// attempt to set this watchpoint again.
@@ -2447,29 +2106,47 @@ public:
// Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies
// that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck().
- void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
- void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
- void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, SpeculationDirection);
- void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&, SpeculationDirection);
+ void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
+ void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
+ void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
+ void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
// Called when we statically determine that a speculation will fail.
- void terminateSpeculativeExecution(ExitKind, JSValueRegs, NodeIndex);
+ void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
- void terminateSpeculativeExecution(ExitKind, JSValueRegs, NodeIndex, SpeculationDirection);
- // Issue a forward speculation watchpoint, which will exit to the next instruction rather
- // than the current one.
- JumpReplacementWatchpoint* forwardSpeculationWatchpoint(ExitKind = UncountableWatchpoint);
- JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, SpeculationDirection);
+
+ // Helpers for performing type checks on an edge stored in the given registers.
+ bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_state.forNode(edge).m_type & ~typesPassedThrough; }
+ void backwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
+ void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
+ void forwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery&);
+
+ void speculateInt32(Edge);
+ void speculateNumber(Edge);
+ void speculateRealNumber(Edge);
+ void speculateBoolean(Edge);
+ void speculateCell(Edge);
+ void speculateObject(Edge);
+ void speculateObjectOrOther(Edge);
+ void speculateString(Edge);
+ template<typename StructureLocationType>
+ void speculateStringObjectForStructure(Edge, StructureLocationType);
+ void speculateStringObject(Edge, GPRReg);
+ void speculateStringObject(Edge);
+ void speculateStringOrStringObject(Edge);
+ void speculateNotCell(Edge);
+ void speculateOther(Edge);
+ void speculate(Node*, Edge);
const TypedArrayDescriptor* typedArrayDescriptor(ArrayMode);
- JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType, bool invert);
- JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, bool invert = false);
- void checkArray(Node&);
- void arrayify(Node&, GPRReg baseReg, GPRReg propertyReg);
- void arrayify(Node&);
+ JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType);
+ JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode);
+ void checkArray(Node*);
+ void arrayify(Node*, GPRReg baseReg, GPRReg propertyReg);
+ void arrayify(Node*);
template<bool strict>
- GPRReg fillSpeculateIntInternal(NodeIndex, DataFormat& returnFormat, SpeculationDirection);
+ GPRReg fillSpeculateIntInternal(Edge, DataFormat& returnFormat);
// It is possible, during speculative generation, to reach a situation in which we
// can statically determine a speculation will fail (for example, when two nodes
@@ -2485,9 +2162,9 @@ public:
return valueSourceReferenceForOperand(operand);
}
- void setNodeIndexForOperand(NodeIndex nodeIndex, int operand)
+ void setNodeForOperand(Node* node, int operand)
{
- valueSourceReferenceForOperand(operand) = ValueSource(nodeIndex);
+ valueSourceReferenceForOperand(operand) = ValueSource(MinifiedID(node));
}
// Call this with care, since it both returns a reference into an array
@@ -2518,7 +2195,11 @@ public:
// The current node being generated.
BlockIndex m_block;
- NodeIndex m_compileIndex;
+ Node* m_currentNode;
+ SpeculationDirection m_speculationDirection;
+#if !ASSERT_DISABLED
+ bool m_canExit;
+#endif
unsigned m_indexInBlock;
// Virtual and physical register maps.
Vector<GenerationInfo, 32> m_generationInfo;
@@ -2552,7 +2233,7 @@ public:
bool m_isCheckingArgumentTypes;
- Vector<SlowPathGenerator*, 8> m_slowPathGenerators; // doesn't use OwnPtr<> because I don't want to include DFGSlowPathGenerator.h
+ Vector<OwnPtr<SlowPathGenerator>, 8> m_slowPathGenerators;
Vector<SilentRegisterSavePlan> m_plans;
ValueRecovery computeValueRecoveryFor(const ValueSource&);
@@ -2566,7 +2247,7 @@ public:
// === Operand types ===
//
-// IntegerOperand, DoubleOperand and JSValueOperand.
+// IntegerOperand and JSValueOperand.
//
// These classes are used to lock the operands to a node into machine
// registers. These classes implement of pattern of locking a value
@@ -2577,17 +2258,17 @@ public:
class IntegerOperand {
public:
- explicit IntegerOperand(SpeculativeJIT* jit, Edge use)
+ explicit IntegerOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_gprOrInvalid(InvalidGPRReg)
#ifndef NDEBUG
, m_format(DataFormatNone)
#endif
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
- if (jit->isFilled(m_index))
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == KnownInt32Use);
+ if (jit->isFilled(edge.node()))
gpr();
}
@@ -2597,9 +2278,14 @@ public:
m_jit->unlock(m_gprOrInvalid);
}
- NodeIndex index() const
+ Edge edge() const
{
- return m_index;
+ return m_edge;
+ }
+
+ Node* node() const
+ {
+ return edge().node();
}
DataFormat format()
@@ -2612,77 +2298,27 @@ public:
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillInteger(index(), m_format);
+ m_gprOrInvalid = m_jit->fillInteger(m_edge, m_format);
return m_gprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
GPRReg m_gprOrInvalid;
DataFormat m_format;
};
-class DoubleOperand {
-public:
- explicit DoubleOperand(SpeculativeJIT* jit, Edge use)
- : m_jit(jit)
- , m_index(use.index())
- , m_fprOrInvalid(InvalidFPRReg)
- {
- ASSERT(m_jit);
-
- // This is counter-intuitive but correct. DoubleOperand is intended to
- // be used only when you're a node that is happy to accept an untyped
- // value, but will special-case for doubles (using DoubleOperand) if the
- // value happened to already be represented as a double. The implication
- // is that you will not try to force the value to become a double if it
- // is not one already.
- ASSERT(use.useKind() != DoubleUse);
-
- if (jit->isFilledDouble(m_index))
- fpr();
- }
-
- ~DoubleOperand()
- {
- ASSERT(m_fprOrInvalid != InvalidFPRReg);
- m_jit->unlock(m_fprOrInvalid);
- }
-
- NodeIndex index() const
- {
- return m_index;
- }
-
- FPRReg fpr()
- {
- if (m_fprOrInvalid == InvalidFPRReg)
- m_fprOrInvalid = m_jit->fillDouble(index());
- return m_fprOrInvalid;
- }
-
- void use()
- {
- m_jit->use(m_index);
- }
-
-private:
- SpeculativeJIT* m_jit;
- NodeIndex m_index;
- FPRReg m_fprOrInvalid;
-};
-
class JSValueOperand {
public:
- explicit JSValueOperand(SpeculativeJIT* jit, Edge use)
+ explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
#if USE(JSVALUE64)
, m_gprOrInvalid(InvalidGPRReg)
#elif USE(JSVALUE32_64)
@@ -2690,14 +2326,14 @@ public:
#endif
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
#if USE(JSVALUE64)
- if (jit->isFilled(m_index))
+ if (jit->isFilled(node()))
gpr();
#elif USE(JSVALUE32_64)
m_register.pair.tagGPR = InvalidGPRReg;
m_register.pair.payloadGPR = InvalidGPRReg;
- if (jit->isFilled(m_index))
+ if (jit->isFilled(node()))
fill();
#endif
}
@@ -2718,17 +2354,22 @@ public:
}
#endif
}
+
+ Edge edge() const
+ {
+ return m_edge;
+ }
- NodeIndex index() const
+ Node* node() const
{
- return m_index;
+ return edge().node();
}
#if USE(JSVALUE64)
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillJSValue(index());
+ m_gprOrInvalid = m_jit->fillJSValue(m_edge);
return m_gprOrInvalid;
}
JSValueRegs jsValueRegs()
@@ -2741,7 +2382,7 @@ public:
void fill()
{
if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
- m_isDouble = !m_jit->fillJSValue(index(), m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
+ m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
}
GPRReg tagGPR()
@@ -2773,12 +2414,12 @@ public:
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
#if USE(JSVALUE64)
GPRReg m_gprOrInvalid;
#elif USE(JSVALUE32_64)
@@ -2795,14 +2436,14 @@ private:
class StorageOperand {
public:
- explicit StorageOperand(SpeculativeJIT* jit, Edge use)
+ explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
- if (jit->isFilled(m_index))
+ ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
+ if (jit->isFilled(node()))
gpr();
}
@@ -2812,26 +2453,31 @@ public:
m_jit->unlock(m_gprOrInvalid);
}
- NodeIndex index() const
+ Edge edge() const
{
- return m_index;
+ return m_edge;
+ }
+
+ Node* node() const
+ {
+ return edge().node();
}
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillStorage(index());
+ m_gprOrInvalid = m_jit->fillStorage(edge());
return m_gprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
GPRReg m_gprOrInvalid;
};
@@ -2883,8 +2529,6 @@ private:
class FPRTemporary {
public:
FPRTemporary(SpeculativeJIT*);
- FPRTemporary(SpeculativeJIT*, DoubleOperand&);
- FPRTemporary(SpeculativeJIT*, DoubleOperand&, DoubleOperand&);
FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
#if USE(JSVALUE32_64)
@@ -2965,18 +2609,17 @@ private:
class SpeculateIntegerOperand {
public:
- explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
+ explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_gprOrInvalid(InvalidGPRReg)
#ifndef NDEBUG
, m_format(DataFormatNone)
#endif
- , m_direction(direction)
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
- if (jit->isFilled(m_index))
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
+ if (jit->isFilled(node()))
gpr();
}
@@ -2985,10 +2628,15 @@ public:
ASSERT(m_gprOrInvalid != InvalidGPRReg);
m_jit->unlock(m_gprOrInvalid);
}
+
+ Edge edge() const
+ {
+ return m_edge;
+ }
- NodeIndex index() const
+ Node* node() const
{
- return m_index;
+ return edge().node();
}
DataFormat format()
@@ -3001,33 +2649,32 @@ public:
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillSpeculateInt(index(), m_format, m_direction);
+ m_gprOrInvalid = m_jit->fillSpeculateInt(edge(), m_format);
return m_gprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
GPRReg m_gprOrInvalid;
DataFormat m_format;
- SpeculationDirection m_direction;
};
class SpeculateStrictInt32Operand {
public:
- explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge use)
+ explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
- if (jit->isFilled(m_index))
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
+ if (jit->isFilled(node()))
gpr();
}
@@ -3036,41 +2683,45 @@ public:
ASSERT(m_gprOrInvalid != InvalidGPRReg);
m_jit->unlock(m_gprOrInvalid);
}
+
+ Edge edge() const
+ {
+ return m_edge;
+ }
- NodeIndex index() const
+ Node* node() const
{
- return m_index;
+ return edge().node();
}
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillSpeculateIntStrict(index());
+ m_gprOrInvalid = m_jit->fillSpeculateIntStrict(edge());
return m_gprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
GPRReg m_gprOrInvalid;
};
class SpeculateDoubleOperand {
public:
- explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
+ explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_fprOrInvalid(InvalidFPRReg)
- , m_direction(direction)
{
ASSERT(m_jit);
- ASSERT(use.useKind() == DoubleUse);
- if (jit->isFilled(m_index))
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == NumberUse || edge.useKind() == KnownNumberUse || edge.useKind() == RealNumberUse));
+ if (jit->isFilled(node()))
fpr();
}
@@ -3079,86 +2730,98 @@ public:
ASSERT(m_fprOrInvalid != InvalidFPRReg);
m_jit->unlock(m_fprOrInvalid);
}
+
+ Edge edge() const
+ {
+ return m_edge;
+ }
- NodeIndex index() const
+ Node* node() const
{
- return m_index;
+ return edge().node();
}
FPRReg fpr()
{
if (m_fprOrInvalid == InvalidFPRReg)
- m_fprOrInvalid = m_jit->fillSpeculateDouble(index(), m_direction);
+ m_fprOrInvalid = m_jit->fillSpeculateDouble(edge());
return m_fprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
FPRReg m_fprOrInvalid;
- SpeculationDirection m_direction;
};
class SpeculateCellOperand {
public:
- explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
+ explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_gprOrInvalid(InvalidGPRReg)
- , m_direction(direction)
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
- if (jit->isFilled(m_index))
+ if (!edge)
+ return;
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == CellUse || edge.useKind() == KnownCellUse || edge.useKind() == ObjectUse || edge.useKind() == StringUse || edge.useKind() == KnownStringUse || edge.useKind() == StringObjectUse || edge.useKind() == StringOrStringObjectUse));
+ if (jit->isFilled(node()))
gpr();
}
~SpeculateCellOperand()
{
+ if (!m_edge)
+ return;
ASSERT(m_gprOrInvalid != InvalidGPRReg);
m_jit->unlock(m_gprOrInvalid);
}
+
+ Edge edge() const
+ {
+ return m_edge;
+ }
- NodeIndex index() const
+ Node* node() const
{
- return m_index;
+ return edge().node();
}
GPRReg gpr()
{
+ ASSERT(m_edge);
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillSpeculateCell(index(), m_direction);
+ m_gprOrInvalid = m_jit->fillSpeculateCell(edge());
return m_gprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ ASSERT(m_edge);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
GPRReg m_gprOrInvalid;
- SpeculationDirection m_direction;
};
class SpeculateBooleanOperand {
public:
- explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge use, SpeculationDirection direction = BackwardSpeculation)
+ explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
: m_jit(jit)
- , m_index(use.index())
+ , m_edge(edge)
, m_gprOrInvalid(InvalidGPRReg)
- , m_direction(direction)
{
ASSERT(m_jit);
- ASSERT(use.useKind() != DoubleUse);
- if (jit->isFilled(m_index))
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
+ if (jit->isFilled(node()))
gpr();
}
@@ -3168,30 +2831,57 @@ public:
m_jit->unlock(m_gprOrInvalid);
}
- NodeIndex index() const
+ Edge edge() const
{
- return m_index;
+ return m_edge;
+ }
+
+ Node* node() const
+ {
+ return edge().node();
}
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillSpeculateBoolean(index(), m_direction);
+ m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge());
return m_gprOrInvalid;
}
void use()
{
- m_jit->use(m_index);
+ m_jit->use(node());
}
private:
SpeculativeJIT* m_jit;
- NodeIndex m_index;
+ Edge m_edge;
GPRReg m_gprOrInvalid;
- SpeculationDirection m_direction;
};
+template<typename StructureLocationType>
+void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
+{
+ Structure* stringObjectStructure =
+ m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure();
+ Structure* stringPrototypeStructure = stringObjectStructure->storedPrototype().asCell()->structure();
+ ASSERT(stringPrototypeStructure->transitionWatchpointSetIsStillValid());
+
+ if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure()))) {
+ speculationCheck(
+ NotStringObject, JSValueRegs(), 0,
+ m_jit.branchPtr(
+ JITCompiler::NotEqual, structureLocation, TrustedImmPtr(stringObjectStructure)));
+ }
+ stringPrototypeStructure->addTransitionWatchpoint(speculationWatchpoint(NotStringObject));
+}
+
+#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
+ if (!needsTypeCheck((edge), (typesPassedThrough))) \
+ break; \
+ typeCheck((source), (edge), (typesPassedThrough), (jumpToFail)); \
+ } while (0)
+
} } // namespace JSC::DFG
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index fce151ef2..1d213c6fe 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,29 +34,31 @@
#include "DFGSlowPathGenerator.h"
#include "JSActivation.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
namespace JSC { namespace DFG {
#if USE(JSVALUE32_64)
-GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
+GPRReg SpeculativeJIT::fillInteger(Edge edge, DataFormat& returnFormat)
{
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ ASSERT(!needsTypeCheck(edge, SpecInt32));
+
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
if (info.registerFormat() == DataFormatNone) {
GPRReg gpr = allocate();
- if (node.hasConstant()) {
+ if (edge->hasConstant()) {
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- if (isInt32Constant(nodeIndex))
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
- else if (isNumberConstant(nodeIndex))
- ASSERT_NOT_REACHED();
+ if (isInt32Constant(edge.node()))
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
+ else if (isNumberConstant(edge.node()))
+ RELEASE_ASSERT_NOT_REACHED();
else {
- ASSERT(isJSConstant(nodeIndex));
- JSValue jsValue = valueOfJSConstant(nodeIndex);
+ ASSERT(isJSConstant(edge.node()));
+ JSValue jsValue = valueOfJSConstant(edge.node());
m_jit.move(MacroAssembler::Imm32(jsValue.payload()), gpr);
}
} else {
@@ -82,7 +84,7 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat
case DataFormatJSBoolean:
case DataFormatStorage:
// Should only be calling this function if we know this operand to be integer.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case DataFormatJSInteger: {
GPRReg tagGPR = info.tagGPR();
@@ -108,156 +110,30 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-FPRReg SpeculativeJIT::fillDouble(NodeIndex nodeIndex)
-{
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
-
- if (info.registerFormat() == DataFormatNone) {
-
- if (node.hasConstant()) {
- if (isInt32Constant(nodeIndex)) {
- // FIXME: should not be reachable?
- GPRReg gpr = allocate();
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
- m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- info.fillInteger(*m_stream, gpr);
- unlock(gpr);
- } else if (isNumberConstant(nodeIndex)) {
- FPRReg fpr = fprAllocate();
- m_jit.loadDouble(addressOfDoubleConstant(nodeIndex), fpr);
- m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
- info.fillDouble(*m_stream, fpr);
- return fpr;
- } else {
- // FIXME: should not be reachable?
- ASSERT_NOT_REACHED();
- }
- } else {
- DataFormat spillFormat = info.spillFormat();
- ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
- if (spillFormat == DataFormatJSDouble) {
- FPRReg fpr = fprAllocate();
- m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
- m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
- info.fillDouble(*m_stream, fpr);
- return fpr;
- }
-
- FPRReg fpr = fprAllocate();
- JITCompiler::Jump hasUnboxedDouble;
-
- if (spillFormat != DataFormatJSInteger && spillFormat != DataFormatInteger) {
- JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag));
- m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
- hasUnboxedDouble = m_jit.jump();
- isInteger.link(&m_jit);
- }
-
- m_jit.convertInt32ToDouble(JITCompiler::payloadFor(virtualRegister), fpr);
-
- if (hasUnboxedDouble.isSet())
- hasUnboxedDouble.link(&m_jit);
-
- m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
- info.fillDouble(*m_stream, fpr);
- return fpr;
- }
- }
-
- switch (info.registerFormat()) {
- case DataFormatNone:
- // Should have filled, above.
- case DataFormatCell:
- case DataFormatJSCell:
- case DataFormatBoolean:
- case DataFormatJSBoolean:
- case DataFormatStorage:
- // Should only be calling this function if we know this operand to be numeric.
- ASSERT_NOT_REACHED();
-
- case DataFormatJSInteger:
- case DataFormatJS: {
- GPRReg tagGPR = info.tagGPR();
- GPRReg payloadGPR = info.payloadGPR();
- FPRReg fpr = fprAllocate();
- m_gprs.lock(tagGPR);
- m_gprs.lock(payloadGPR);
-
- JITCompiler::Jump hasUnboxedDouble;
-
- if (info.registerFormat() != DataFormatJSInteger) {
- FPRTemporary scratch(this);
- JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
- m_jit.jitAssertIsJSDouble(tagGPR);
- unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
- hasUnboxedDouble = m_jit.jump();
- isInteger.link(&m_jit);
- }
-
- m_jit.convertInt32ToDouble(payloadGPR, fpr);
-
- if (hasUnboxedDouble.isSet())
- hasUnboxedDouble.link(&m_jit);
-
- m_gprs.release(tagGPR);
- m_gprs.release(payloadGPR);
- m_gprs.unlock(tagGPR);
- m_gprs.unlock(payloadGPR);
- m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
- info.fillDouble(*m_stream, fpr);
- info.killSpilled();
- return fpr;
- }
-
- case DataFormatInteger: {
- FPRReg fpr = fprAllocate();
- GPRReg gpr = info.gpr();
- m_gprs.lock(gpr);
- m_jit.convertInt32ToDouble(gpr, fpr);
- m_gprs.unlock(gpr);
- return fpr;
- }
-
- case DataFormatJSDouble:
- case DataFormatDouble: {
- FPRReg fpr = info.fpr();
- m_fprs.lock(fpr);
- return fpr;
- }
-
- default:
- ASSERT_NOT_REACHED();
- return InvalidFPRReg;
- }
-}
-
-bool SpeculativeJIT::fillJSValue(NodeIndex nodeIndex, GPRReg& tagGPR, GPRReg& payloadGPR, FPRReg& fpr)
+bool SpeculativeJIT::fillJSValue(Edge edge, GPRReg& tagGPR, GPRReg& payloadGPR, FPRReg& fpr)
{
// FIXME: For double we could fill with a FPR.
UNUSED_PARAM(fpr);
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
- if (node.hasConstant()) {
+ if (edge->hasConstant()) {
tagGPR = allocate();
payloadGPR = allocate();
- m_jit.move(Imm32(valueOfJSConstant(nodeIndex).tag()), tagGPR);
- m_jit.move(Imm32(valueOfJSConstant(nodeIndex).payload()), payloadGPR);
+ m_jit.move(Imm32(valueOfJSConstant(edge.node()).tag()), tagGPR);
+ m_jit.move(Imm32(valueOfJSConstant(edge.node()).payload()), payloadGPR);
m_gprs.retain(tagGPR, virtualRegister, SpillOrderConstant);
m_gprs.retain(payloadGPR, virtualRegister, SpillOrderConstant);
- info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(nodeIndex) ? DataFormatJSInteger : DataFormatJS);
+ info.fillJSValue(*m_stream, tagGPR, payloadGPR, isInt32Constant(edge.node()) ? DataFormatJSInteger : DataFormatJS);
} else {
DataFormat spillFormat = info.spillFormat();
ASSERT(spillFormat != DataFormatNone && spillFormat != DataFormatStorage);
@@ -318,7 +194,7 @@ bool SpeculativeJIT::fillJSValue(NodeIndex nodeIndex, GPRReg& tagGPR, GPRReg& pa
fillFormat = DataFormatJSBoolean;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
m_jit.move(TrustedImm32(tag), tagGPR);
@@ -357,131 +233,17 @@ bool SpeculativeJIT::fillJSValue(NodeIndex nodeIndex, GPRReg& tagGPR, GPRReg& pa
case DataFormatStorage:
// this type currently never occurs
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return true;
}
}
-class ValueToNumberSlowPathGenerator
- : public CallSlowPathGenerator<MacroAssembler::Jump, D_DFGOperation_EJ, JSValueRegs> {
-public:
- ValueToNumberSlowPathGenerator(
- MacroAssembler::Jump from, SpeculativeJIT* jit,
- GPRReg resultTagGPR, GPRReg resultPayloadGPR, GPRReg jsValueTagGPR, GPRReg jsValuePayloadGPR)
- : CallSlowPathGenerator<MacroAssembler::Jump, D_DFGOperation_EJ, JSValueRegs>(
- from, jit, dfgConvertJSValueToNumber, NeedToSpill, JSValueRegs(resultTagGPR, resultPayloadGPR))
- , m_jsValueTagGPR(jsValueTagGPR)
- , m_jsValuePayloadGPR(jsValuePayloadGPR)
- {
- }
-
-protected:
- virtual void generateInternal(SpeculativeJIT* jit)
- {
- setUp(jit);
- recordCall(jit->callOperation(dfgConvertJSValueToNumber, FPRInfo::returnValueFPR, m_jsValueTagGPR, m_jsValuePayloadGPR));
- jit->boxDouble(FPRInfo::returnValueFPR, m_result.tagGPR(), m_result.payloadGPR());
- tearDown(jit);
- }
-
-private:
- GPRReg m_jsValueTagGPR;
- GPRReg m_jsValuePayloadGPR;
-};
-
-void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
+void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node* node)
{
- if (isKnownNumeric(node.child1().index())) {
- JSValueOperand op1(this, node.child1());
- op1.fill();
- if (op1.isDouble()) {
- FPRTemporary result(this, op1);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
- } else {
- GPRTemporary resultTag(this, op1);
- GPRTemporary resultPayload(this, op1, false);
- m_jit.move(op1.tagGPR(), resultTag.gpr());
- m_jit.move(op1.payloadGPR(), resultPayload.gpr());
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
- }
- return;
- }
-
- JSValueOperand op1(this, node.child1());
- GPRTemporary resultTag(this, op1);
- GPRTemporary resultPayload(this, op1, false);
-
- ASSERT(!isInt32Constant(node.child1().index()));
- ASSERT(!isNumberConstant(node.child1().index()));
-
- GPRReg tagGPR = op1.tagGPR();
- GPRReg payloadGPR = op1.payloadGPR();
- GPRReg resultTagGPR = resultTag.gpr();
- GPRReg resultPayloadGPR = resultPayload.gpr();
- op1.use();
-
- JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
- JITCompiler::Jump nonNumeric = m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag));
-
- isInteger.link(&m_jit);
- m_jit.move(tagGPR, resultTagGPR);
- m_jit.move(payloadGPR, resultPayloadGPR);
-
- addSlowPathGenerator(adoptPtr(new ValueToNumberSlowPathGenerator(nonNumeric, this, resultTagGPR, resultPayloadGPR, tagGPR, payloadGPR)));
-
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
-}
-
-void SpeculativeJIT::nonSpeculativeValueToInt32(Node& node)
-{
- ASSERT(!isInt32Constant(node.child1().index()));
-
- if (isKnownInteger(node.child1().index())) {
- IntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- m_jit.move(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
- return;
- }
-
- GenerationInfo& childInfo = m_generationInfo[at(node.child1()).virtualRegister()];
- if (childInfo.isJSDouble()) {
- DoubleOperand op1(this, node.child1());
- GPRTemporary result(this);
- FPRReg fpr = op1.fpr();
- GPRReg gpr = result.gpr();
- op1.use();
- JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
-
- addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
-
- integerResult(gpr, m_compileIndex, UseChildrenCalledExplicitly);
- return;
- }
-
- JSValueOperand op1(this, node.child1());
- GPRTemporary result(this);
- GPRReg tagGPR = op1.tagGPR();
- GPRReg payloadGPR = op1.payloadGPR();
- GPRReg resultGPR = result.gpr();
- op1.use();
-
- JITCompiler::Jump isNotInteger = m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag));
-
- m_jit.move(payloadGPR, resultGPR);
-
- addSlowPathGenerator(slowPathCall(isNotInteger, this, dfgConvertJSValueToInt32, resultGPR, tagGPR, payloadGPR));
-
- integerResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
-}
-
-void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node)
-{
- IntegerOperand op1(this, node.child1());
+ IntegerOperand op1(this, node->child1());
FPRTemporary boxer(this);
GPRTemporary resultTag(this, op1);
GPRTemporary resultPayload(this);
@@ -503,13 +265,13 @@ void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node)
done.link(&m_jit);
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
}
void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
{
JITCompiler::DataLabelPtr structureToCompare;
- JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+ JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(unusedPointer)));
JITCompiler::ConvertibleLoadLabel propertyStorageLoad = m_jit.convertibleLoadPtr(JITCompiler::Address(basePayloadGPR, JSObject::butterflyOffset()), resultPayloadGPR);
JITCompiler::DataLabelCompact tagLoadWithPatch = m_jit.load32WithCompactAddressOffsetPatch(JITCompiler::Address(resultPayloadGPR, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
@@ -564,7 +326,7 @@ void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseTagGPROrNon
void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
{
JITCompiler::DataLabelPtr structureToCompare;
- JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+ JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(basePayloadGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(unusedPointer)));
writeBarrier(basePayloadGPR, valueTagGPR, valueUse, WriteBarrierForPropertyAccess, scratchGPR);
@@ -574,7 +336,7 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR,
JITCompiler::Label doneLabel = m_jit.label();
V_DFGOperation_EJCI optimizedCall;
- if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) {
+ if (m_jit.strictModeFor(m_currentNode->codeOrigin)) {
if (putKind == Direct)
optimizedCall = operationPutByIdDirectStrictOptimize;
else
@@ -624,15 +386,21 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
GPRReg resultPayloadGPR = resultPayload.gpr();
JITCompiler::Jump notCell;
- if (!isKnownCell(operand.index()))
- notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
-
JITCompiler::Jump notMasqueradesAsUndefined;
- if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
+
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultPayloadGPR);
notMasqueradesAsUndefined = m_jit.jump();
} else {
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
+
m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultPayloadGPR);
JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(resultPayloadGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined));
@@ -640,16 +408,14 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
notMasqueradesAsUndefined = m_jit.jump();
isMasqueradesAsUndefined.link(&m_jit);
- GPRTemporary localGlobalObject(this);
- GPRTemporary remoteGlobalObject(this);
GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
- m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)), localGlobalObjectGPR);
m_jit.loadPtr(JITCompiler::Address(resultPayloadGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultPayloadGPR);
}
- if (!isKnownCell(operand.index())) {
+ if (!isKnownCell(operand.node())) {
JITCompiler::Jump done = m_jit.jump();
notCell.link(&m_jit);
@@ -664,14 +430,13 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
notMasqueradesAsUndefined.link(&m_jit);
- booleanResult(resultPayloadGPR, m_compileIndex);
+ booleanResult(resultPayloadGPR, m_currentNode);
}
-void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex branchNodeIndex, bool invert)
+void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
if (taken == nextBlock()) {
invert = !invert;
@@ -686,29 +451,33 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex br
GPRTemporary result(this, arg);
GPRReg resultGPR = result.gpr();
-
+
JITCompiler::Jump notCell;
-
- if (!isKnownCell(operand.index()))
- notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
-
- if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+
+ if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
+
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
jump(invert ? taken : notTaken, ForceJump);
} else {
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branch32(MacroAssembler::NotEqual, argTagGPR, TrustedImm32(JSValue::CellTag));
+
m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureOffset()), resultGPR);
branchTest8(JITCompiler::Zero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), invert ? taken : notTaken);
- GPRTemporary localGlobalObject(this);
- GPRTemporary remoteGlobalObject(this);
GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
- m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)), localGlobalObjectGPR);
m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, invert ? notTaken : taken);
}
- if (!isKnownCell(operand.index())) {
+ if (!isKnownCell(operand.node())) {
jump(notTaken, ForceJump);
notCell.link(&m_jit);
@@ -722,20 +491,20 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex br
jump(notTaken);
}
-bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, Edge operand, bool invert)
+bool SpeculativeJIT::nonSpeculativeCompareNull(Node* node, Edge operand, bool invert)
{
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
- ASSERT(node.adjustedRefCount() == 1);
+ ASSERT(node->adjustedRefCount() == 1);
- nonSpeculativePeepholeBranchNull(operand, branchNodeIndex, invert);
+ nonSpeculativePeepholeBranchNull(operand, branchNode, invert);
- use(node.child1());
- use(node.child2());
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
@@ -745,11 +514,10 @@ bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, Edge operand, bool in
return false;
}
-void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
+void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
@@ -763,8 +531,8 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
notTaken = tmp;
}
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1TagGPR = arg1.tagGPR();
GPRReg arg1PayloadGPR = arg1.payloadGPR();
GPRReg arg2TagGPR = arg2.tagGPR();
@@ -772,7 +540,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
+ if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -790,14 +558,14 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1().index()))
+ if (!isKnownInteger(node->child1().node()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg1TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
- if (!isKnownInteger(node.child2().index()))
+ if (!isKnownInteger(node->child2().node()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg2TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
branch32(cond, arg1PayloadGPR, arg2PayloadGPR, taken);
- if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
+ if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
jump(notTaken, ForceJump);
slowPath.link(&m_jit);
@@ -813,7 +581,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
jump(notTaken);
m_indexInBlock = m_jit.graph().m_blocks[m_block]->size() - 1;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
}
template<typename JumpType>
@@ -852,10 +620,10 @@ private:
GPRReg m_arg2Payload;
};
-void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
+void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
{
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1TagGPR = arg1.tagGPR();
GPRReg arg1PayloadGPR = arg1.payloadGPR();
GPRReg arg2TagGPR = arg2.tagGPR();
@@ -863,7 +631,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
+ if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
GPRResult result(this);
GPRReg resultPayloadGPR = result.gpr();
@@ -873,7 +641,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
flushRegisters();
callOperation(helperFunction, resultPayloadGPR, arg1TagGPR, arg1PayloadGPR, arg2TagGPR, arg2PayloadGPR);
- booleanResult(resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
} else {
GPRTemporary resultPayload(this, arg1, false);
GPRReg resultPayloadGPR = resultPayload.gpr();
@@ -881,29 +649,28 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1().index()))
+ if (!isKnownInteger(node->child1().node()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg1TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
- if (!isKnownInteger(node.child2().index()))
+ if (!isKnownInteger(node->child2().node()))
slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg2TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
m_jit.compare32(cond, arg1PayloadGPR, arg2PayloadGPR, resultPayloadGPR);
- if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
+ if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
addSlowPathGenerator(adoptPtr(
new CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>(
slowPath, this, helperFunction, resultPayloadGPR, arg1TagGPR,
arg1PayloadGPR, arg2TagGPR, arg2PayloadGPR)));
}
- booleanResult(resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
}
}
-void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert)
+void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
// The branch instruction will branch to the taken block.
// If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
@@ -914,8 +681,8 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
notTaken = tmp;
}
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1TagGPR = arg1.tagGPR();
GPRReg arg1PayloadGPR = arg1.payloadGPR();
GPRReg arg2TagGPR = arg2.tagGPR();
@@ -927,7 +694,7 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
arg1.use();
arg2.use();
- if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
+ if (isKnownCell(node->child1().node()) && isKnownCell(node->child2().node())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
branchPtr(JITCompiler::Equal, arg1PayloadGPR, arg2PayloadGPR, invert ? notTaken : taken);
@@ -950,10 +717,10 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
jump(notTaken);
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
+void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node* node, bool invert)
{
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1TagGPR = arg1.tagGPR();
GPRReg arg1PayloadGPR = arg1.payloadGPR();
GPRReg arg2TagGPR = arg2.tagGPR();
@@ -965,7 +732,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
arg1.use();
arg2.use();
- if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
+ if (isKnownCell(node->child1().node()) && isKnownCell(node->child2().node())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
// FIXME: this should flush registers instead of silent spill/fill.
@@ -993,21 +760,21 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
m_jit.andPtr(JITCompiler::TrustedImm32(1), resultPayloadGPR);
}
- booleanResult(resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::emitCall(Node& node)
+void SpeculativeJIT::emitCall(Node* node)
{
- if (node.op() != Call)
- ASSERT(node.op() == Construct);
+ if (node->op() != Call)
+ ASSERT(node->op() == Construct);
// For constructors, the this argument is not passed but we have to make space
// for it.
- int dummyThisArgument = node.op() == Call ? 0 : 1;
+ int dummyThisArgument = node->op() == Call ? 0 : 1;
- CallLinkInfo::CallType callType = node.op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
+ CallLinkInfo::CallType callType = node->op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
- Edge calleeEdge = m_jit.graph().m_varArgChildren[node.firstChild()];
+ Edge calleeEdge = m_jit.graph().m_varArgChildren[node->firstChild()];
JSValueOperand callee(this, calleeEdge);
GPRReg calleeTagGPR = callee.tagGPR();
GPRReg calleePayloadGPR = callee.payloadGPR();
@@ -1015,7 +782,7 @@ void SpeculativeJIT::emitCall(Node& node)
// The call instruction's first child is either the function (normal call) or the
// receiver (method call). subsequent children are the arguments.
- int numPassedArgs = node.numChildren() - 1;
+ int numPassedArgs = node->numChildren() - 1;
m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs + dummyThisArgument), callFramePayloadSlot(JSStack::ArgumentCount));
m_jit.storePtr(GPRInfo::callFrameRegister, callFramePayloadSlot(JSStack::CallerFrame));
@@ -1023,7 +790,7 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.store32(calleeTagGPR, callFrameTagSlot(JSStack::Callee));
for (int i = 0; i < numPassedArgs; i++) {
- Edge argEdge = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i];
+ Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
JSValueOperand arg(this, argEdge);
GPRReg argTagGPR = arg.tagGPR();
GPRReg argPayloadGPR = arg.payloadGPR();
@@ -1044,7 +811,7 @@ void SpeculativeJIT::emitCall(Node& node)
JITCompiler::JumpList slowPath;
CallBeginToken token;
- m_jit.beginCall(node.codeOrigin, token);
+ m_jit.beginCall(node->codeOrigin, token);
m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
@@ -1054,7 +821,7 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.storePtr(resultPayloadGPR, MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
- CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
+ CodeOrigin codeOrigin = node->codeOrigin;
JITCompiler::Call fastCall = m_jit.nearCall();
m_jit.notifyCall(fastCall, codeOrigin, token);
@@ -1081,35 +848,36 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.setupResults(resultPayloadGPR, resultTagGPR);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, DataFormatJS, UseChildrenCalledExplicitly);
- m_jit.addJSCall(fastCall, slowCall, targetToCheck, callType, calleePayloadGPR, at(m_compileIndex).codeOrigin);
+ m_jit.addJSCall(fastCall, slowCall, targetToCheck, callType, calleePayloadGPR, node->codeOrigin);
}
template<bool strict>
-GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateIntInternal(Edge edge, DataFormat& returnFormat)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecInt@%d ", nodeIndex);
+ dataLogF("SpecInt@%d ", edge->index());
#endif
- if (isKnownNotInteger(nodeIndex)) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
- returnFormat = DataFormatInteger;
- return allocate();
- }
-
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
+ value.filter(SpecInt32);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
-
- if (node.hasConstant()) {
- ASSERT(isInt32Constant(nodeIndex));
+ if ((edge->hasConstant() && !isInt32Constant(edge.node())) || info.spillFormat() == DataFormatDouble) {
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ returnFormat = DataFormatInteger;
+ return allocate();
+ }
+
+ if (edge->hasConstant()) {
+ ASSERT(isInt32Constant(edge.node()));
GPRReg gpr = allocate();
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
info.fillInteger(*m_stream, gpr);
returnFormat = DataFormatInteger;
@@ -1120,8 +888,8 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
ASSERT_UNUSED(spillFormat, (spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
// If we know this was spilled as an integer we can fill without checking.
- if (!isInt32Speculation(type))
- speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)), direction);
+ if (type & ~SpecInt32)
+ speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
GPRReg gpr = allocate();
m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
@@ -1138,8 +906,8 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
GPRReg payloadGPR = info.payloadGPR();
m_gprs.lock(tagGPR);
m_gprs.lock(payloadGPR);
- if (!isInt32Speculation(type))
- speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)), direction);
+ if (type & ~SpecInt32)
+ speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)));
m_gprs.unlock(tagGPR);
m_gprs.release(tagGPR);
m_gprs.release(payloadGPR);
@@ -1163,60 +931,61 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
case DataFormatJSDouble:
case DataFormatJSCell:
case DataFormatJSBoolean:
- case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ returnFormat = DataFormatInteger;
+ return allocate();
+ case DataFormatStorage:
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateInt(Edge edge, DataFormat& returnFormat)
{
- return fillSpeculateIntInternal<false>(nodeIndex, returnFormat, direction);
+ return fillSpeculateIntInternal<false>(edge, returnFormat);
}
-GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
+GPRReg SpeculativeJIT::fillSpeculateIntStrict(Edge edge)
{
DataFormat mustBeDataFormatInteger;
- GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger, BackwardSpeculation);
+ GPRReg result = fillSpeculateIntInternal<true>(edge, mustBeDataFormatInteger);
ASSERT(mustBeDataFormatInteger == DataFormatInteger);
return result;
}
-FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirection direction)
+FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecDouble@%d ", nodeIndex);
+ dataLogF("SpecDouble@%d ", edge->index());
#endif
- if (isKnownNotNumber(nodeIndex)) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
- return fprAllocate();
- }
-
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber));
+ value.filter(SpecNumber);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
if (info.registerFormat() == DataFormatNone) {
- if (node.hasConstant()) {
- if (isInt32Constant(nodeIndex)) {
+ if (edge->hasConstant()) {
+ if (isInt32Constant(edge.node())) {
GPRReg gpr = allocate();
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
info.fillInteger(*m_stream, gpr);
unlock(gpr);
- } else if (isNumberConstant(nodeIndex)) {
+ } else if (isNumberConstant(edge.node())) {
FPRReg fpr = fprAllocate();
- m_jit.loadDouble(addressOfDoubleConstant(nodeIndex), fpr);
+ m_jit.loadDouble(addressOfDoubleConstant(edge.node()), fpr);
m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
info.fillDouble(*m_stream, fpr);
return fpr;
- } else
- ASSERT_NOT_REACHED();
+ } else {
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ return fprAllocate();
+ }
} else {
DataFormat spillFormat = info.spillFormat();
ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
@@ -1233,8 +1002,8 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
if (spillFormat != DataFormatJSInteger && spillFormat != DataFormatInteger) {
JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag));
- if (!isNumberSpeculation(type))
- speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)), direction);
+ if (type & ~SpecNumber)
+ speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::LowestTag)));
m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
hasUnboxedDouble = m_jit.jump();
@@ -1268,8 +1037,8 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
if (info.registerFormat() != DataFormatJSInteger) {
FPRTemporary scratch(this);
JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
- if (!isNumberSpeculation(type))
- speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)), direction);
+ if (type & ~SpecNumber)
+ speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
hasUnboxedDouble = m_jit.jump();
isInteger.link(&m_jit);
@@ -1308,49 +1077,52 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
case DataFormatNone:
case DataFormatStorage:
+ RELEASE_ASSERT_NOT_REACHED();
+
case DataFormatCell:
case DataFormatJSCell:
case DataFormatBoolean:
case DataFormatJSBoolean:
- ASSERT_NOT_REACHED();
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ return fprAllocate();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidFPRReg;
}
}
-GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecCell@%d ", nodeIndex);
+ dataLogF("SpecCell@%d ", edge->index());
#endif
- if (isKnownNotCell(nodeIndex)) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
- return allocate();
- }
-
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
+ value.filter(SpecCell);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
- if (node.hasConstant()) {
- JSValue jsValue = valueOfJSConstant(nodeIndex);
- ASSERT(jsValue.isCell());
+ if (edge->hasConstant()) {
+ JSValue jsValue = valueOfJSConstant(edge.node());
GPRReg gpr = allocate();
- m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
- info.fillCell(*m_stream, gpr);
+ if (jsValue.isCell()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
+ info.fillCell(*m_stream, gpr);
+ return gpr;
+ }
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return gpr;
}
ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatCell);
- if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)), direction);
+ if (type & ~SpecCell)
+ speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)));
GPRReg gpr = allocate();
m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
@@ -1370,8 +1142,8 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirecti
GPRReg payloadGPR = info.payloadGPR();
m_gprs.lock(tagGPR);
m_gprs.lock(payloadGPR);
- if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)), direction);
+ if (type & ~SpecCell)
+ speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)));
m_gprs.unlock(tagGPR);
m_gprs.release(tagGPR);
m_gprs.release(payloadGPR);
@@ -1386,47 +1158,53 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirecti
case DataFormatDouble:
case DataFormatJSBoolean:
case DataFormatBoolean:
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ return allocate();
+
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecBool@%d ", nodeIndex);
+ dataLogF("SpecBool@%d ", edge.node()->index());
#endif
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = m_jit.graph()[nodeIndex];
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ value.filter(SpecBoolean);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
- if ((node.hasConstant() && !valueOfJSConstant(nodeIndex).isBoolean())
- || !(info.isJSBoolean() || info.isUnknownJS())) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
- return allocate();
- }
switch (info.registerFormat()) {
case DataFormatNone: {
-
- if (node.hasConstant()) {
- JSValue jsValue = valueOfJSConstant(nodeIndex);
- ASSERT(jsValue.isBoolean());
+ if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) {
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ return allocate();
+ }
+
+ if (edge->hasConstant()) {
+ JSValue jsValue = valueOfJSConstant(edge.node());
GPRReg gpr = allocate();
- m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
- info.fillBoolean(*m_stream, gpr);
+ if (jsValue.isBoolean()) {
+ m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
+ m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
+ info.fillBoolean(*m_stream, gpr);
+ return gpr;
+ }
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return gpr;
}
ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatBoolean);
- if (!isBooleanSpeculation(type))
- speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)), direction);
+ if (type & ~SpecBoolean)
+ speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
GPRReg gpr = allocate();
m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
@@ -1447,8 +1225,8 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDire
GPRReg payloadGPR = info.payloadGPR();
m_gprs.lock(tagGPR);
m_gprs.lock(payloadGPR);
- if (!isBooleanSpeculation(type))
- speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag)), direction);
+ if (type & ~SpecBoolean)
+ speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag)));
m_gprs.unlock(tagGPR);
m_gprs.release(tagGPR);
@@ -1464,11 +1242,14 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDire
case DataFormatDouble:
case DataFormatJSCell:
case DataFormatCell:
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
+ return allocate();
+
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
@@ -1477,62 +1258,66 @@ JITCompiler::Jump SpeculativeJIT::convertToDouble(JSValueOperand& op, FPRReg res
{
FPRTemporary scratch(this);
- JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, op.tagGPR(), TrustedImm32(JSValue::Int32Tag));
- JITCompiler::Jump notNumber = m_jit.branch32(MacroAssembler::AboveOrEqual, op.payloadGPR(), TrustedImm32(JSValue::LowestTag));
+ GPRReg opPayloadGPR = op.payloadGPR();
+ GPRReg opTagGPR = op.tagGPR();
+ FPRReg scratchFPR = scratch.fpr();
+
+ JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, opTagGPR, TrustedImm32(JSValue::Int32Tag));
+ JITCompiler::Jump notNumber = m_jit.branch32(MacroAssembler::AboveOrEqual, opPayloadGPR, TrustedImm32(JSValue::LowestTag));
- unboxDouble(op.tagGPR(), op.payloadGPR(), result, scratch.fpr());
+ unboxDouble(opTagGPR, opPayloadGPR, result, scratchFPR);
JITCompiler::Jump done = m_jit.jump();
isInteger.link(&m_jit);
- m_jit.convertInt32ToDouble(op.payloadGPR(), result);
+ m_jit.convertInt32ToDouble(opPayloadGPR, result);
done.link(&m_jit);
return notNumber;
}
-void SpeculativeJIT::compileObjectEquality(Node& node)
+void SpeculativeJIT::compileObjectEquality(Node* node)
{
- SpeculateCellOperand op1(this, node.child1());
- SpeculateCellOperand op2(this, node.child2());
+ SpeculateCellOperand op1(this, node->child1());
+ SpeculateCellOperand op2(this, node->child2());
GPRReg op1GPR = op1.gpr();
GPRReg op2GPR = op2.gpr();
- if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(),
- m_jit.branchPtr(
+ if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(),
- m_jit.branchPtr(
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
GPRTemporary structure(this);
GPRReg structureGPR = structure.gpr();
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1549,39 +1334,47 @@ void SpeculativeJIT::compileObjectEquality(Node& node)
m_jit.move(TrustedImm32(0), resultPayloadGPR);
done.link(&m_jit);
- booleanResult(resultPayloadGPR, m_compileIndex);
+ booleanResult(resultPayloadGPR, node);
}
void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
{
- Node& leftNode = m_jit.graph()[leftChild.index()];
SpeculateCellOperand op1(this, leftChild);
- JSValueOperand op2(this, rightChild);
+ JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
GPRTemporary result(this);
GPRReg op1GPR = op1.gpr();
GPRReg op2TagGPR = op2.tagGPR();
GPRReg op2PayloadGPR = op2.payloadGPR();
GPRReg resultGPR = result.gpr();
-
- if (m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ GPRTemporary structure;
+ GPRReg structureGPR = InvalidGPRReg;
+
+ bool masqueradesAsUndefinedWatchpointValid = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
+
+ if (!masqueradesAsUndefinedWatchpointValid) {
+ // The masquerades as undefined case will use the structure register, so allocate it here.
+ // Do this at the top of the function to avoid branching around a register allocation.
+ GPRTemporary realStructure(this);
+ structure.adopt(realStructure);
+ structureGPR = structure.gpr();
+ }
+
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1595,24 +1388,23 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
m_jit.branch32(MacroAssembler::NotEqual, op2TagGPR, TrustedImm32(JSValue::CellTag));
// We know that within this branch, rightChild must be a cell.
- if (m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1629,12 +1421,12 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
- if (!isOtherOrEmptySpeculation(m_state.forNode(rightChild).m_type & ~SpecCell)) {
+ if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
m_jit.move(op2TagGPR, resultGPR);
m_jit.or32(TrustedImm32(1), resultGPR);
- speculationCheck(
- BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ typeCheck(
+ JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
m_jit.branch32(
MacroAssembler::NotEqual, resultGPR,
MacroAssembler::TrustedImm32(JSValue::NullTag)));
@@ -1647,42 +1439,50 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
m_jit.move(TrustedImm32(1), resultGPR);
done.link(&m_jit);
- booleanResult(resultGPR, m_compileIndex);
+ booleanResult(resultGPR, m_currentNode);
}
-void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, NodeIndex branchNodeIndex)
+void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
SpeculateCellOperand op1(this, leftChild);
- JSValueOperand op2(this, rightChild);
+ JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
GPRTemporary result(this);
GPRReg op1GPR = op1.gpr();
GPRReg op2TagGPR = op2.tagGPR();
GPRReg op2PayloadGPR = op2.payloadGPR();
GPRReg resultGPR = result.gpr();
-
- if (m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ GPRTemporary structure;
+ GPRReg structureGPR = InvalidGPRReg;
+
+ bool masqueradesAsUndefinedWatchpointValid = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
+
+ if (!masqueradesAsUndefinedWatchpointValid) {
+ // The masquerades as undefined case will use the structure register, so allocate it here.
+ // Do this at the top of the function to avoid branching around a register allocation.
+ GPRTemporary realStructure(this);
+ structure.adopt(realStructure);
+ structureGPR = structure.gpr();
+ }
+
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1695,24 +1495,23 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
m_jit.branch32(MacroAssembler::NotEqual, op2TagGPR, TrustedImm32(JSValue::CellTag));
// We know that within this branch, rightChild must be a cell.
- if (m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op2PayloadGPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1726,7 +1525,7 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
- if (isOtherOrEmptySpeculation(m_state.forNode(rightChild).m_type & ~SpecCell))
+ if (!needsTypeCheck(rightChild, SpecCell | SpecOther))
rightNotCell.link(&m_jit);
else {
jump(notTaken, ForceJump);
@@ -1735,8 +1534,8 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
m_jit.move(op2TagGPR, resultGPR);
m_jit.or32(TrustedImm32(1), resultGPR);
- speculationCheck(
- BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild.index(),
+ typeCheck(
+ JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
m_jit.branch32(
MacroAssembler::NotEqual, resultGPR,
MacroAssembler::TrustedImm32(JSValue::NullTag)));
@@ -1745,22 +1544,22 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
jump(notTaken);
}
-void SpeculativeJIT::compileIntegerCompare(Node& node, MacroAssembler::RelationalCondition condition)
+void SpeculativeJIT::compileIntegerCompare(Node* node, MacroAssembler::RelationalCondition condition)
{
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary resultPayload(this);
m_jit.compare32(condition, op1.gpr(), op2.gpr(), resultPayload.gpr());
// If we add a DataFormatBool, we should use it here.
- booleanResult(resultPayload.gpr(), m_compileIndex);
+ booleanResult(resultPayload.gpr(), node);
}
-void SpeculativeJIT::compileDoubleCompare(Node& node, MacroAssembler::DoubleCondition condition)
+void SpeculativeJIT::compileDoubleCompare(Node* node, MacroAssembler::DoubleCondition condition)
{
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
GPRTemporary resultPayload(this);
m_jit.move(TrustedImm32(1), resultPayload.gpr());
@@ -1768,13 +1567,13 @@ void SpeculativeJIT::compileDoubleCompare(Node& node, MacroAssembler::DoubleCond
m_jit.move(TrustedImm32(0), resultPayload.gpr());
trueCase.link(&m_jit);
- booleanResult(resultPayload.gpr(), m_compileIndex);
+ booleanResult(resultPayload.gpr(), node);
}
-void SpeculativeJIT::compileValueAdd(Node& node)
+void SpeculativeJIT::compileValueAdd(Node* node)
{
- JSValueOperand op1(this, node.child1());
- JSValueOperand op2(this, node.child2());
+ JSValueOperand op1(this, node->child1());
+ JSValueOperand op2(this, node->child2());
GPRReg op1TagGPR = op1.tagGPR();
GPRReg op1PayloadGPR = op1.payloadGPR();
@@ -1785,46 +1584,53 @@ void SpeculativeJIT::compileValueAdd(Node& node)
GPRResult2 resultTag(this);
GPRResult resultPayload(this);
- if (isKnownNotNumber(node.child1().index()) || isKnownNotNumber(node.child2().index()))
+ if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
else
callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
}
-void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool needSpeculationCheck)
+void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
{
- JSValueOperand value(this, nodeUse);
+ JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
GPRTemporary resultPayload(this);
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
GPRReg resultPayloadGPR = resultPayload.gpr();
-
+ GPRTemporary structure;
+ GPRReg structureGPR = InvalidGPRReg;
+
+ bool masqueradesAsUndefinedWatchpointValid = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
+
+ if (!masqueradesAsUndefinedWatchpointValid) {
+ // The masquerades as undefined case will use the structure register, so allocate it here.
+ // Do this at the top of the function to avoid branching around a register allocation.
+ GPRTemporary realStructure(this);
+ structure.adopt(realStructure);
+ structureGPR = structure.gpr();
+ }
+
MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag));
- if (m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
-
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
- m_jit.branchPtr(
- MacroAssembler::Equal,
- MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
- } else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ } else {
m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()), structureGPR);
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
- m_jit.branchPtr(
- MacroAssembler::Equal,
- structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ structureGPR,
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
MacroAssembler::Jump isNotMasqueradesAsUndefined =
m_jit.branchTest8(
@@ -1836,7 +1642,7 @@ void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool ne
m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin))));
+ MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->codeOrigin))));
isNotMasqueradesAsUndefined.link(&m_jit);
}
@@ -1846,10 +1652,11 @@ void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool ne
notCell.link(&m_jit);
COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
- if (needSpeculationCheck) {
+ if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
m_jit.move(valueTagGPR, resultPayloadGPR);
m_jit.or32(TrustedImm32(1), resultPayloadGPR);
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
+ typeCheck(
+ JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
m_jit.branch32(
MacroAssembler::NotEqual,
resultPayloadGPR,
@@ -1859,100 +1666,109 @@ void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool ne
done.link(&m_jit);
- booleanResult(resultPayloadGPR, m_compileIndex);
+ booleanResult(resultPayloadGPR, m_currentNode);
}
-void SpeculativeJIT::compileLogicalNot(Node& node)
+void SpeculativeJIT::compileLogicalNot(Node* node)
{
- if (at(node.child1()).shouldSpeculateBoolean()) {
- SpeculateBooleanOperand value(this, node.child1());
+ switch (node->child1().useKind()) {
+ case BooleanUse: {
+ SpeculateBooleanOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.xor32(TrustedImm32(1), value.gpr(), result.gpr());
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
return;
}
- if (at(node.child1()).shouldSpeculateNonStringCellOrOther()) {
- compileNonStringCellOrOtherLogicalNot(node.child1(),
- !isNonStringCellOrOtherSpeculation(m_state.forNode(node.child1()).m_type));
+
+ case ObjectOrOtherUse: {
+ compileObjectOrOtherLogicalNot(node->child1());
return;
}
- if (at(node.child1()).shouldSpeculateInteger()) {
- SpeculateIntegerOperand value(this, node.child1());
+
+ case Int32Use: {
+ SpeculateIntegerOperand value(this, node->child1());
GPRTemporary resultPayload(this, value);
m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), resultPayload.gpr());
- booleanResult(resultPayload.gpr(), m_compileIndex);
+ booleanResult(resultPayload.gpr(), node);
return;
}
- if (at(node.child1()).shouldSpeculateNumber()) {
- SpeculateDoubleOperand value(this, node.child1());
+
+ case NumberUse: {
+ SpeculateDoubleOperand value(this, node->child1());
FPRTemporary scratch(this);
GPRTemporary resultPayload(this);
m_jit.move(TrustedImm32(0), resultPayload.gpr());
MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
m_jit.move(TrustedImm32(1), resultPayload.gpr());
nonZero.link(&m_jit);
- booleanResult(resultPayload.gpr(), m_compileIndex);
+ booleanResult(resultPayload.gpr(), node);
return;
}
- JSValueOperand arg1(this, node.child1());
- GPRTemporary resultPayload(this, arg1, false);
- GPRReg arg1TagGPR = arg1.tagGPR();
- GPRReg arg1PayloadGPR = arg1.payloadGPR();
- GPRReg resultPayloadGPR = resultPayload.gpr();
+ case UntypedUse: {
+ JSValueOperand arg1(this, node->child1());
+ GPRTemporary resultPayload(this, arg1, false);
+ GPRReg arg1TagGPR = arg1.tagGPR();
+ GPRReg arg1PayloadGPR = arg1.payloadGPR();
+ GPRReg resultPayloadGPR = resultPayload.gpr();
- arg1.use();
+ arg1.use();
- JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
+ JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
- m_jit.move(arg1PayloadGPR, resultPayloadGPR);
+ m_jit.move(arg1PayloadGPR, resultPayloadGPR);
- addSlowPathGenerator(
- slowPathCall(
- slowCase, this, dfgConvertJSValueToBoolean, resultPayloadGPR, arg1TagGPR,
- arg1PayloadGPR));
+ addSlowPathGenerator(
+ slowPathCall(
+ slowCase, this, dfgConvertJSValueToBoolean, resultPayloadGPR, arg1TagGPR,
+ arg1PayloadGPR));
- m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
- booleanResult(resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
+ booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
}
-void SpeculativeJIT::emitNonStringCellOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck)
+void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken)
{
- JSValueOperand value(this, nodeUse);
+ JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
GPRTemporary scratch(this);
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
GPRReg scratchGPR = scratch.gpr();
MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag));
- if (m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
-
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
- m_jit.branchPtr(
- MacroAssembler::Equal,
- MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureOffset()), scratchGPR);
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse.index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- scratchGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
+ m_jit.branchPtr(
+ MacroAssembler::Equal,
+ scratchGPR,
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::Zero, MacroAssembler::Address(scratchGPR, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse.index(),
+ speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(scratchGPR, Structure::globalObjectOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin))));
+ MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->codeOrigin))));
isNotMasqueradesAsUndefined.link(&m_jit);
}
@@ -1961,24 +1777,27 @@ void SpeculativeJIT::emitNonStringCellOrOtherBranch(Edge nodeUse, BlockIndex tak
notCell.link(&m_jit);
COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
- if (needSpeculationCheck) {
+ if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
m_jit.move(valueTagGPR, scratchGPR);
m_jit.or32(TrustedImm32(1), scratchGPR);
- speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
+ typeCheck(
+ JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
+ m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
}
jump(notTaken);
- noResult(m_compileIndex);
+ noResult(m_currentNode);
}
-void SpeculativeJIT::emitBranch(Node& node)
+void SpeculativeJIT::emitBranch(Node* node)
{
- BlockIndex taken = node.takenBlockIndex();
- BlockIndex notTaken = node.notTakenBlockIndex();
+ BlockIndex taken = node->takenBlockIndex();
+ BlockIndex notTaken = node->notTakenBlockIndex();
- if (at(node.child1()).shouldSpeculateBoolean()) {
- SpeculateBooleanOperand value(this, node.child1());
+ switch (node->child1().useKind()) {
+ case BooleanUse: {
+ SpeculateBooleanOperand value(this, node->child1());
MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
if (taken == nextBlock()) {
@@ -1991,12 +1810,18 @@ void SpeculativeJIT::emitBranch(Node& node)
branchTest32(condition, value.gpr(), TrustedImm32(1), taken);
jump(notTaken);
- noResult(m_compileIndex);
- } else if (at(node.child1()).shouldSpeculateNonStringCellOrOther()) {
- emitNonStringCellOrOtherBranch(node.child1(), taken, notTaken,
- !isNonStringCellOrOtherSpeculation(m_state.forNode(node.child1()).m_type));
- } else if (at(node.child1()).shouldSpeculateNumber()) {
- if (at(node.child1()).shouldSpeculateInteger()) {
+ noResult(node);
+ return;
+ }
+
+ case ObjectOrOtherUse: {
+ emitObjectOrOtherBranch(node->child1(), taken, notTaken);
+ return;
+ }
+
+ case NumberUse:
+ case Int32Use: {
+ if (node->child1().useKind() == Int32Use) {
bool invert = false;
if (taken == nextBlock()) {
@@ -2006,19 +1831,22 @@ void SpeculativeJIT::emitBranch(Node& node)
notTaken = tmp;
}
- SpeculateIntegerOperand value(this, node.child1());
+ SpeculateIntegerOperand value(this, node->child1());
branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr(), taken);
} else {
- SpeculateDoubleOperand value(this, node.child1());
+ SpeculateDoubleOperand value(this, node->child1());
FPRTemporary scratch(this);
branchDoubleNonZero(value.fpr(), scratch.fpr(), taken);
}
jump(notTaken);
- noResult(m_compileIndex);
- } else {
- JSValueOperand value(this, node.child1());
+ noResult(node);
+ return;
+ }
+
+ case UntypedUse: {
+ JSValueOperand value(this, node->child1());
value.fill();
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
@@ -2026,7 +1854,7 @@ void SpeculativeJIT::emitBranch(Node& node)
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
- use(node.child1());
+ use(node->child1());
JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag));
JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag));
@@ -2043,16 +1871,22 @@ void SpeculativeJIT::emitBranch(Node& node)
branchTest32(JITCompiler::NonZero, resultGPR, taken);
jump(notTaken);
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
}
}
template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
-void SpeculativeJIT::compileContiguousPutByVal(Node& node, BaseOperandType& base, PropertyOperandType& property, ValueOperandType& value, GPRReg valuePayloadReg, TagType valueTag)
+void SpeculativeJIT::compileContiguousPutByVal(Node* node, BaseOperandType& base, PropertyOperandType& property, ValueOperandType& value, GPRReg valuePayloadReg, TagType valueTag)
{
Edge child4 = m_jit.graph().varArgChild(node, 3);
- ArrayMode arrayMode = node.arrayMode();
+ ArrayMode arrayMode = node->arrayMode();
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2060,29 +1894,29 @@ void SpeculativeJIT::compileContiguousPutByVal(Node& node, BaseOperandType& base
StorageOperand storage(this, child4);
GPRReg storageReg = storage.gpr();
- if (node.op() == PutByValAlias) {
+ if (node->op() == PutByValAlias) {
// Store the value to the array.
GPRReg propertyReg = property.gpr();
m_jit.store32(valueTag, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- noResult(m_compileIndex);
+ noResult(node);
return;
}
- MacroAssembler::JumpList slowCases;
+ MacroAssembler::Jump slowCase;
if (arrayMode.isInBounds()) {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ StoreToHoleOrOutOfBounds, JSValueRegs(), 0,
m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
} else {
MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
+ slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
if (!arrayMode.isOutOfBounds())
- speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
m_jit.add32(TrustedImm32(1), propertyReg);
m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
@@ -2102,135 +1936,142 @@ void SpeculativeJIT::compileContiguousPutByVal(Node& node, BaseOperandType& base
if (arrayMode.isOutOfBounds()) {
addSlowPathGenerator(
slowPathCall(
- slowCases, this,
+ slowCase, this,
m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
NoResult, baseReg, propertyReg, valueTag, valuePayloadReg));
}
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::compile(Node& node)
+void SpeculativeJIT::compile(Node* node)
{
- NodeType op = node.op();
+ NodeType op = node->op();
+
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.clearRegisterAllocationOffsets();
+#endif
switch (op) {
case JSConstant:
- initConstantInfo(m_compileIndex);
+ initConstantInfo(node);
break;
case PhantomArguments:
- initConstantInfo(m_compileIndex);
+ initConstantInfo(node);
break;
case WeakJSConstant:
- m_jit.addWeakReference(node.weakConstant());
- initConstantInfo(m_compileIndex);
+ m_jit.addWeakReference(node->weakConstant());
+ initConstantInfo(node);
break;
case Identity: {
- // This could be done a lot better. We take the cheap way out because Identity
- // is only going to stick around after CSE if we had prediction weirdness.
- JSValueOperand operand(this, node.child1());
- GPRTemporary resultTag(this);
- GPRTemporary resultPayload(this);
- m_jit.move(operand.tagGPR(), resultTag.gpr());
- m_jit.move(operand.payloadGPR(), resultPayload.gpr());
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
case GetLocal: {
- SpeculatedType prediction = node.variableAccessData()->prediction();
- AbstractValue& value = block()->valuesAtHead.operand(node.local());
+ SpeculatedType prediction = node->variableAccessData()->prediction();
+ AbstractValue& value = m_state.variables().operand(node->local());
// If we have no prediction for this local, then don't attempt to compile.
if (prediction == SpecNone) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
- if (!node.variableAccessData()->isCaptured()) {
- // If the CFA is tracking this variable and it found that the variable
- // cannot have been assigned, then don't attempt to proceed.
- if (value.isClear()) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
- break;
- }
+ // If the CFA is tracking this variable and it found that the variable
+ // cannot have been assigned, then don't attempt to proceed.
+ if (value.isClear()) {
+ // FIXME: We should trap instead.
+ // https://bugs.webkit.org/show_bug.cgi?id=110383
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+ 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(node, node->refCount(), result.fpr());
+ break;
+ }
+
+ if (isInt32Speculation(value.m_type)) {
+ GPRTemporary result(this);
+ m_jit.load32(JITCompiler::payloadFor(node->local()), result.gpr());
- 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;
- }
+ // 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(node, node->refCount(), result.gpr());
+ break;
+ }
- if (isInt32Speculation(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;
- }
-
- if (isCellSpeculation(value.m_type)) {
- 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 (isBooleanSpeculation(value.m_type)) {
- 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;
- }
+ if (isCellSpeculation(value.m_type)) {
+ 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(node, node->refCount(), result.gpr());
+ break;
+ }
+
+ if (isBooleanSpeculation(value.m_type)) {
+ 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(node, 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());
+ m_jit.load32(JITCompiler::payloadFor(node->local()), result.gpr());
+ m_jit.load32(JITCompiler::tagFor(node->local()), tag.gpr());
// Like jsValueResult, but don't useChildren - our children are phi nodes,
// and don't represent values within this dataflow with virtual registers.
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
- DataFormat format;
- if (isCellSpeculation(value.m_type)
- && !node.variableAccessData()->isCaptured())
- format = DataFormatJSCell;
- else
- format = DataFormatJS;
- m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
+ m_generationInfo[virtualRegister].initJSValue(node, node->refCount(), tag.gpr(), result.gpr(), DataFormatJS);
break;
}
case GetLocalUnlinked: {
GPRTemporary payload(this);
GPRTemporary tag(this);
- m_jit.load32(JITCompiler::payloadFor(node.unlinkedLocal()), payload.gpr());
- m_jit.load32(JITCompiler::tagFor(node.unlinkedLocal()), tag.gpr());
- jsValueResult(tag.gpr(), payload.gpr(), m_compileIndex);
+ m_jit.load32(JITCompiler::payloadFor(node->unlinkedLocal()), payload.gpr());
+ m_jit.load32(JITCompiler::tagFor(node->unlinkedLocal()), tag.gpr());
+ jsValueResult(tag.gpr(), payload.gpr(), node);
+ break;
+ }
+
+ case MovHintAndCheck: {
+ compileMovHintAndCheck(node);
+ break;
+ }
+
+ case InlineStart: {
+ compileInlineStart(node);
+ break;
+ }
+
+ case MovHint:
+ case ZombieHint: {
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -2241,60 +2082,60 @@ void SpeculativeJIT::compile(Node& node)
// stack.
compileMovHint(node);
- if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) {
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- SpeculateDoubleOperand value(this, node.child1(), ForwardSpeculation);
- m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
+ if (node->variableAccessData()->shouldUnboxIfPossible()) {
+ if (node->variableAccessData()->shouldUseDoubleFormat()) {
+ SpeculateDoubleOperand value(this, node->child1());
+ m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->local()));
+ noResult(node);
// Indicate that it's no longer necessary to retrieve the value of
// this bytecode variable from registers or other locations in the stack,
// but that it is stored as a double.
- recordSetLocal(node.local(), ValueSource(DoubleInJSStack));
+ recordSetLocal(node->local(), ValueSource(DoubleInJSStack));
break;
}
- SpeculatedType predictedType = node.variableAccessData()->argumentAwarePrediction();
- 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);
- recordSetLocal(node.local(), ValueSource(DoubleInJSStack));
+ SpeculatedType predictedType = node->variableAccessData()->argumentAwarePrediction();
+ if (m_generationInfo[node->child1()->virtualRegister()].registerFormat() == DataFormatDouble) {
+ SpeculateDoubleOperand value(this, node->child1(), ManualOperandSpeculation);
+ m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(DoubleInJSStack));
break;
}
if (isInt32Speculation(predictedType)) {
- SpeculateIntegerOperand value(this, node.child1(), ForwardSpeculation);
- m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
- noResult(m_compileIndex);
- recordSetLocal(node.local(), ValueSource(Int32InJSStack));
+ SpeculateIntegerOperand value(this, node->child1());
+ m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(Int32InJSStack));
break;
}
if (isCellSpeculation(predictedType)) {
- SpeculateCellOperand cell(this, node.child1(), ForwardSpeculation);
+ SpeculateCellOperand cell(this, node->child1());
GPRReg cellGPR = cell.gpr();
- m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
- noResult(m_compileIndex);
- recordSetLocal(node.local(), ValueSource(CellInJSStack));
+ m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(CellInJSStack));
break;
}
if (isBooleanSpeculation(predictedType)) {
- SpeculateBooleanOperand value(this, node.child1(), ForwardSpeculation);
- m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
- noResult(m_compileIndex);
- recordSetLocal(node.local(), ValueSource(BooleanInJSStack));
+ SpeculateBooleanOperand value(this, node->child1());
+ m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(BooleanInJSStack));
break;
}
}
- 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);
- recordSetLocal(node.local(), ValueSource(ValueInJSStack));
+ JSValueOperand value(this, node->child1());
+ m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->local()));
+ m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(ValueInJSStack));
// If we're storing an arguments object that has been optimized away,
// our variable event stream for OSR exit now reflects the optimized
// value (JSValue()). On the slow path, we want an arguments object
// instead. We add an additional move hint to show OSR exit that it
// needs to reconstruct the arguments object.
- if (at(node.child1()).op() == PhantomArguments)
+ if (node->child1()->op() == PhantomArguments)
compileMovHint(node);
break;
@@ -2310,54 +2151,54 @@ void SpeculativeJIT::compile(Node& node)
case BitAnd:
case BitOr:
case BitXor:
- if (isInt32Constant(node.child1().index())) {
- SpeculateIntegerOperand op2(this, node.child2());
+ if (isInt32Constant(node->child1().node())) {
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op2);
- bitOp(op, valueOfInt32Constant(node.child1().index()), op2.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node->child1().node()), op2.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
- } else if (isInt32Constant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
+ integerResult(result.gpr(), node);
+ } else if (isInt32Constant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this, op1);
- bitOp(op, valueOfInt32Constant(node.child2().index()), op1.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node->child2().node()), op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
} else {
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op1, op2);
GPRReg reg1 = op1.gpr();
GPRReg reg2 = op2.gpr();
bitOp(op, reg1, reg2, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
}
break;
case BitRShift:
case BitLShift:
case BitURShift:
- if (isInt32Constant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
+ if (isInt32Constant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this, op1);
- shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2().index()) & 0x1f, result.gpr());
+ shiftOp(op, op1.gpr(), valueOfInt32Constant(node->child2().node()) & 0x1f, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
} else {
// Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op1);
GPRReg reg1 = op1.gpr();
GPRReg reg2 = op2.gpr();
shiftOp(op, reg1, reg2, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
}
break;
@@ -2376,29 +2217,21 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case Int32ToDouble: {
+ case Int32ToDouble:
+ case ForwardInt32ToDouble: {
compileInt32ToDouble(node);
break;
}
- case CheckNumber: {
- if (!isNumberSpeculation(m_state.forNode(node.child1()).m_type)) {
- JSValueOperand op1(this, node.child1());
- JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, op1.tagGPR(), TrustedImm32(JSValue::Int32Tag));
- speculationCheck(
- BadType, JSValueRegs(op1.tagGPR(), op1.payloadGPR()), node.child1().index(),
- m_jit.branch32(MacroAssembler::AboveOrEqual, op1.tagGPR(), TrustedImm32(JSValue::LowestTag)));
- isInteger.link(&m_jit);
- }
- noResult(m_compileIndex);
- break;
- }
-
case ValueAdd:
case ArithAdd:
compileAdd(node);
break;
+ case MakeRope:
+ compileMakeRope(node);
+ break;
+
case ArithSub:
compileArithSub(node);
break;
@@ -2411,26 +2244,40 @@ void SpeculativeJIT::compile(Node& node)
compileArithMul(node);
break;
+ case ArithIMul:
+ compileArithIMul(node);
+ break;
+
case ArithDiv: {
- if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2()))
- && node.canSpeculateInteger()) {
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
#if CPU(X86)
compileIntegerArithDivForX86(node);
-#else // CPU(X86) -> so non-X86 code follows
- ASSERT_NOT_REACHED(); // should have been coverted into a double divide.
-#endif // CPU(X86)
+#elif CPU(APPLE_ARMV7S)
+ compileIntegerArithDivForARMv7s(node);
+#else // CPU type without integer divide
+ RELEASE_ASSERT_NOT_REACHED(); // should have been coverted into a double divide.
+#endif
+ break;
+ }
+
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
+ FPRTemporary result(this, op1);
+
+ FPRReg reg1 = op1.fpr();
+ FPRReg reg2 = op2.fpr();
+ m_jit.divDouble(reg1, reg2, result.fpr());
+
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
-
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1);
-
- FPRReg reg1 = op1.fpr();
- FPRReg reg2 = op2.fpr();
- m_jit.divDouble(reg1, reg2, result.fpr());
-
- doubleResult(result.fpr(), m_compileIndex);
break;
}
@@ -2440,9 +2287,9 @@ void SpeculativeJIT::compile(Node& node)
}
case ArithAbs: {
- if (at(node.child1()).shouldSpeculateIntegerForArithmetic()
- && node.canSpeculateInteger()) {
- SpeculateIntegerOperand op1(this, node.child1());
+ switch (node->child1().useKind()) {
+ case Int32Use: {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this, op1);
GPRTemporary scratch(this);
@@ -2450,81 +2297,106 @@ void SpeculativeJIT::compile(Node& node)
m_jit.rshift32(result.gpr(), MacroAssembler::TrustedImm32(31), scratch.gpr());
m_jit.add32(scratch.gpr(), result.gpr());
m_jit.xor32(scratch.gpr(), result.gpr());
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
- integerResult(result.gpr(), m_compileIndex);
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
+ integerResult(result.gpr(), node);
break;
}
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this);
-
- m_jit.absDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRTemporary result(this);
+
+ m_jit.absDouble(op1.fpr(), result.fpr());
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
case ArithMin:
case ArithMax: {
- if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2()))
- && node.canSpeculateInteger()) {
- SpeculateStrictInt32Operand op1(this, node.child1());
- SpeculateStrictInt32Operand op2(this, node.child2());
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
+ SpeculateStrictInt32Operand op1(this, node->child1());
+ SpeculateStrictInt32Operand op2(this, node->child2());
GPRTemporary result(this, op1);
-
- MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr());
- m_jit.move(op2.gpr(), result.gpr());
- if (op1.gpr() != result.gpr()) {
+
+ GPRReg op1GPR = op1.gpr();
+ GPRReg op2GPR = op2.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1GPR, op2GPR);
+ m_jit.move(op2GPR, resultGPR);
+ if (op1GPR != resultGPR) {
MacroAssembler::Jump done = m_jit.jump();
op1Less.link(&m_jit);
- m_jit.move(op1.gpr(), result.gpr());
+ m_jit.move(op1GPR, resultGPR);
done.link(&m_jit);
} else
op1Less.link(&m_jit);
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(resultGPR, node);
break;
}
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1);
-
- MacroAssembler::JumpList done;
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
+ FPRTemporary result(this, op1);
+
+ FPRReg op1FPR = op1.fpr();
+ FPRReg op2FPR = op2.fpr();
+ FPRReg resultFPR = result.fpr();
+
+ MacroAssembler::JumpList done;
- MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
+ MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1FPR, op2FPR);
- // op2 is eather the lesser one or one of then is NaN
- MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
+ // op2 is eather the lesser one or one of then is NaN
+ MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1FPR, op2FPR);
- // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
- // op1 + op2 and putting it into result.
- m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
- done.append(m_jit.jump());
+ // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
+ // op1 + op2 and putting it into result.
+ m_jit.addDouble(op1FPR, op2FPR, resultFPR);
+ done.append(m_jit.jump());
- op2Less.link(&m_jit);
- m_jit.moveDouble(op2.fpr(), result.fpr());
+ op2Less.link(&m_jit);
+ m_jit.moveDouble(op2FPR, resultFPR);
- if (op1.fpr() != result.fpr()) {
- done.append(m_jit.jump());
+ if (op1FPR != resultFPR) {
+ done.append(m_jit.jump());
- op1Less.link(&m_jit);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- } else
- op1Less.link(&m_jit);
+ op1Less.link(&m_jit);
+ m_jit.moveDouble(op1FPR, resultFPR);
+ } else
+ op1Less.link(&m_jit);
- done.link(&m_jit);
+ done.link(&m_jit);
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(resultFPR, node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
case ArithSqrt: {
- SpeculateDoubleOperand op1(this, node.child1());
+ SpeculateDoubleOperand op1(this, node->child1());
FPRTemporary result(this, op1);
m_jit.sqrtDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(result.fpr(), node);
break;
}
@@ -2551,22 +2423,23 @@ void SpeculativeJIT::compile(Node& node)
if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
return;
break;
+
+ case CompareEqConstant:
+ ASSERT(isNullConstant(node->child2().node()));
+ if (nonSpeculativeCompareNull(node, node->child1()))
+ return;
+ break;
case CompareEq:
- if (isNullConstant(node.child1().index())) {
- if (nonSpeculativeCompareNull(node, node.child2()))
- return;
- break;
- }
- if (isNullConstant(node.child2().index())) {
- if (nonSpeculativeCompareNull(node, node.child1()))
- return;
- break;
- }
if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
return;
break;
+ case CompareStrictEqConstant:
+ if (compileStrictEqForConstant(node, node->child1(), valueOfJSConstant(node->child2().node())))
+ return;
+ break;
+
case CompareStrictEq:
if (compileStrictEq(node))
return;
@@ -2582,6 +2455,11 @@ void SpeculativeJIT::compile(Node& node)
compileGetByValOnString(node);
break;
}
+
+ case StringFromCharCode: {
+ compileFromCharCode(node);
+ break;
+ }
case CheckArray: {
checkArray(node);
@@ -2595,15 +2473,15 @@ void SpeculativeJIT::compile(Node& node)
}
case GetByVal: {
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::SelectUsingPredictions:
case Array::ForceExit:
- ASSERT_NOT_REACHED();
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ RELEASE_ASSERT_NOT_REACHED();
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
case Array::Generic: {
- SpeculateCellOperand base(this, node.child1()); // Save a register, speculate cell. We'll probably be right.
- JSValueOperand property(this, node.child2());
+ SpeculateCellOperand base(this, node->child1()); // Save a register, speculate cell. We'll probably be right.
+ JSValueOperand property(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg propertyTagGPR = property.tagGPR();
GPRReg propertyPayloadGPR = property.payloadGPR();
@@ -2613,14 +2491,14 @@ void SpeculativeJIT::compile(Node& node)
GPRResult resultPayload(this);
callOperation(operationGetByValCell, resultTag.gpr(), resultPayload.gpr(), baseGPR, propertyTagGPR, propertyPayloadGPR);
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
case Array::Int32:
case Array::Contiguous: {
- if (node.arrayMode().isInBounds()) {
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ if (node->arrayMode().isInBounds()) {
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
@@ -2628,32 +2506,32 @@ void SpeculativeJIT::compile(Node& node)
if (!m_compileOkay)
return;
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
GPRTemporary resultPayload(this);
- if (node.arrayMode().type() == Array::Int32) {
+ if (node->arrayMode().type() == Array::Int32) {
speculationCheck(
- OutOfBounds, JSValueRegs(), NoNode,
+ OutOfBounds, JSValueRegs(), 0,
m_jit.branch32(
MacroAssembler::Equal,
MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
TrustedImm32(JSValue::EmptyValueTag)));
m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
- integerResult(resultPayload.gpr(), m_compileIndex);
+ integerResult(resultPayload.gpr(), node);
break;
}
GPRTemporary resultTag(this);
m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
+ speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2680,20 +2558,20 @@ void SpeculativeJIT::compile(Node& node)
slowCases, this, operationGetByValArrayInt,
JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg));
- jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex);
+ jsValueResult(resultTagReg, resultPayloadReg, node);
break;
}
case Array::Double: {
- if (node.arrayMode().isInBounds()) {
- if (node.arrayMode().isSaneChain()) {
- JSGlobalObject* globalObject = m_jit.globalObjectFor(node.codeOrigin);
+ if (node->arrayMode().isInBounds()) {
+ if (node->arrayMode().isSaneChain()) {
+ JSGlobalObject* globalObject = m_jit.globalObjectFor(node->codeOrigin);
ASSERT(globalObject->arrayPrototypeChainIsSane());
globalObject->arrayPrototype()->structure()->addTransitionWatchpoint(speculationWatchpoint());
globalObject->objectPrototype()->structure()->addTransitionWatchpoint(speculationWatchpoint());
}
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
@@ -2701,19 +2579,19 @@ void SpeculativeJIT::compile(Node& node)
if (!m_compileOkay)
return;
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
FPRTemporary result(this);
m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr());
- if (!node.arrayMode().isSaneChain())
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr()));
- doubleResult(result.fpr(), m_compileIndex);
+ if (!node->arrayMode().isSaneChain())
+ speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr()));
+ doubleResult(result.fpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2742,36 +2620,36 @@ void SpeculativeJIT::compile(Node& node)
slowCases, this, operationGetByValArrayInt,
JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg));
- jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex);
+ jsValueResult(resultTagReg, resultPayloadReg, node);
break;
}
case Array::ArrayStorage:
case Array::SlowPutArrayStorage: {
- if (node.arrayMode().isInBounds()) {
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ if (node->arrayMode().isInBounds()) {
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
if (!m_compileOkay)
return;
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
GPRTemporary resultTag(this);
GPRTemporary resultPayload(this);
m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
+ speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
GPRReg baseReg = base.gpr();
@@ -2802,7 +2680,7 @@ void SpeculativeJIT::compile(Node& node)
JSValueRegs(resultTagReg, resultPayloadReg),
baseReg, propertyReg));
- jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex);
+ jsValueResult(resultTagReg, resultPayloadReg, node);
break;
}
case Array::String:
@@ -2812,34 +2690,34 @@ void SpeculativeJIT::compile(Node& node)
compileGetByValOnArguments(node);
break;
case Array::Int8Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), node, sizeof(int8_t), SignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->int8ArrayDescriptor(), node, sizeof(int8_t), SignedTypedArray);
break;
case Array::Int16Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), node, sizeof(int16_t), SignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->int16ArrayDescriptor(), node, sizeof(int16_t), SignedTypedArray);
break;
case Array::Int32Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), node, sizeof(int32_t), SignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->int32ArrayDescriptor(), node, sizeof(int32_t), SignedTypedArray);
break;
case Array::Uint8Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint8ArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
break;
case Array::Uint8ClampedArray:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
break;
case Array::Uint16Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), node, sizeof(uint16_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint16ArrayDescriptor(), node, sizeof(uint16_t), UnsignedTypedArray);
break;
case Array::Uint32Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), node, sizeof(uint32_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint32ArrayDescriptor(), node, sizeof(uint32_t), UnsignedTypedArray);
break;
case Array::Float32Array:
- compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float));
+ compileGetByValOnFloatTypedArray(m_jit.vm()->float32ArrayDescriptor(), node, sizeof(float));
break;
case Array::Float64Array:
- compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double));
+ compileGetByValOnFloatTypedArray(m_jit.vm()->float64ArrayDescriptor(), node, sizeof(double));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
break;
@@ -2852,18 +2730,18 @@ void SpeculativeJIT::compile(Node& node)
Edge child3 = m_jit.graph().varArgChild(node, 2);
Edge child4 = m_jit.graph().varArgChild(node, 3);
- ArrayMode arrayMode = node.arrayMode().modeForPut();
+ ArrayMode arrayMode = node->arrayMode().modeForPut();
bool alreadyHandled = false;
switch (arrayMode.type()) {
case Array::SelectUsingPredictions:
case Array::ForceExit:
- ASSERT_NOT_REACHED();
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ RELEASE_ASSERT_NOT_REACHED();
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
alreadyHandled = true;
break;
case Array::Generic: {
- ASSERT(node.op() == PutByVal);
+ ASSERT(node->op() == PutByVal);
SpeculateCellOperand base(this, child1); // Save a register, speculate cell. We'll probably be right.
JSValueOperand property(this, child2);
@@ -2877,7 +2755,7 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValCellStrict : operationPutByValCellNonStrict, baseGPR, propertyTagGPR, propertyPayloadGPR, valueTagGPR, valuePayloadGPR);
- noResult(m_compileIndex);
+ noResult(node);
alreadyHandled = true;
break;
}
@@ -2946,13 +2824,13 @@ void SpeculativeJIT::compile(Node& node)
StorageOperand storage(this, child4);
GPRReg storageReg = storage.gpr();
- if (node.op() == PutByValAlias) {
+ if (node->op() == PutByValAlias) {
// Store the value to the array.
GPRReg propertyReg = property.gpr();
m_jit.store32(value.tagGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
m_jit.store32(value.payloadGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -2960,17 +2838,14 @@ void SpeculativeJIT::compile(Node& node)
MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
if (!arrayMode.isOutOfBounds())
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, beyondArrayBounds);
else
slowCases.append(beyondArrayBounds);
// Check if we're writing to a hole; if so increment m_numValuesInVector.
if (arrayMode.isInBounds()) {
- // This is uncountable because if we take this exit, then the baseline JIT
- // will immediately count the hole store. So there is no need for exit
- // profiling.
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ StoreToHole, JSValueRegs(), 0,
m_jit.branch32(MacroAssembler::Equal, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)));
} else {
MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
@@ -3010,54 +2885,54 @@ void SpeculativeJIT::compile(Node& node)
NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
}
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
case Array::Arguments:
// FIXME: we could at some point make this work. Right now we're assuming that the register
// pressure would be too great.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
case Array::Int8Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), SignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), SignedTypedArray);
break;
case Array::Int16Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), SignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), SignedTypedArray);
break;
case Array::Int32Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), SignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), SignedTypedArray);
break;
case Array::Uint8Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray);
break;
case Array::Uint8ClampedArray:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray, ClampRounding);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray, ClampRounding);
break;
case Array::Uint16Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), UnsignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), UnsignedTypedArray);
break;
case Array::Uint32Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), UnsignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), UnsignedTypedArray);
break;
case Array::Float32Array:
- compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float));
+ compilePutByValForFloatTypedArray(m_jit.vm()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float));
break;
case Array::Float64Array:
- compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double));
+ compilePutByValForFloatTypedArray(m_jit.vm()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
break;
@@ -3067,9 +2942,9 @@ void SpeculativeJIT::compile(Node& node)
if (compileRegExpExec(node))
return;
- if (!node.adjustedRefCount()) {
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ if (!node->adjustedRefCount()) {
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3079,12 +2954,12 @@ void SpeculativeJIT::compile(Node& node)
// Must use jsValueResult because otherwise we screw up register
// allocation, which thinks that this node has a result.
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3093,13 +2968,13 @@ void SpeculativeJIT::compile(Node& node)
GPRResult resultPayload(this);
callOperation(operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), baseGPR, argumentGPR);
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
case RegExpTest: {
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3108,25 +2983,25 @@ void SpeculativeJIT::compile(Node& node)
callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
// If we add a DataFormatBool, we should use it here.
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
case ArrayPush: {
- ASSERT(node.arrayMode().isJSArray());
+ ASSERT(node->arrayMode().isJSArray());
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary storageLength(this);
GPRReg baseGPR = base.gpr();
GPRReg storageLengthGPR = storageLength.gpr();
- StorageOperand storage(this, node.child3());
+ StorageOperand storage(this, node->child3());
GPRReg storageGPR = storage.gpr();
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::Int32: {
- SpeculateIntegerOperand value(this, node.child2());
+ SpeculateIntegerOperand value(this, node->child2());
GPRReg valuePayloadGPR = value.gpr();
m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
@@ -3143,18 +3018,18 @@ void SpeculativeJIT::compile(Node& node)
JSValueRegs(storageGPR, storageLengthGPR),
TrustedImm32(JSValue::Int32Tag), valuePayloadGPR, baseGPR));
- jsValueResult(storageGPR, storageLengthGPR, m_compileIndex);
+ jsValueResult(storageGPR, storageLengthGPR, node);
break;
}
case Array::Contiguous: {
- JSValueOperand value(this, node.child2());
+ JSValueOperand value(this, node->child2());
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
if (Heap::isWriteBarrierEnabled()) {
GPRTemporary scratch(this);
- writeBarrier(baseGPR, valueTagGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
+ writeBarrier(baseGPR, valueTagGPR, node->child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
}
m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
@@ -3171,21 +3046,17 @@ void SpeculativeJIT::compile(Node& node)
JSValueRegs(storageGPR, storageLengthGPR),
valueTagGPR, valuePayloadGPR, baseGPR));
- jsValueResult(storageGPR, storageLengthGPR, m_compileIndex);
+ jsValueResult(storageGPR, storageLengthGPR, node);
break;
}
case Array::Double: {
- SpeculateDoubleOperand value(this, node.child2());
+ SpeculateDoubleOperand value(this, node->child2());
FPRReg valueFPR = value.fpr();
- if (!isRealNumberSpeculation(m_state.forNode(node.child2()).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(), node->child2(), SpecRealNumber,
+ m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
@@ -3200,24 +3071,24 @@ void SpeculativeJIT::compile(Node& node)
JSValueRegs(storageGPR, storageLengthGPR),
valueFPR, baseGPR));
- jsValueResult(storageGPR, storageLengthGPR, m_compileIndex);
+ jsValueResult(storageGPR, storageLengthGPR, node);
break;
}
case Array::ArrayStorage: {
- JSValueOperand value(this, node.child2());
+ JSValueOperand value(this, node->child2());
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
if (Heap::isWriteBarrierEnabled()) {
GPRTemporary scratch(this);
- writeBarrier(baseGPR, valueTagGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
+ writeBarrier(baseGPR, valueTagGPR, node->child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
}
m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
// Refuse to handle bizarre lengths.
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
@@ -3231,7 +3102,7 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(slowPathCall(slowPath, this, operationArrayPush, JSValueRegs(storageGPR, storageLengthGPR), valueTagGPR, valuePayloadGPR, baseGPR));
- jsValueResult(storageGPR, storageLengthGPR, m_compileIndex);
+ jsValueResult(storageGPR, storageLengthGPR, node);
break;
}
@@ -3243,10 +3114,10 @@ void SpeculativeJIT::compile(Node& node)
}
case ArrayPop: {
- ASSERT(node.arrayMode().isJSArray());
+ ASSERT(node->arrayMode().isJSArray());
- SpeculateCellOperand base(this, node.child1());
- StorageOperand storage(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ StorageOperand storage(this, node->child2());
GPRTemporary valueTag(this);
GPRTemporary valuePayload(this);
@@ -3255,7 +3126,7 @@ void SpeculativeJIT::compile(Node& node)
GPRReg valuePayloadGPR = valuePayload.gpr();
GPRReg storageGPR = storage.gpr();
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::Int32:
case Array::Contiguous: {
m_jit.load32(
@@ -3286,7 +3157,7 @@ void SpeculativeJIT::compile(Node& node)
slowCase, this, operationArrayPopAndRecoverLength,
JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
- jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex);
+ jsValueResult(valueTagGPR, valuePayloadGPR, node);
break;
}
@@ -3324,7 +3195,7 @@ void SpeculativeJIT::compile(Node& node)
slowCase, this, operationArrayPopAndRecoverLength,
JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
- jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex);
+ jsValueResult(valueTagGPR, valuePayloadGPR, node);
break;
}
@@ -3363,7 +3234,7 @@ void SpeculativeJIT::compile(Node& node)
slowCase, this, operationArrayPop,
JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
- jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex);
+ jsValueResult(valueTagGPR, valuePayloadGPR, node);
break;
}
@@ -3375,34 +3246,13 @@ void SpeculativeJIT::compile(Node& node)
}
case DFG::Jump: {
- BlockIndex taken = node.takenBlockIndex();
+ BlockIndex taken = node->takenBlockIndex();
jump(taken);
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case Branch:
- if (at(node.child1()).shouldSpeculateInteger()) {
- SpeculateIntegerOperand op(this, node.child1());
-
- BlockIndex taken = node.takenBlockIndex();
- BlockIndex notTaken = node.notTakenBlockIndex();
-
- MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
-
- if (taken == nextBlock()) {
- condition = MacroAssembler::Zero;
- BlockIndex tmp = taken;
- taken = notTaken;
- notTaken = tmp;
- }
-
- branchTest32(condition, op.gpr(), taken);
- jump(notTaken);
-
- noResult(m_compileIndex);
- break;
- }
emitBranch(node);
break;
@@ -3417,7 +3267,7 @@ void SpeculativeJIT::compile(Node& node)
#endif
// Return the result in returnValueGPR.
- JSValueOperand op1(this, node.child1());
+ JSValueOperand op1(this, node->child1());
op1.fill();
if (op1.isDouble())
boxDouble(op1.fpr(), GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
@@ -3441,7 +3291,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT2);
m_jit.ret();
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -3449,28 +3299,13 @@ void SpeculativeJIT::compile(Node& node)
case ThrowReferenceError: {
// We expect that throw statements are rare and are intended to exit the code block
// anyway, so we just OSR back to the old JIT for now.
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
break;
}
case ToPrimitive: {
- if (at(node.child1()).shouldSpeculateInteger()) {
- // It's really profitable to speculate integer, since it's really cheap,
- // it means we don't have to do any real work, and we emit a lot less code.
-
- SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
-
- ASSERT(op1.format() == DataFormatInteger);
- m_jit.move(op1.gpr(), result.gpr());
-
- integerResult(result.gpr(), m_compileIndex);
- break;
- }
-
- // FIXME: Add string speculation here.
-
- JSValueOperand op1(this, node.child1());
+ RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
+ JSValueOperand op1(this, node->child1());
GPRTemporary resultTag(this, op1);
GPRTemporary resultPayload(this, op1, false);
@@ -3481,12 +3316,12 @@ void SpeculativeJIT::compile(Node& node)
op1.use();
- if (!(m_state.forNode(node.child1()).m_type & ~(SpecNumber | SpecBoolean))) {
+ if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean))) {
m_jit.move(op1TagGPR, resultTagGPR);
m_jit.move(op1PayloadGPR, resultPayloadGPR);
} else {
MacroAssembler::Jump alreadyPrimitive = m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
- MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
+ MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get()));
alreadyPrimitive.link(&m_jit);
m_jit.move(op1TagGPR, resultTagGPR);
@@ -3498,66 +3333,64 @@ void SpeculativeJIT::compile(Node& node)
JSValueRegs(resultTagGPR, resultPayloadGPR), op1TagGPR, op1PayloadGPR));
}
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
break;
}
- case StrCat: {
- size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren();
- ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize);
- EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
-
- for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
- JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
- GPRReg opTagGPR = operand.tagGPR();
- GPRReg opPayloadGPR = operand.payloadGPR();
- operand.use();
+ case ToString: {
+ if (node->child1().useKind() == UntypedUse) {
+ JSValueOperand op1(this, node->child1());
+ GPRReg op1PayloadGPR = op1.payloadGPR();
+ GPRReg op1TagGPR = op1.tagGPR();
+
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+
+ flushRegisters();
- m_jit.store32(opTagGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
- m_jit.store32(opPayloadGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+ JITCompiler::Jump done;
+ if (node->child1()->prediction() & SpecString) {
+ JITCompiler::Jump slowPath1 = m_jit.branch32(
+ JITCompiler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
+ JITCompiler::Jump slowPath2 = m_jit.branchPtr(
+ JITCompiler::NotEqual,
+ JITCompiler::Address(op1PayloadGPR, JSCell::structureOffset()),
+ TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+ m_jit.move(op1PayloadGPR, resultGPR);
+ done = m_jit.jump();
+ slowPath1.link(&m_jit);
+ slowPath2.link(&m_jit);
+ }
+ callOperation(operationToString, resultGPR, op1TagGPR, op1PayloadGPR);
+ if (done.isSet())
+ done.link(&m_jit);
+ cellResult(resultGPR, node);
+ break;
}
- flushRegisters();
-
- if (scratchSize) {
- GPRTemporary scratch(this);
-
- // Tell GC mark phase how much of the scratch buffer is active during call.
- m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr());
- m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());
- }
-
- GPRResult resultPayload(this);
- GPRResult2 resultTag(this);
+ compileToStringOnCell(node);
+ break;
+ }
- callOperation(operationStrCat, resultTag.gpr(), resultPayload.gpr(), static_cast<void *>(buffer), node.numChildren());
-
- if (scratchSize) {
- GPRTemporary scratch(this);
-
- m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr());
- m_jit.storePtr(TrustedImmPtr(0), scratch.gpr());
- }
-
- // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag.
- cellResult(resultPayload.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
+ case NewStringObject: {
+ compileNewStringObject(node);
break;
}
-
+
case NewArray: {
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
- if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin);
+ if (!globalObject->isHavingABadTime() && !hasArrayStorage(node->indexingType())) {
globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
- Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType());
- ASSERT(structure->indexingType() == node.indexingType());
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
+ ASSERT(structure->indexingType() == node->indexingType());
ASSERT(
hasUndecided(structure->indexingType())
|| hasInt32(structure->indexingType())
|| hasDouble(structure->indexingType())
|| hasContiguous(structure->indexingType()));
- unsigned numElements = node.numChildren();
+ unsigned numElements = node->numChildren();
GPRTemporary result(this);
GPRTemporary storage(this);
@@ -3565,16 +3398,16 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
GPRReg storageGPR = storage.gpr();
- emitAllocateJSArray(structure, resultGPR, storageGPR, numElements);
+ emitAllocateJSArray(resultGPR, structure, storageGPR, numElements);
// At this point, one way or another, resultGPR and storageGPR have pointers to
// the JSArray and the Butterfly, respectively.
- ASSERT(!hasUndecided(structure->indexingType()) || !node.numChildren());
+ ASSERT(!hasUndecided(structure->indexingType()) || !node->numChildren());
- for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
- Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx];
- switch (node.indexingType()) {
+ for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
+ Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
+ switch (node->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
case ALL_UNDECIDED_INDEXING_TYPES:
CRASH();
@@ -3582,13 +3415,9 @@ void SpeculativeJIT::compile(Node& node)
case ALL_DOUBLE_INDEXING_TYPES: {
SpeculateDoubleOperand operand(this, use);
FPRReg opFPR = operand.fpr();
- if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(), use, SpecRealNumber,
+ m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
break;
@@ -3600,7 +3429,7 @@ void SpeculativeJIT::compile(Node& node)
break;
}
case ALL_CONTIGUOUS_INDEXING_TYPES: {
- JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
+ JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx]);
GPRReg opTagGPR = operand.tagGPR();
GPRReg opPayloadGPR = operand.payloadGPR();
m_jit.store32(opTagGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
@@ -3620,30 +3449,30 @@ void SpeculativeJIT::compile(Node& node)
// bigger problem will also likely fix the redundancy in reloading the storage
// pointer that we currently have.
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
- if (!node.numChildren()) {
+ if (!node->numChildren()) {
flushRegisters();
GPRResult result(this);
callOperation(
- operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()));
- cellResult(result.gpr(), m_compileIndex);
+ operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
+ cellResult(result.gpr(), node);
break;
}
- size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren();
- ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize);
+ size_t scratchSize = sizeof(EncodedJSValue) * node->numChildren();
+ ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(scratchSize);
EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
- for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
+ for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
// Need to perform the speculations that this node promises to perform. If we're
// emitting code here and the indexing type is not array storage then there is
// probably something hilarious going on and we're already failing at all the
// things, but at least we're going to be sound.
- Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx];
- switch (node.indexingType()) {
+ Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
+ switch (node->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
case ALL_UNDECIDED_INDEXING_TYPES:
CRASH();
@@ -3651,13 +3480,9 @@ void SpeculativeJIT::compile(Node& node)
case ALL_DOUBLE_INDEXING_TYPES: {
SpeculateDoubleOperand operand(this, use);
FPRReg opFPR = operand.fpr();
- if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(), use, SpecRealNumber,
+ m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
m_jit.storeDouble(opFPR, reinterpret_cast<char*>(buffer + operandIdx));
break;
@@ -3671,7 +3496,7 @@ void SpeculativeJIT::compile(Node& node)
}
case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
- JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
+ JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx]);
GPRReg opTagGPR = operand.tagGPR();
GPRReg opPayloadGPR = operand.payloadGPR();
@@ -3686,7 +3511,7 @@ void SpeculativeJIT::compile(Node& node)
}
}
- switch (node.indexingType()) {
+ switch (node->indexingType()) {
case ALL_DOUBLE_INDEXING_TYPES:
case ALL_INT32_INDEXING_TYPES:
useChildren(node);
@@ -3708,8 +3533,8 @@ void SpeculativeJIT::compile(Node& node)
GPRResult result(this);
callOperation(
- operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()),
- static_cast<void*>(buffer), node.numChildren());
+ operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
+ static_cast<void*>(buffer), node->numChildren());
if (scratchSize) {
GPRTemporary scratch(this);
@@ -3718,24 +3543,26 @@ void SpeculativeJIT::compile(Node& node)
m_jit.storePtr(TrustedImmPtr(0), scratch.gpr());
}
- cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
+ cellResult(result.gpr(), node, UseChildrenCalledExplicitly);
break;
}
case NewArrayWithSize: {
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
- if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin);
+ if (!globalObject->isHavingABadTime() && !hasArrayStorage(node->indexingType())) {
globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
- SpeculateStrictInt32Operand size(this, node.child1());
+ SpeculateStrictInt32Operand size(this, node->child1());
GPRTemporary result(this);
GPRTemporary storage(this);
GPRTemporary scratch(this);
+ GPRTemporary scratch2(this);
GPRReg sizeGPR = size.gpr();
GPRReg resultGPR = result.gpr();
GPRReg storageGPR = storage.gpr();
GPRReg scratchGPR = scratch.gpr();
+ GPRReg scratch2GPR = scratch2.gpr();
MacroAssembler::JumpList slowCases;
slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
@@ -3747,14 +3574,13 @@ void SpeculativeJIT::compile(Node& node)
slowCases.append(
emitAllocateBasicStorage(resultGPR, storageGPR));
m_jit.subPtr(scratchGPR, storageGPR);
- emitAllocateBasicJSObject<JSArray, MarkedBlock::None>(
- TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), resultGPR, scratchGPR,
- storageGPR, sizeof(JSArray), slowCases);
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
+ emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases);
m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
- if (hasDouble(node.indexingType())) {
+ if (hasDouble(node->indexingType())) {
JSValue nan = JSValue(JSValue::EncodeAsDouble, QNaN);
m_jit.move(sizeGPR, scratchGPR);
@@ -3770,39 +3596,39 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(adoptPtr(
new CallArrayAllocatorWithVariableSizeSlowPathGenerator(
slowCases, this, operationNewArrayWithSize, resultGPR,
- globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()),
+ globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage),
sizeGPR)));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
- SpeculateStrictInt32Operand size(this, node.child1());
+ SpeculateStrictInt32Operand size(this, node->child1());
GPRReg sizeGPR = size.gpr();
flushRegisters();
GPRResult result(this);
GPRReg resultGPR = result.gpr();
GPRReg structureGPR = selectScratchGPR(sizeGPR);
MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX));
- m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), structureGPR);
+ m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())), structureGPR);
MacroAssembler::Jump done = m_jit.jump();
bigLength.link(&m_jit);
m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR);
done.link(&m_jit);
callOperation(
operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR);
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case NewArrayBuffer: {
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
- IndexingType indexingType = node.indexingType();
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin);
+ IndexingType indexingType = node->indexingType();
if (!globalObject->isHavingABadTime() && !hasArrayStorage(indexingType)) {
globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
- unsigned numElements = node.numConstants();
+ unsigned numElements = node->numConstants();
GPRTemporary result(this);
GPRTemporary storage(this);
@@ -3810,11 +3636,11 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
GPRReg storageGPR = storage.gpr();
- emitAllocateJSArray(globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), resultGPR, storageGPR, numElements);
+ emitAllocateJSArray(resultGPR, globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements);
- if (node.indexingType() == ArrayWithDouble) {
- JSValue* data = m_jit.codeBlock()->constantBuffer(node.startConstant());
- for (unsigned index = 0; index < node.numConstants(); ++index) {
+ if (node->indexingType() == ArrayWithDouble) {
+ JSValue* data = m_jit.codeBlock()->constantBuffer(node->startConstant());
+ for (unsigned index = 0; index < node->numConstants(); ++index) {
union {
int32_t halves[2];
double value;
@@ -3824,23 +3650,23 @@ void SpeculativeJIT::compile(Node& node)
m_jit.store32(Imm32(u.halves[1]), MacroAssembler::Address(storageGPR, sizeof(double) * index + sizeof(int32_t)));
}
} else {
- int32_t* data = bitwise_cast<int32_t*>(m_jit.codeBlock()->constantBuffer(node.startConstant()));
- for (unsigned index = 0; index < node.numConstants() * 2; ++index) {
+ int32_t* data = bitwise_cast<int32_t*>(m_jit.codeBlock()->constantBuffer(node->startConstant()));
+ for (unsigned index = 0; index < node->numConstants() * 2; ++index) {
m_jit.store32(
Imm32(data[index]), MacroAssembler::Address(storageGPR, sizeof(int32_t) * index));
}
}
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
flushRegisters();
GPRResult result(this);
- callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), node.startConstant(), node.numConstants());
+ callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()), node->startConstant(), node->numConstants());
- cellResult(result.gpr(), m_compileIndex);
+ cellResult(result.gpr(), node);
break;
}
@@ -3849,56 +3675,17 @@ void SpeculativeJIT::compile(Node& node)
GPRResult resultPayload(this);
GPRResult2 resultTag(this);
- callOperation(operationNewRegexp, resultTag.gpr(), resultPayload.gpr(), m_jit.codeBlock()->regexp(node.regexpIndex()));
+ callOperation(operationNewRegexp, resultTag.gpr(), resultPayload.gpr(), m_jit.codeBlock()->regexp(node->regexpIndex()));
// FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag.
- cellResult(resultPayload.gpr(), m_compileIndex);
+ cellResult(resultPayload.gpr(), node);
break;
}
case ConvertThis: {
- if (isObjectSpeculation(m_state.forNode(node.child1()).m_type)) {
- SpeculateCellOperand thisValue(this, node.child1());
- GPRTemporary result(this, thisValue);
- m_jit.move(thisValue.gpr(), result.gpr());
- cellResult(result.gpr(), m_compileIndex);
- break;
- }
-
- if (isOtherSpeculation(at(node.child1()).prediction())) {
- JSValueOperand thisValue(this, node.child1());
- GPRTemporary scratch(this);
-
- GPRReg thisValueTagGPR = thisValue.tagGPR();
- GPRReg scratchGPR = scratch.gpr();
-
- COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
- m_jit.move(thisValueTagGPR, scratchGPR);
- m_jit.or32(TrustedImm32(1), scratchGPR);
- // This is hard. It would be better to save the value, but we can't quite do it,
- // since this operation does not otherwise get the payload.
- speculationCheck(BadType, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
-
- m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalThisObjectFor(node.codeOrigin)), scratchGPR);
- cellResult(scratchGPR, m_compileIndex);
- break;
- }
-
- if (isObjectSpeculation(at(node.child1()).prediction())) {
- SpeculateCellOperand thisValue(this, node.child1());
- GPRReg thisValueGPR = thisValue.gpr();
-
- if (!isObjectSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
-
- GPRTemporary result(this, thisValue);
- GPRReg resultGPR = result.gpr();
- m_jit.move(thisValueGPR, resultGPR);
- cellResult(resultGPR, m_compileIndex);
- break;
- }
-
- JSValueOperand thisValue(this, node.child1());
+ ASSERT(node->child1().useKind() == UntypedUse);
+
+ JSValueOperand thisValue(this, node->child1());
GPRReg thisValueTagGPR = thisValue.tagGPR();
GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
@@ -3908,7 +3695,7 @@ void SpeculativeJIT::compile(Node& node)
GPRResult resultPayload(this);
callOperation(operationConvertThis, resultTag.gpr(), resultPayload.gpr(), thisValueTagGPR, thisValuePayloadGPR);
- cellResult(resultPayload.gpr(), m_compileIndex);
+ cellResult(resultPayload.gpr(), node);
break;
}
@@ -3919,106 +3706,150 @@ void SpeculativeJIT::compile(Node& node)
// then we speculate because we want to get recompiled if it isn't (since
// otherwise we'd start taking slow path a lot).
- SpeculateCellOperand callee(this, node.child1());
+ SpeculateCellOperand callee(this, node->child1());
GPRTemporary result(this);
+ GPRTemporary allocator(this);
GPRTemporary structure(this);
GPRTemporary scratch(this);
GPRReg calleeGPR = callee.gpr();
GPRReg resultGPR = result.gpr();
+ GPRReg allocatorGPR = allocator.gpr();
GPRReg structureGPR = structure.gpr();
GPRReg scratchGPR = scratch.gpr();
- // Load the inheritorID. If the inheritorID is not set, go to slow path.
- m_jit.loadPtr(MacroAssembler::Address(calleeGPR, JSFunction::offsetOfCachedInheritorID()), structureGPR);
MacroAssembler::JumpList slowPath;
- slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, structureGPR));
-
- emitAllocateJSFinalObject(structureGPR, resultGPR, scratchGPR, slowPath);
-
- addSlowPathGenerator(slowPathCall(slowPath, this, operationCreateThis, resultGPR, calleeGPR));
+
+ m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
+ m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
+ slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR));
+ emitAllocateJSObject(resultGPR, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath);
+
+ addSlowPathGenerator(slowPathCall(slowPath, this, operationCreateThis, resultGPR, calleeGPR, node->inlineCapacity()));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
- case InheritorIDWatchpoint: {
- jsCast<JSFunction*>(node.function())->addInheritorIDWatchpoint(speculationWatchpoint());
- noResult(m_compileIndex);
+ case AllocationProfileWatchpoint: {
+ jsCast<JSFunction*>(node->function())->addAllocationProfileWatchpoint(speculationWatchpoint());
+ noResult(node);
break;
}
case NewObject: {
GPRTemporary result(this);
+ GPRTemporary allocator(this);
GPRTemporary scratch(this);
GPRReg resultGPR = result.gpr();
+ GPRReg allocatorGPR = allocator.gpr();
GPRReg scratchGPR = scratch.gpr();
MacroAssembler::JumpList slowPath;
- emitAllocateJSFinalObject(MacroAssembler::TrustedImmPtr(node.structure()), resultGPR, scratchGPR, slowPath);
-
- addSlowPathGenerator(slowPathCall(slowPath, this, operationNewObject, resultGPR, node.structure()));
+ Structure* structure = node->structure();
+ size_t allocationSize = JSObject::allocationSize(structure->inlineCapacity());
+ MarkedAllocator* allocatorPtr = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize);
+
+ m_jit.move(TrustedImmPtr(allocatorPtr), allocatorGPR);
+ emitAllocateJSObject(resultGPR, allocatorGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath);
+
+ addSlowPathGenerator(slowPathCall(slowPath, this, operationNewObject, resultGPR, structure));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case GetCallee: {
GPRTemporary result(this);
- m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::Callee)), result.gpr());
- cellResult(result.gpr(), m_compileIndex);
+ m_jit.loadPtr(JITCompiler::payloadFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::Callee))), result.gpr());
+ cellResult(result.gpr(), node);
break;
}
-
+
+ case SetCallee: {
+ SpeculateCellOperand callee(this, node->child1());
+ m_jit.storePtr(callee.gpr(), JITCompiler::payloadFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::Callee))));
+ m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), JITCompiler::tagFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::Callee))));
+ noResult(node);
+ break;
+ }
+
case GetScope: {
+ SpeculateCellOperand function(this, node->child1());
+ GPRTemporary result(this, function);
+ m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSFunction::offsetOfScopeChain()), result.gpr());
+ cellResult(result.gpr(), node);
+ break;
+ }
+
+ case GetMyScope: {
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
- m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::ScopeChain)), resultGPR);
- bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain();
- int skip = node.scopeChainDepth();
- ASSERT(skip || !checkTopLevel);
- if (checkTopLevel && skip--) {
- JITCompiler::Jump activationNotCreated;
- if (checkTopLevel)
- activationNotCreated = m_jit.branchTestPtr(JITCompiler::Zero, JITCompiler::addressFor(static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
- m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
- activationNotCreated.link(&m_jit);
- }
- while (skip--)
- m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
+ m_jit.loadPtr(JITCompiler::payloadFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::ScopeChain))), resultGPR);
+ cellResult(resultGPR, node);
+ break;
+ }
+
+ case SetMyScope: {
+ SpeculateCellOperand callee(this, node->child1());
+ m_jit.storePtr(callee.gpr(), JITCompiler::payloadFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::ScopeChain))));
+ noResult(node);
+ break;
+ }
- cellResult(resultGPR, m_compileIndex);
+ case SkipTopScope: {
+ SpeculateCellOperand scope(this, node->child1());
+ GPRTemporary result(this, scope);
+ GPRReg resultGPR = result.gpr();
+ m_jit.move(scope.gpr(), resultGPR);
+ JITCompiler::Jump activationNotCreated =
+ m_jit.branchTestPtr(
+ JITCompiler::Zero,
+ JITCompiler::payloadFor(
+ static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
+ activationNotCreated.link(&m_jit);
+ cellResult(resultGPR, node);
break;
}
+
+ case SkipScope: {
+ SpeculateCellOperand scope(this, node->child1());
+ GPRTemporary result(this, scope);
+ m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSScope::offsetOfNext()), result.gpr());
+ cellResult(result.gpr(), node);
+ break;
+ }
+
case GetScopeRegisters: {
- SpeculateCellOperand scope(this, node.child1());
+ SpeculateCellOperand scope(this, node->child1());
GPRTemporary result(this);
GPRReg scopeGPR = scope.gpr();
GPRReg resultGPR = result.gpr();
m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
- storageResult(resultGPR, m_compileIndex);
+ storageResult(resultGPR, node);
break;
}
case GetScopedVar: {
- StorageOperand registers(this, node.child1());
+ StorageOperand registers(this, node->child1());
GPRTemporary resultTag(this);
GPRTemporary resultPayload(this);
GPRReg registersGPR = registers.gpr();
GPRReg resultTagGPR = resultTag.gpr();
GPRReg resultPayloadGPR = resultPayload.gpr();
- m_jit.load32(JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
- m_jit.load32(JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
+ m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
+ m_jit.load32(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
case PutScopedVar: {
- SpeculateCellOperand scope(this, node.child1());
- StorageOperand registers(this, node.child2());
- JSValueOperand value(this, node.child3());
+ SpeculateCellOperand scope(this, node->child1());
+ StorageOperand registers(this, node->child2());
+ JSValueOperand value(this, node->child3());
GPRTemporary scratchRegister(this);
GPRReg scopeGPR = scope.gpr();
GPRReg registersGPR = registers.gpr();
@@ -4026,21 +3857,21 @@ void SpeculativeJIT::compile(Node& node)
GPRReg valuePayloadGPR = value.payloadGPR();
GPRReg scratchGPR = scratchRegister.gpr();
- m_jit.store32(valueTagGPR, JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
- m_jit.store32(valuePayloadGPR, JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
- writeBarrier(scopeGPR, valueTagGPR, node.child2(), WriteBarrierForVariableAccess, scratchGPR);
- noResult(m_compileIndex);
+ m_jit.store32(valueTagGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
+ m_jit.store32(valuePayloadGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
+ writeBarrier(scopeGPR, valueTagGPR, node->child2(), WriteBarrierForVariableAccess, scratchGPR);
+ noResult(node);
break;
}
case GetById: {
- if (!node.prediction()) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ if (!node->prediction()) {
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
- if (isCellSpeculation(at(node.child1()).prediction())) {
- SpeculateCellOperand base(this, node.child1());
+ if (isCellSpeculation(node->child1()->prediction())) {
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary resultTag(this, base);
GPRTemporary resultPayload(this);
@@ -4050,13 +3881,13 @@ void SpeculativeJIT::compile(Node& node)
base.use();
- cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber());
+ cachedGetById(node->codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber());
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
break;
}
- JSValueOperand base(this, node.child1());
+ JSValueOperand base(this, node->child1());
GPRTemporary resultTag(this, base);
GPRTemporary resultPayload(this);
@@ -4069,20 +3900,21 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
- cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), notCell);
+ cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
break;
}
case GetByIdFlush: {
- if (!node.prediction()) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ if (!node->prediction()) {
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
- if (isCellSpeculation(at(node.child1()).prediction())) {
- SpeculateCellOperand base(this, node.child1());
+ switch (node->child1().useKind()) {
+ case CellUse: {
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseGPR = base.gpr();
@@ -4095,30 +3927,38 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
- cachedGetById(node.codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill);
+ cachedGetById(node->codeOrigin, InvalidGPRReg, baseGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), JITCompiler::Jump(), DontSpill);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
break;
}
- JSValueOperand base(this, node.child1());
- GPRReg baseTagGPR = base.tagGPR();
- GPRReg basePayloadGPR = base.payloadGPR();
+ case UntypedUse: {
+ JSValueOperand base(this, node->child1());
+ GPRReg baseTagGPR = base.tagGPR();
+ GPRReg basePayloadGPR = base.payloadGPR();
- GPRResult resultTag(this);
- GPRResult2 resultPayload(this);
- GPRReg resultTagGPR = resultTag.gpr();
- GPRReg resultPayloadGPR = resultPayload.gpr();
+ GPRResult resultTag(this);
+ GPRResult2 resultPayload(this);
+ GPRReg resultTagGPR = resultTag.gpr();
+ GPRReg resultPayloadGPR = resultPayload.gpr();
- base.use();
+ base.use();
- flushRegisters();
+ flushRegisters();
- JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
+ JITCompiler::Jump notCell = m_jit.branch32(JITCompiler::NotEqual, baseTagGPR, TrustedImm32(JSValue::CellTag));
- cachedGetById(node.codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node.identifierNumber(), notCell, DontSpill);
+ cachedGetById(node->codeOrigin, baseTagGPR, basePayloadGPR, resultTagGPR, resultPayloadGPR, node->identifierNumber(), notCell, DontSpill);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
@@ -4127,34 +3967,32 @@ void SpeculativeJIT::compile(Node& node)
break;
case CheckFunction: {
- SpeculateCellOperand function(this, node.child1());
- speculationCheck(BadCache, JSValueSource::unboxedCell(function.gpr()), node.child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node.function()));
- noResult(m_compileIndex);
+ SpeculateCellOperand function(this, node->child1());
+ speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()));
+ noResult(node);
break;
}
+ case CheckExecutable: {
+ SpeculateCellOperand function(this, node->child1());
+ speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
+ noResult(node);
+ break;
+ }
+
case CheckStructure:
case ForwardCheckStructure: {
- AbstractValue& value = m_state.forNode(node.child1());
- if (value.m_currentKnownStructure.isSubsetOf(node.structureSet())
- && isCellSpeculation(value.m_type)) {
- noResult(m_compileIndex);
- break;
- }
-
- SpeculationDirection direction = node.op() == ForwardCheckStructure ? ForwardSpeculation : BackwardSpeculation;
- SpeculateCellOperand base(this, node.child1(), direction);
+ SpeculateCellOperand base(this, node->child1());
- ASSERT(node.structureSet().size());
+ ASSERT(node->structureSet().size());
- if (node.structureSet().size() == 1) {
+ if (node->structureSet().size() == 1) {
speculationCheck(
- BadCache, JSValueSource::unboxedCell(base.gpr()), NoNode,
+ BadCache, JSValueSource::unboxedCell(base.gpr()), 0,
m_jit.branchWeakPtr(
JITCompiler::NotEqual,
JITCompiler::Address(base.gpr(), JSCell::structureOffset()),
- node.structureSet()[0]),
- direction);
+ node->structureSet()[0]));
} else {
GPRTemporary structure(this);
@@ -4162,19 +4000,18 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::JumpList done;
- for (size_t i = 0; i < node.structureSet().size() - 1; ++i)
- done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node.structureSet()[i]));
+ for (size_t i = 0; i < node->structureSet().size() - 1; ++i)
+ done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node->structureSet()[i]));
speculationCheck(
- BadCache, JSValueSource::unboxedCell(base.gpr()), NoNode,
+ BadCache, JSValueSource::unboxedCell(base.gpr()), 0,
m_jit.branchWeakPtr(
- JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()),
- direction);
+ JITCompiler::NotEqual, structure.gpr(), node->structureSet().last()));
done.link(&m_jit);
}
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4187,54 +4024,54 @@ void SpeculativeJIT::compile(Node& node)
// we'll just rely on the fact that when a watchpoint fires then that's
// quite a hint already.
- SpeculationDirection direction = node.op() == ForwardStructureTransitionWatchpoint ? ForwardSpeculation : BackwardSpeculation;
-
- m_jit.addWeakReference(node.structure());
- node.structure()->addTransitionWatchpoint(
+ m_jit.addWeakReference(node->structure());
+ node->structure()->addTransitionWatchpoint(
speculationWatchpoint(
- m_jit.graph()[node.child1()].op() == WeakJSConstant ? BadWeakConstantCache : BadCache,
- direction));
+ node->child1()->op() == WeakJSConstant ? BadWeakConstantCache : BadCache));
#if !ASSERT_DISABLED
- SpeculateCellOperand op1(this, node.child1(), direction);
- JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node.structure()));
+ SpeculateCellOperand op1(this, node->child1());
+ JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node->structure()));
m_jit.breakpoint();
isOK.link(&m_jit);
+#else
+ speculateCell(node->child1());
#endif
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case PhantomPutStructure: {
- ASSERT(node.structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
+ ASSERT(isKnownCell(node->child1().node()));
+ ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
m_jit.addWeakReferenceTransition(
- node.codeOrigin.codeOriginOwner(),
- node.structureTransitionData().previousStructure,
- node.structureTransitionData().newStructure);
- noResult(m_compileIndex);
+ node->codeOrigin.codeOriginOwner(),
+ node->structureTransitionData().previousStructure,
+ node->structureTransitionData().newStructure);
+ noResult(node);
break;
}
case PutStructure: {
- ASSERT(node.structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
+ ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseGPR = base.gpr();
m_jit.addWeakReferenceTransition(
- node.codeOrigin.codeOriginOwner(),
- node.structureTransitionData().previousStructure,
- node.structureTransitionData().newStructure);
+ node->codeOrigin.codeOriginOwner(),
+ node->structureTransitionData().previousStructure,
+ node->structureTransitionData().newStructure);
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
// Must always emit this write barrier as the structure transition itself requires it
- writeBarrier(baseGPR, node.structureTransitionData().newStructure, WriteBarrierForGenericAccess);
+ writeBarrier(baseGPR, node->structureTransitionData().newStructure, WriteBarrierForGenericAccess);
#endif
- m_jit.storePtr(MacroAssembler::TrustedImmPtr(node.structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
+ m_jit.storePtr(MacroAssembler::TrustedImmPtr(node->structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4247,7 +4084,7 @@ void SpeculativeJIT::compile(Node& node)
break;
case GetButterfly: {
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary result(this, base);
GPRReg baseGPR = base.gpr();
@@ -4255,7 +4092,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::butterflyOffset()), resultGPR);
- storageResult(resultGPR, m_compileIndex);
+ storageResult(resultGPR, node);
break;
}
@@ -4265,7 +4102,7 @@ void SpeculativeJIT::compile(Node& node)
}
case GetByOffset: {
- StorageOperand storage(this, node.child1());
+ StorageOperand storage(this, node->child1());
GPRTemporary resultTag(this, storage);
GPRTemporary resultPayload(this);
@@ -4273,42 +4110,42 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultTagGPR = resultTag.gpr();
GPRReg resultPayloadGPR = resultPayload.gpr();
- StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
+ StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
m_jit.load32(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
m_jit.load32(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
case PutByOffset: {
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
- SpeculateCellOperand base(this, node.child2());
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ SpeculateCellOperand base(this, node->child2());
#endif
- StorageOperand storage(this, node.child1());
- JSValueOperand value(this, node.child3());
+ StorageOperand storage(this, node->child1());
+ JSValueOperand value(this, node->child3());
GPRReg storageGPR = storage.gpr();
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
- writeBarrier(base.gpr(), valueTagGPR, node.child3(), WriteBarrierForPropertyAccess);
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ writeBarrier(base.gpr(), valueTagGPR, node->child3(), WriteBarrierForPropertyAccess);
#endif
- StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
+ StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
m_jit.storePtr(valueTagGPR, JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
m_jit.storePtr(valuePayloadGPR, JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case PutById: {
- SpeculateCellOperand base(this, node.child1());
- JSValueOperand value(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ JSValueOperand value(this, node->child2());
GPRTemporary scratch(this);
GPRReg baseGPR = base.gpr();
@@ -4319,15 +4156,15 @@ void SpeculativeJIT::compile(Node& node)
base.use();
value.use();
- cachedPutById(node.codeOrigin, baseGPR, valueTagGPR, valuePayloadGPR, node.child2(), scratchGPR, node.identifierNumber(), NotDirect);
+ cachedPutById(node->codeOrigin, baseGPR, valueTagGPR, valuePayloadGPR, node->child2(), scratchGPR, node->identifierNumber(), NotDirect);
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
case PutByIdDirect: {
- SpeculateCellOperand base(this, node.child1());
- JSValueOperand value(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ JSValueOperand value(this, node->child2());
GPRTemporary scratch(this);
GPRReg baseGPR = base.gpr();
@@ -4338,9 +4175,9 @@ void SpeculativeJIT::compile(Node& node)
base.use();
value.use();
- cachedPutById(node.codeOrigin, baseGPR, valueTagGPR, valuePayloadGPR, node.child2(), scratchGPR, node.identifierNumber(), Direct);
+ cachedPutById(node->codeOrigin, baseGPR, valueTagGPR, valuePayloadGPR, node->child2(), scratchGPR, node->identifierNumber(), Direct);
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
@@ -4348,40 +4185,40 @@ void SpeculativeJIT::compile(Node& node)
GPRTemporary resultPayload(this);
GPRTemporary resultTag(this);
- m_jit.move(TrustedImmPtr(node.registerPointer()), resultPayload.gpr());
+ m_jit.move(TrustedImmPtr(node->registerPointer()), resultPayload.gpr());
m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTag.gpr());
m_jit.load32(JITCompiler::Address(resultPayload.gpr(), OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayload.gpr());
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
case PutGlobalVar: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
if (Heap::isWriteBarrierEnabled()) {
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
- writeBarrier(m_jit.globalObjectFor(node.codeOrigin), value.tagGPR(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
+ writeBarrier(m_jit.globalObjectFor(node->codeOrigin), value.tagGPR(), node->child1(), WriteBarrierForVariableAccess, scratchReg);
}
// FIXME: if we happen to have a spare register - and _ONLY_ if we happen to have
// a spare register - a good optimization would be to put the register pointer into
// a register and then do a zero offset store followed by a four-offset store (or
// vice-versa depending on endianness).
- m_jit.store32(value.tagGPR(), node.registerPointer()->tagPointer());
- m_jit.store32(value.payloadGPR(), node.registerPointer()->payloadPointer());
+ m_jit.store32(value.tagGPR(), node->registerPointer()->tagPointer());
+ m_jit.store32(value.payloadGPR(), node->registerPointer()->payloadPointer());
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case PutGlobalVarCheck: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
WatchpointSet* watchpointSet =
- m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
- identifier(node.identifierNumberForCheck())->impl()).watchpointSet();
+ m_jit.globalObjectFor(node->codeOrigin)->symbolTable()->get(
+ identifier(node->identifierNumberForCheck())->impl()).watchpointSet();
addSlowPathGenerator(
slowPathCall(
m_jit.branchTest8(
@@ -4393,54 +4230,54 @@ void SpeculativeJIT::compile(Node& node)
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
- writeBarrier(m_jit.globalObjectFor(node.codeOrigin), value.tagGPR(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
+ writeBarrier(m_jit.globalObjectFor(node->codeOrigin), value.tagGPR(), node->child1(), WriteBarrierForVariableAccess, scratchReg);
}
// FIXME: if we happen to have a spare register - and _ONLY_ if we happen to have
// a spare register - a good optimization would be to put the register pointer into
// a register and then do a zero offset store followed by a four-offset store (or
// vice-versa depending on endianness).
- m_jit.store32(value.tagGPR(), node.registerPointer()->tagPointer());
- m_jit.store32(value.payloadGPR(), node.registerPointer()->payloadPointer());
+ m_jit.store32(value.tagGPR(), node->registerPointer()->tagPointer());
+ m_jit.store32(value.payloadGPR(), node->registerPointer()->payloadPointer());
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case GlobalVarWatchpoint: {
- m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
- identifier(node.identifierNumberForCheck())->impl()).addWatchpoint(
+ m_jit.globalObjectFor(node->codeOrigin)->symbolTable()->get(
+ identifier(node->identifierNumberForCheck())->impl()).addWatchpoint(
speculationWatchpoint());
#if DFG_ENABLE(JIT_ASSERT)
GPRTemporary scratch(this);
GPRReg scratchGPR = scratch.gpr();
- m_jit.load32(node.registerPointer()->tagPointer(), scratchGPR);
+ m_jit.load32(node->registerPointer()->tagPointer(), scratchGPR);
JITCompiler::Jump notOK = m_jit.branch32(
JITCompiler::NotEqual, scratchGPR,
- TrustedImm32(node.registerPointer()->get().tag()));
- m_jit.load32(node.registerPointer()->payloadPointer(), scratchGPR);
+ TrustedImm32(node->registerPointer()->get().tag()));
+ m_jit.load32(node->registerPointer()->payloadPointer(), scratchGPR);
JITCompiler::Jump ok = m_jit.branch32(
JITCompiler::Equal, scratchGPR,
- TrustedImm32(node.registerPointer()->get().payload()));
+ TrustedImm32(node->registerPointer()->get().payload()));
notOK.link(&m_jit);
m_jit.breakpoint();
ok.link(&m_jit);
#endif
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case CheckHasInstance: {
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary structure(this);
// Speculate that base 'ImplementsDefaultHasInstance'.
m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4450,9 +4287,11 @@ void SpeculativeJIT::compile(Node& node)
}
case IsUndefined: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this);
-
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+
JITCompiler::Jump isCell = m_jit.branch32(JITCompiler::Equal, value.tagGPR(), JITCompiler::TrustedImm32(JSValue::CellTag));
m_jit.compare32(JITCompiler::Equal, value.tagGPR(), TrustedImm32(JSValue::UndefinedTag), result.gpr());
@@ -4460,8 +4299,8 @@ void SpeculativeJIT::compile(Node& node)
isCell.link(&m_jit);
JITCompiler::Jump notMasqueradesAsUndefined;
- if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
m_jit.move(TrustedImm32(0), result.gpr());
notMasqueradesAsUndefined = m_jit.jump();
} else {
@@ -4471,42 +4310,40 @@ void SpeculativeJIT::compile(Node& node)
notMasqueradesAsUndefined = m_jit.jump();
isMasqueradesAsUndefined.link(&m_jit);
- GPRTemporary localGlobalObject(this);
- GPRTemporary remoteGlobalObject(this);
GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
- m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), localGlobalObjectGPR);
+ m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node->codeOrigin)), localGlobalObjectGPR);
m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR);
m_jit.compare32(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr());
}
notMasqueradesAsUndefined.link(&m_jit);
done.link(&m_jit);
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
case IsBoolean: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.compare32(JITCompiler::Equal, value.tagGPR(), JITCompiler::TrustedImm32(JSValue::BooleanTag), result.gpr());
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
case IsNumber: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.add32(TrustedImm32(1), value.tagGPR(), result.gpr());
m_jit.compare32(JITCompiler::Below, result.gpr(), JITCompiler::TrustedImm32(JSValue::LowestTag + 1), result.gpr());
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
case IsString: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
JITCompiler::Jump isNotCell = m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), JITCompiler::TrustedImm32(JSValue::CellTag));
@@ -4519,31 +4356,92 @@ void SpeculativeJIT::compile(Node& node)
m_jit.move(TrustedImm32(0), result.gpr());
done.link(&m_jit);
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
case IsObject: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
GPRResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
callOperation(operationIsObject, resultGPR, valueTagGPR, valuePayloadGPR);
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
break;
}
case IsFunction: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
GPRResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
callOperation(operationIsFunction, resultGPR, valueTagGPR, valuePayloadGPR);
- booleanResult(result.gpr(), m_compileIndex);
+ booleanResult(result.gpr(), node);
+ break;
+ }
+ case TypeOf: {
+ JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
+ GPRReg tagGPR = value.tagGPR();
+ GPRReg payloadGPR = value.payloadGPR();
+ GPRTemporary temp(this);
+ GPRReg tempGPR = temp.gpr();
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+ JITCompiler::JumpList doneJumps;
+
+ flushRegisters();
+
+ ASSERT(node->child1().useKind() == UntypedUse || node->child1().useKind() == CellUse || node->child1().useKind() == StringUse);
+
+ JITCompiler::Jump isNotCell = m_jit.branch32(JITCompiler::NotEqual, tagGPR, JITCompiler::TrustedImm32(JSValue::CellTag));
+ if (node->child1().useKind() != UntypedUse)
+ speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node->child1(), isNotCell);
+
+ if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
+ m_jit.loadPtr(JITCompiler::Address(payloadGPR, JSCell::structureOffset()), tempGPR);
+ JITCompiler::Jump notString = m_jit.branch8(JITCompiler::NotEqual, JITCompiler::Address(tempGPR, Structure::typeInfoTypeOffset()), TrustedImm32(StringType));
+ if (node->child1().useKind() == StringUse)
+ DFG_TYPE_CHECK(JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecString, notString);
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.stringString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ if (node->child1().useKind() != StringUse) {
+ notString.link(&m_jit);
+ callOperation(operationTypeOf, resultGPR, payloadGPR);
+ doneJumps.append(m_jit.jump());
+ }
+ } else {
+ callOperation(operationTypeOf, resultGPR, payloadGPR);
+ doneJumps.append(m_jit.jump());
+ }
+
+ if (node->child1().useKind() == UntypedUse) {
+ isNotCell.link(&m_jit);
+
+ m_jit.add32(TrustedImm32(1), tagGPR, tempGPR);
+ JITCompiler::Jump notNumber = m_jit.branch32(JITCompiler::AboveOrEqual, tempGPR, JITCompiler::TrustedImm32(JSValue::LowestTag + 1));
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.numberString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ notNumber.link(&m_jit);
+
+ JITCompiler::Jump notUndefined = m_jit.branch32(JITCompiler::NotEqual, tagGPR, TrustedImm32(JSValue::UndefinedTag));
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.undefinedString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ notUndefined.link(&m_jit);
+
+ JITCompiler::Jump notNull = m_jit.branch32(JITCompiler::NotEqual, tagGPR, TrustedImm32(JSValue::NullTag));
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.objectString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ notNull.link(&m_jit);
+
+ // Only boolean left
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.booleanString()), resultGPR);
+ }
+ doneJumps.link(&m_jit);
+ cellResult(resultGPR, node);
break;
}
@@ -4555,7 +4453,7 @@ void SpeculativeJIT::compile(Node& node)
#if ENABLE(DEBUG_WITH_BREAKPOINT)
m_jit.breakpoint();
#else
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif
break;
@@ -4568,9 +4466,9 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
GPRResult resultPayload(this);
GPRResult2 resultTag(this);
- ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node.resolveOperationsDataIndex()];
- callOperation(operationResolve, resultTag.gpr(), resultPayload.gpr(), identifier(data.identifierNumber), resolveOperations(data.resolveOperationsIndex));
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node->resolveOperationsDataIndex()];
+ callOperation(operationResolve, resultTag.gpr(), resultPayload.gpr(), identifier(data.identifierNumber), data.resolveOperations);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
@@ -4578,9 +4476,9 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
GPRResult resultPayload(this);
GPRResult2 resultTag(this);
- ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node.resolveOperationsDataIndex()];
- callOperation(operationResolveBase, resultTag.gpr(), resultPayload.gpr(), identifier(data.identifierNumber), resolveOperations(data.resolveOperationsIndex), putToBaseOperation(data.putToBaseOperationIndex));
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node->resolveOperationsDataIndex()];
+ callOperation(operationResolveBase, resultTag.gpr(), resultPayload.gpr(), identifier(data.identifierNumber), data.resolveOperations, data.putToBaseOperation);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
@@ -4588,9 +4486,9 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
GPRResult resultPayload(this);
GPRResult2 resultTag(this);
- ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node.resolveOperationsDataIndex()];
- callOperation(operationResolveBaseStrictPut, resultTag.gpr(), resultPayload.gpr(), identifier(data.identifierNumber), resolveOperations(data.resolveOperationsIndex), putToBaseOperation(data.putToBaseOperationIndex));
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
+ ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node->resolveOperationsDataIndex()];
+ callOperation(operationResolveBaseStrictPut, resultTag.gpr(), resultPayload.gpr(), identifier(data.identifierNumber), data.resolveOperations, data.putToBaseOperation);
+ jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
break;
}
@@ -4605,11 +4503,11 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultTagGPR = resultTag.gpr();
GPRReg resultPayloadGPR = resultPayload.gpr();
- ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node.resolveGlobalDataIndex()];
- ResolveOperation* resolveOperationAddress = &(m_jit.codeBlock()->resolveOperations(data.resolveOperationsIndex)->data()[data.resolvePropertyIndex]);
+ ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node->resolveGlobalDataIndex()];
+ ResolveOperation* resolveOperationAddress = &(data.resolveOperations->data()[data.resolvePropertyIndex]);
// Check Structure of global object
- m_jit.move(JITCompiler::TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), globalObjectGPR);
+ m_jit.move(JITCompiler::TrustedImmPtr(m_jit.globalObjectFor(node->codeOrigin)), globalObjectGPR);
m_jit.move(JITCompiler::TrustedImmPtr(resolveOperationAddress), resolveInfoGPR);
m_jit.loadPtr(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(ResolveOperation, m_structure)), resultPayloadGPR);
@@ -4634,12 +4532,12 @@ void SpeculativeJIT::compile(Node& node)
JSValueRegs(resultTagGPR, resultPayloadGPR), resolveInfoGPR, globalObjectGPR,
&m_jit.codeBlock()->identifier(data.identifierNumber)));
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
case CreateActivation: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value, false);
GPRReg valueTagGPR = value.tagGPR();
@@ -4653,12 +4551,12 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(
slowPathCall(notCreated, this, operationCreateActivation, resultGPR));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case CreateArguments: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value, false);
GPRReg valueTagGPR = value.tagGPR();
@@ -4669,22 +4567,22 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
addSlowPathGenerator(
slowPathCall(
notCreated, this, operationCreateInlinedArguments, resultGPR,
- node.codeOrigin.inlineCallFrame));
+ node->codeOrigin.inlineCallFrame));
} else {
addSlowPathGenerator(
slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
}
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case TearOffActivation: {
- JSValueOperand activationValue(this, node.child1());
+ JSValueOperand activationValue(this, node->child1());
GPRTemporary scratch(this);
GPRReg activationValueTagGPR = activationValue.tagGPR();
@@ -4693,7 +4591,7 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, activationValueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
- SharedSymbolTable* symbolTable = m_jit.symbolTableFor(node.codeOrigin);
+ SharedSymbolTable* symbolTable = m_jit.symbolTableFor(node->codeOrigin);
int registersOffset = JSActivation::registersOffset(symbolTable);
int captureEnd = symbolTable->captureEnd();
@@ -4717,24 +4615,24 @@ void SpeculativeJIT::compile(Node& node)
m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValuePayloadGPR, JSActivation::offsetOfRegisters()));
notCreated.link(&m_jit);
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case TearOffArguments: {
- JSValueOperand unmodifiedArgumentsValue(this, node.child1());
- JSValueOperand activationValue(this, node.child2());
+ JSValueOperand unmodifiedArgumentsValue(this, node->child1());
+ JSValueOperand activationValue(this, node->child2());
GPRReg unmodifiedArgumentsValuePayloadGPR = unmodifiedArgumentsValue.payloadGPR();
GPRReg activationValuePayloadGPR = activationValue.payloadGPR();
JITCompiler::Jump created = m_jit.branchTest32(
JITCompiler::NonZero, unmodifiedArgumentsValuePayloadGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
addSlowPathGenerator(
slowPathCall(
created, this, operationTearOffInlinedArguments, NoResult,
- unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR, node.codeOrigin.inlineCallFrame));
+ unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR, node->codeOrigin.inlineCallFrame));
} else {
addSlowPathGenerator(
slowPathCall(
@@ -4742,21 +4640,21 @@ void SpeculativeJIT::compile(Node& node)
unmodifiedArgumentsValuePayloadGPR, activationValuePayloadGPR));
}
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case CheckArgumentsNotCreated: {
ASSERT(!isEmptySpeculation(
m_state.variables().operand(
- m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type));
+ m_jit.graph().argumentsRegisterFor(node->codeOrigin)).m_type));
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::NotEqual,
- JITCompiler::tagFor(m_jit.argumentsRegisterFor(node.codeOrigin)),
+ JITCompiler::tagFor(m_jit.argumentsRegisterFor(node->codeOrigin)),
TrustedImm32(JSValue::EmptyValueTag)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4766,19 +4664,19 @@ void SpeculativeJIT::compile(Node& node)
if (!isEmptySpeculation(
m_state.variables().operand(
- m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type)) {
+ m_jit.graph().argumentsRegisterFor(node->codeOrigin)).m_type)) {
speculationCheck(
- ArgumentsEscaped, JSValueRegs(), NoNode,
+ ArgumentsEscaped, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::NotEqual,
- JITCompiler::tagFor(m_jit.argumentsRegisterFor(node.codeOrigin)),
+ JITCompiler::tagFor(m_jit.argumentsRegisterFor(node->codeOrigin)),
TrustedImm32(JSValue::EmptyValueTag)));
}
- ASSERT(!node.codeOrigin.inlineCallFrame);
+ ASSERT(!node->codeOrigin.inlineCallFrame);
m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
m_jit.sub32(TrustedImm32(1), resultGPR);
- integerResult(resultGPR, m_compileIndex);
+ integerResult(resultGPR, node);
break;
}
@@ -4790,12 +4688,12 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump created = m_jit.branch32(
JITCompiler::NotEqual,
- JITCompiler::tagFor(m_jit.argumentsRegisterFor(node.codeOrigin)),
+ JITCompiler::tagFor(m_jit.argumentsRegisterFor(node->codeOrigin)),
TrustedImm32(JSValue::EmptyValueTag));
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
m_jit.move(
- Imm32(node.codeOrigin.inlineCallFrame->arguments.size() - 1),
+ Imm32(node->codeOrigin.inlineCallFrame->arguments.size() - 1),
resultPayloadGPR);
} else {
m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultPayloadGPR);
@@ -4811,14 +4709,14 @@ void SpeculativeJIT::compile(Node& node)
slowPathCall(
created, this, operationGetArgumentsLength,
JSValueRegs(resultTagGPR, resultPayloadGPR),
- m_jit.argumentsRegisterFor(node.codeOrigin)));
+ m_jit.argumentsRegisterFor(node->codeOrigin)));
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
case GetMyArgumentByVal: {
- SpeculateStrictInt32Operand index(this, node.child1());
+ SpeculateStrictInt32Operand index(this, node->child1());
GPRTemporary resultPayload(this);
GPRTemporary resultTag(this);
GPRReg indexGPR = index.gpr();
@@ -4827,27 +4725,27 @@ void SpeculativeJIT::compile(Node& node)
if (!isEmptySpeculation(
m_state.variables().operand(
- m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type)) {
+ m_jit.graph().argumentsRegisterFor(node->codeOrigin)).m_type)) {
speculationCheck(
- ArgumentsEscaped, JSValueRegs(), NoNode,
+ ArgumentsEscaped, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::NotEqual,
- JITCompiler::tagFor(m_jit.argumentsRegisterFor(node.codeOrigin)),
+ JITCompiler::tagFor(m_jit.argumentsRegisterFor(node->codeOrigin)),
TrustedImm32(JSValue::EmptyValueTag)));
}
m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::AboveOrEqual,
resultPayloadGPR,
- Imm32(node.codeOrigin.inlineCallFrame->arguments.size())));
+ Imm32(node->codeOrigin.inlineCallFrame->arguments.size())));
} else {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::AboveOrEqual,
resultPayloadGPR,
@@ -4856,11 +4754,11 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::JumpList slowArgument;
JITCompiler::JumpList slowArgumentOutOfBounds;
- if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node->codeOrigin)->slowArguments()) {
slowArgumentOutOfBounds.append(
m_jit.branch32(
JITCompiler::AboveOrEqual, indexGPR,
- Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+ Imm32(m_jit.symbolTableFor(node->codeOrigin)->parameterCount())));
COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
@@ -4873,12 +4771,12 @@ void SpeculativeJIT::compile(Node& node)
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfLocals(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfLocals(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
slowArgument.append(m_jit.jump());
}
@@ -4889,20 +4787,20 @@ void SpeculativeJIT::compile(Node& node)
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfArgumentsIncludingThis(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfArgumentsIncludingThis(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
slowArgument.link(&m_jit);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
case GetMyArgumentByValSafe: {
- SpeculateStrictInt32Operand index(this, node.child1());
+ SpeculateStrictInt32Operand index(this, node->child1());
GPRTemporary resultPayload(this);
GPRTemporary resultTag(this);
GPRReg indexGPR = index.gpr();
@@ -4913,16 +4811,16 @@ void SpeculativeJIT::compile(Node& node)
slowPath.append(
m_jit.branch32(
JITCompiler::NotEqual,
- JITCompiler::tagFor(m_jit.argumentsRegisterFor(node.codeOrigin)),
+ JITCompiler::tagFor(m_jit.argumentsRegisterFor(node->codeOrigin)),
TrustedImm32(JSValue::EmptyValueTag)));
m_jit.add32(TrustedImm32(1), indexGPR, resultPayloadGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
slowPath.append(
m_jit.branch32(
JITCompiler::AboveOrEqual,
resultPayloadGPR,
- Imm32(node.codeOrigin.inlineCallFrame->arguments.size())));
+ Imm32(node->codeOrigin.inlineCallFrame->arguments.size())));
} else {
slowPath.append(
m_jit.branch32(
@@ -4933,11 +4831,11 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::JumpList slowArgument;
JITCompiler::JumpList slowArgumentOutOfBounds;
- if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node->codeOrigin)->slowArguments()) {
slowArgumentOutOfBounds.append(
m_jit.branch32(
JITCompiler::AboveOrEqual, indexGPR,
- Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+ Imm32(m_jit.symbolTableFor(node->codeOrigin)->parameterCount())));
COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
m_jit.move(ImmPtr(slowArguments), resultPayloadGPR);
@@ -4949,12 +4847,12 @@ void SpeculativeJIT::compile(Node& node)
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfLocals(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfLocals(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfLocals(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
slowArgument.append(m_jit.jump());
}
@@ -4965,31 +4863,31 @@ void SpeculativeJIT::compile(Node& node)
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ m_jit.offsetOfArgumentsIncludingThis(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
resultTagGPR);
m_jit.load32(
JITCompiler::BaseIndex(
GPRInfo::callFrameRegister, resultPayloadGPR, JITCompiler::TimesEight,
- m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
+ m_jit.offsetOfArgumentsIncludingThis(node->codeOrigin) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
resultPayloadGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
addSlowPathGenerator(
slowPathCall(
slowPath, this, operationGetInlinedArgumentByVal,
JSValueRegs(resultTagGPR, resultPayloadGPR),
- m_jit.argumentsRegisterFor(node.codeOrigin),
- node.codeOrigin.inlineCallFrame, indexGPR));
+ m_jit.argumentsRegisterFor(node->codeOrigin),
+ node->codeOrigin.inlineCallFrame, indexGPR));
} else {
addSlowPathGenerator(
slowPathCall(
slowPath, this, operationGetArgumentByVal,
JSValueRegs(resultTagGPR, resultPayloadGPR),
- m_jit.argumentsRegisterFor(node.codeOrigin), indexGPR));
+ m_jit.argumentsRegisterFor(node->codeOrigin), indexGPR));
}
slowArgument.link(&m_jit);
- jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
@@ -4998,23 +4896,26 @@ void SpeculativeJIT::compile(Node& node)
break;
case NewFunction: {
- JSValueOperand value(this, node.child1());
- GPRTemporary result(this, value, false);
+ JSValueOperand value(this, node->child1());
+ GPRTemporary resultTag(this, value);
+ GPRTemporary resultPayload(this, value, false);
GPRReg valueTagGPR = value.tagGPR();
GPRReg valuePayloadGPR = value.payloadGPR();
- GPRReg resultGPR = result.gpr();
+ GPRReg resultTagGPR = resultTag.gpr();
+ GPRReg resultPayloadGPR = resultPayload.gpr();
- m_jit.move(valuePayloadGPR, resultGPR);
+ m_jit.move(valuePayloadGPR, resultPayloadGPR);
+ m_jit.move(valueTagGPR, resultTagGPR);
JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
addSlowPathGenerator(
slowPathCall(
- notCreated, this, operationNewFunction, resultGPR,
- m_jit.codeBlock()->functionDecl(node.functionDeclIndex())));
+ notCreated, this, operationNewFunction, JSValueRegs(resultTagGPR, resultPayloadGPR),
+ m_jit.codeBlock()->functionDecl(node->functionDeclIndex())));
- cellResult(resultGPR, m_compileIndex);
+ jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
@@ -5028,27 +4929,47 @@ void SpeculativeJIT::compile(Node& node)
break;
case ForceOSRExit: {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
+ case CheckWatchdogTimer:
+ speculationCheck(
+ WatchdogTimerFired, JSValueRegs(), 0,
+ m_jit.branchTest8(
+ JITCompiler::NonZero,
+ JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog.timerDidFireAddress())));
+ break;
+
+ case CountExecution:
+ m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node->executionCounter()->address()));
+ break;
+
case Phantom:
+ DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
+ noResult(node);
+ break;
+
+ case PhantomLocal:
// This is a no-op.
- noResult(m_compileIndex);
+ noResult(node);
break;
- case InlineStart:
case Nop:
case LastNodeType:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
-
+
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.clearRegisterAllocationOffsets();
+#endif
+
if (!m_compileOkay)
return;
- if (node.hasResult() && node.mustGenerate())
- use(m_compileIndex);
+ if (node->hasResult() && node->mustGenerate())
+ use(node);
}
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 7b43c5cfc..ab9da9732 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,35 +32,37 @@
#include "ArrayPrototype.h"
#include "DFGCallArrayAllocatorSlowPathGenerator.h"
#include "DFGSlowPathGenerator.h"
+#include "JSCJSValueInlines.h"
#include "ObjectPrototype.h"
namespace JSC { namespace DFG {
#if USE(JSVALUE64)
-GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
+GPRReg SpeculativeJIT::fillInteger(Edge edge, DataFormat& returnFormat)
{
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ ASSERT(!needsTypeCheck(edge, SpecInt32));
+
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
if (info.registerFormat() == DataFormatNone) {
GPRReg gpr = allocate();
- if (node.hasConstant()) {
+ if (edge->hasConstant()) {
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- if (isInt32Constant(nodeIndex)) {
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ if (isInt32Constant(edge.node())) {
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
info.fillInteger(*m_stream, gpr);
returnFormat = DataFormatInteger;
return gpr;
}
- if (isNumberConstant(nodeIndex)) {
- JSValue jsValue = jsNumber(valueOfNumberConstant(nodeIndex));
+ if (isNumberConstant(edge.node())) {
+ JSValue jsValue = jsNumber(valueOfNumberConstant(edge.node()));
m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
} else {
- ASSERT(isJSConstant(nodeIndex));
- JSValue jsValue = valueOfJSConstant(nodeIndex);
+ ASSERT(isJSConstant(edge.node()));
+ JSValue jsValue = valueOfJSConstant(edge.node());
m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
}
} else if (info.spillFormat() == DataFormatInteger) {
@@ -69,7 +71,7 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat
// Tag it, since fillInteger() is used when we want a boxed integer.
m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr);
} else {
- ASSERT(info.spillFormat() == DataFormatJS || info.spillFormat() == DataFormatJSInteger);
+ RELEASE_ASSERT(info.spillFormat() == DataFormatJS || info.spillFormat() == DataFormatJSInteger);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
}
@@ -93,7 +95,7 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat
case DataFormatJSBoolean:
case DataFormatStorage:
// Should only be calling this function if we know this operand to be integer.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case DataFormatJSInteger: {
GPRReg gpr = info.gpr();
@@ -112,183 +114,32 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-FPRReg SpeculativeJIT::fillDouble(NodeIndex nodeIndex)
-{
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
-
- if (info.registerFormat() == DataFormatNone) {
- if (node.hasConstant()) {
- GPRReg gpr = allocate();
-
- if (isInt32Constant(nodeIndex)) {
- // FIXME: should not be reachable?
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
- m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- info.fillInteger(*m_stream, gpr);
- unlock(gpr);
- } else if (isNumberConstant(nodeIndex)) {
- FPRReg fpr = fprAllocate();
- m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(nodeIndex))), gpr);
- m_jit.move64ToDouble(gpr, fpr);
- unlock(gpr);
-
- m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
- info.fillDouble(*m_stream, fpr);
- return fpr;
- } else {
- // FIXME: should not be reachable?
- ASSERT(isJSConstant(nodeIndex));
- JSValue jsValue = valueOfJSConstant(nodeIndex);
- m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
- m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- info.fillJSValue(*m_stream, gpr, DataFormatJS);
- unlock(gpr);
- }
- } else {
- DataFormat spillFormat = info.spillFormat();
- switch (spillFormat) {
- case DataFormatDouble: {
- FPRReg fpr = fprAllocate();
- m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
- m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
- info.fillDouble(*m_stream, fpr);
- return fpr;
- }
-
- case DataFormatInteger: {
- GPRReg gpr = allocate();
-
- m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
- m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
- info.fillInteger(*m_stream, gpr);
- unlock(gpr);
- break;
- }
-
- default:
- GPRReg gpr = allocate();
-
- ASSERT(spillFormat & DataFormatJS);
- m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
- m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
- info.fillJSValue(*m_stream, gpr, spillFormat);
- unlock(gpr);
- break;
- }
- }
- }
-
- switch (info.registerFormat()) {
- case DataFormatNone:
- // Should have filled, above.
- case DataFormatCell:
- case DataFormatJSCell:
- case DataFormatBoolean:
- case DataFormatJSBoolean:
- case DataFormatStorage:
- // Should only be calling this function if we know this operand to be numeric.
- ASSERT_NOT_REACHED();
-
- case DataFormatJS: {
- GPRReg jsValueGpr = info.gpr();
- m_gprs.lock(jsValueGpr);
- FPRReg fpr = fprAllocate();
- GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?
-
- JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
-
- m_jit.jitAssertIsJSDouble(jsValueGpr);
-
- // First, if we get here we have a double encoded as a JSValue
- m_jit.move(jsValueGpr, tempGpr);
- unboxDouble(tempGpr, fpr);
- JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
-
- // Finally, handle integers.
- isInteger.link(&m_jit);
- m_jit.convertInt32ToDouble(jsValueGpr, fpr);
- hasUnboxedDouble.link(&m_jit);
-
- m_gprs.release(jsValueGpr);
- m_gprs.unlock(jsValueGpr);
- m_gprs.unlock(tempGpr);
- m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
- info.fillDouble(*m_stream, fpr);
- info.killSpilled();
- return fpr;
- }
-
- case DataFormatJSInteger:
- case DataFormatInteger: {
- FPRReg fpr = fprAllocate();
- GPRReg gpr = info.gpr();
- m_gprs.lock(gpr);
- m_jit.convertInt32ToDouble(gpr, fpr);
- m_gprs.unlock(gpr);
- return fpr;
- }
-
- // Unbox the double
- case DataFormatJSDouble: {
- GPRReg gpr = info.gpr();
- FPRReg fpr = fprAllocate();
- if (m_gprs.isLocked(gpr)) {
- // Make sure we don't trample gpr if it is in use.
- GPRReg temp = allocate();
- m_jit.move(gpr, temp);
- unboxDouble(temp, fpr);
- unlock(temp);
- } else
- unboxDouble(gpr, fpr);
-
- m_gprs.release(gpr);
- m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
-
- info.fillDouble(*m_stream, fpr);
- return fpr;
- }
-
- case DataFormatDouble: {
- FPRReg fpr = info.fpr();
- m_fprs.lock(fpr);
- return fpr;
- }
-
- default:
- ASSERT_NOT_REACHED();
- return InvalidFPRReg;
- }
-}
-
-GPRReg SpeculativeJIT::fillJSValue(NodeIndex nodeIndex)
+GPRReg SpeculativeJIT::fillJSValue(Edge edge)
{
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
GPRReg gpr = allocate();
- if (node.hasConstant()) {
- if (isInt32Constant(nodeIndex)) {
+ if (edge->hasConstant()) {
+ if (isInt32Constant(edge.node())) {
info.fillJSValue(*m_stream, gpr, DataFormatJSInteger);
- JSValue jsValue = jsNumber(valueOfInt32Constant(nodeIndex));
+ JSValue jsValue = jsNumber(valueOfInt32Constant(edge.node()));
m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
- } else if (isNumberConstant(nodeIndex)) {
+ } else if (isNumberConstant(edge.node())) {
info.fillJSValue(*m_stream, gpr, DataFormatJSDouble);
- JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(nodeIndex));
+ JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(edge.node()));
m_jit.move(MacroAssembler::Imm64(JSValue::encode(jsValue)), gpr);
} else {
- ASSERT(isJSConstant(nodeIndex));
- JSValue jsValue = valueOfJSConstant(nodeIndex);
+ ASSERT(isJSConstant(edge.node()));
+ JSValue jsValue = valueOfJSConstant(edge.node());
m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
info.fillJSValue(*m_stream, gpr, DataFormatJS);
}
@@ -308,7 +159,7 @@ GPRReg SpeculativeJIT::fillJSValue(NodeIndex nodeIndex)
m_jit.sub64(GPRInfo::tagTypeNumberRegister, gpr);
spillFormat = DataFormatJSDouble;
} else
- ASSERT(spillFormat & DataFormatJS);
+ RELEASE_ASSERT(spillFormat & DataFormatJS);
}
info.fillJSValue(*m_stream, gpr, spillFormat);
}
@@ -357,123 +208,17 @@ GPRReg SpeculativeJIT::fillJSValue(NodeIndex nodeIndex)
case DataFormatBoolean:
case DataFormatStorage:
// this type currently never occurs
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-class ValueToNumberSlowPathGenerator
- : public CallSlowPathGenerator<MacroAssembler::Jump, D_DFGOperation_EJ, GPRReg> {
-public:
- ValueToNumberSlowPathGenerator(
- MacroAssembler::Jump from, SpeculativeJIT* jit,
- GPRReg resultGPR, GPRReg jsValueGPR)
- : CallSlowPathGenerator<MacroAssembler::Jump, D_DFGOperation_EJ, GPRReg>(
- from, jit, dfgConvertJSValueToNumber, NeedToSpill, resultGPR)
- , m_jsValueGPR(jsValueGPR)
- {
- }
-
-protected:
- virtual void generateInternal(SpeculativeJIT* jit)
- {
- setUp(jit);
- recordCall(jit->callOperation(dfgConvertJSValueToNumber, FPRInfo::returnValueFPR, m_jsValueGPR));
- jit->boxDouble(FPRInfo::returnValueFPR, m_result);
- tearDown(jit);
- }
-
-private:
- GPRReg m_jsValueGPR;
-};
-
-void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
-{
- if (isKnownNumeric(node.child1().index())) {
- JSValueOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- m_jit.move(op1.gpr(), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex);
- return;
- }
-
- JSValueOperand op1(this, node.child1());
- GPRTemporary result(this);
-
- ASSERT(!isInt32Constant(node.child1().index()));
- ASSERT(!isNumberConstant(node.child1().index()));
-
- GPRReg jsValueGpr = op1.gpr();
- GPRReg gpr = result.gpr();
- op1.use();
-
- JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
- JITCompiler::Jump nonNumeric = m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister);
-
- // First, if we get here we have a double encoded as a JSValue
- m_jit.move(jsValueGpr, gpr);
- JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
-
- // Finally, handle integers.
- isInteger.link(&m_jit);
- m_jit.or64(GPRInfo::tagTypeNumberRegister, jsValueGpr, gpr);
- hasUnboxedDouble.link(&m_jit);
-
- addSlowPathGenerator(adoptPtr(new ValueToNumberSlowPathGenerator(nonNumeric, this, gpr, jsValueGpr)));
-
- jsValueResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
-}
-
-void SpeculativeJIT::nonSpeculativeValueToInt32(Node& node)
-{
- ASSERT(!isInt32Constant(node.child1().index()));
-
- if (isKnownInteger(node.child1().index())) {
- IntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
- return;
- }
-
- GenerationInfo& childInfo = m_generationInfo[at(node.child1()).virtualRegister()];
- if (childInfo.isJSDouble()) {
- DoubleOperand op1(this, node.child1());
- GPRTemporary result(this);
- FPRReg fpr = op1.fpr();
- GPRReg gpr = result.gpr();
- op1.use();
- JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
-
- addSlowPathGenerator(
- slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
-
- integerResult(gpr, m_compileIndex, UseChildrenCalledExplicitly);
- return;
- }
-
- JSValueOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- GPRReg jsValueGpr = op1.gpr();
- GPRReg resultGPR = result.gpr();
- op1.use();
-
- JITCompiler::Jump isNotInteger = m_jit.branch64(MacroAssembler::Below, jsValueGpr, GPRInfo::tagTypeNumberRegister);
-
- m_jit.zeroExtend32ToPtr(jsValueGpr, resultGPR);
-
- addSlowPathGenerator(
- slowPathCall(isNotInteger, this, dfgConvertJSValueToInt32, resultGPR, jsValueGpr));
-
- integerResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
-}
-
-void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node)
+void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node* node)
{
- IntegerOperand op1(this, node.child1());
+ IntegerOperand op1(this, node->child1());
FPRTemporary boxer(this);
GPRTemporary result(this, op1);
@@ -492,13 +237,13 @@ void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node)
done.link(&m_jit);
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), m_currentNode);
}
void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
{
JITCompiler::DataLabelPtr structureToCompare;
- JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+ JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(unusedPointer)));
JITCompiler::ConvertibleLoadLabel propertyStorageLoad =
m_jit.convertibleLoadPtr(JITCompiler::Address(baseGPR, JSObject::butterflyOffset()), resultGPR);
@@ -532,7 +277,7 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg
{
JITCompiler::DataLabelPtr structureToCompare;
- JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+ JITCompiler::PatchableJump structureCheck = m_jit.patchableBranchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(unusedPointer)));
writeBarrier(baseGPR, valueGPR, valueUse, WriteBarrierForPropertyAccess, scratchGPR);
@@ -543,7 +288,7 @@ void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg
JITCompiler::Label doneLabel = m_jit.label();
V_DFGOperation_EJCI optimizedCall;
- if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) {
+ if (m_jit.strictModeFor(m_currentNode->codeOrigin)) {
if (putKind == Direct)
optimizedCall = operationPutByIdDirectStrictOptimize;
else
@@ -589,15 +334,21 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
JITCompiler::Jump notCell;
- if (!isKnownCell(operand.index()))
- notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
-
JITCompiler::Jump notMasqueradesAsUndefined;
- if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ if (m_jit.graph().globalObjectFor(operand->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
+
+ m_jit.graph().globalObjectFor(operand->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultGPR);
notMasqueradesAsUndefined = m_jit.jump();
} else {
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
+
m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined));
@@ -605,16 +356,14 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
notMasqueradesAsUndefined = m_jit.jump();
isMasqueradesAsUndefined.link(&m_jit);
- GPRTemporary localGlobalObject(this);
- GPRTemporary remoteGlobalObject(this);
GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
- m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.move(JITCompiler::TrustedImmPtr(m_jit.graph().globalObjectFor(operand->codeOrigin)), localGlobalObjectGPR);
m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
m_jit.comparePtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultGPR);
}
- if (!isKnownCell(operand.index())) {
+ if (!isKnownCell(operand.node())) {
JITCompiler::Jump done = m_jit.jump();
notCell.link(&m_jit);
@@ -629,14 +378,13 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
notMasqueradesAsUndefined.link(&m_jit);
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
}
-void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex branchNodeIndex, bool invert)
+void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
if (taken == nextBlock()) {
invert = !invert;
@@ -653,26 +401,30 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex br
JITCompiler::Jump notCell;
- if (!isKnownCell(operand.index()))
- notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
-
- if (m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ if (m_jit.graph().globalObjectFor(operand->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
+
+ m_jit.graph().globalObjectFor(operand->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
jump(invert ? taken : notTaken, ForceJump);
} else {
- m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
- branchTest8(JITCompiler::Zero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), invert ? taken : notTaken);
-
GPRTemporary localGlobalObject(this);
GPRTemporary remoteGlobalObject(this);
+
+ if (!isKnownCell(operand.node()))
+ notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
+
+ m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
+ branchTest8(JITCompiler::Zero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), invert ? taken : notTaken);
+
GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
- m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[operand].codeOrigin)), localGlobalObjectGPR);
+ m_jit.move(TrustedImmPtr(m_jit.graph().globalObjectFor(operand->codeOrigin)), localGlobalObjectGPR);
m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, invert ? notTaken : taken);
}
- if (!isKnownCell(operand.index())) {
+ if (!isKnownCell(operand.node())) {
jump(notTaken, ForceJump);
notCell.link(&m_jit);
@@ -685,20 +437,20 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex br
jump(notTaken);
}
-bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, Edge operand, bool invert)
+bool SpeculativeJIT::nonSpeculativeCompareNull(Node* node, Edge operand, bool invert)
{
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
- NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
+ Node* branchNode = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
- ASSERT(node.adjustedRefCount() == 1);
+ RELEASE_ASSERT(node->adjustedRefCount() == 1);
- nonSpeculativePeepholeBranchNull(operand, branchNodeIndex, invert);
+ nonSpeculativePeepholeBranchNull(operand, branchNode, invert);
- use(node.child1());
- use(node.child2());
+ use(node->child1());
+ use(node->child2());
m_indexInBlock = branchIndexInBlock;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
return true;
}
@@ -708,11 +460,10 @@ bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, Edge operand, bool in
return false;
}
-void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
+void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
@@ -726,14 +477,14 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
notTaken = tmp;
}
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1GPR = arg1.gpr();
GPRReg arg2GPR = arg2.gpr();
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
+ if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -751,14 +502,14 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1().index()))
+ if (!isKnownInteger(node->child1().node()))
slowPath.append(m_jit.branch64(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
- if (!isKnownInteger(node.child2().index()))
+ if (!isKnownInteger(node->child2().node()))
slowPath.append(m_jit.branch64(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
branch32(cond, arg1GPR, arg2GPR, taken);
- if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
+ if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
jump(notTaken, ForceJump);
slowPath.link(&m_jit);
@@ -774,7 +525,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNo
jump(notTaken);
m_indexInBlock = m_jit.graph().m_blocks[m_block]->size() - 1;
- m_compileIndex = branchNodeIndex;
+ m_currentNode = branchNode;
}
template<typename JumpType>
@@ -806,16 +557,16 @@ private:
GPRReg m_arg2;
};
-void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
+void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
{
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1GPR = arg1.gpr();
GPRReg arg2GPR = arg2.gpr();
JITCompiler::JumpList slowPath;
- if (isKnownNotInteger(node.child1().index()) || isKnownNotInteger(node.child2().index())) {
+ if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
GPRResult result(this);
GPRReg resultGPR = result.gpr();
@@ -826,7 +577,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean, UseChildrenCalledExplicitly);
} else {
GPRTemporary result(this, arg2);
GPRReg resultGPR = result.gpr();
@@ -834,29 +585,28 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler
arg1.use();
arg2.use();
- if (!isKnownInteger(node.child1().index()))
+ if (!isKnownInteger(node->child1().node()))
slowPath.append(m_jit.branch64(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
- if (!isKnownInteger(node.child2().index()))
+ if (!isKnownInteger(node->child2().node()))
slowPath.append(m_jit.branch64(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
m_jit.compare32(cond, arg1GPR, arg2GPR, resultGPR);
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- if (!isKnownInteger(node.child1().index()) || !isKnownInteger(node.child2().index())) {
+ if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
addSlowPathGenerator(adoptPtr(
new CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>(
slowPath, this, helperFunction, resultGPR, arg1GPR, arg2GPR)));
}
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean, UseChildrenCalledExplicitly);
}
}
-void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert)
+void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
// The branch instruction will branch to the taken block.
// If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
@@ -867,8 +617,8 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
notTaken = tmp;
}
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1GPR = arg1.gpr();
GPRReg arg2GPR = arg2.gpr();
@@ -878,7 +628,7 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
arg1.use();
arg2.use();
- if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
+ if (isKnownCell(node->child1().node()) && isKnownCell(node->child2().node())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
branch64(JITCompiler::Equal, arg1GPR, arg2GPR, invert ? notTaken : taken);
@@ -919,10 +669,10 @@ void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branch
jump(notTaken);
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
+void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node* node, bool invert)
{
- JSValueOperand arg1(this, node.child1());
- JSValueOperand arg2(this, node.child2());
+ JSValueOperand arg1(this, node->child1());
+ JSValueOperand arg2(this, node->child2());
GPRReg arg1GPR = arg1.gpr();
GPRReg arg2GPR = arg2.gpr();
@@ -932,7 +682,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
arg1.use();
arg2.use();
- if (isKnownCell(node.child1().index()) && isKnownCell(node.child2().index())) {
+ if (isKnownCell(node->child1().node()) && isKnownCell(node->child2().node())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
// FIXME: this should flush registers instead of silent spill/fill.
@@ -985,35 +735,35 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
done.link(&m_jit);
}
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean, UseChildrenCalledExplicitly);
}
-void SpeculativeJIT::emitCall(Node& node)
+void SpeculativeJIT::emitCall(Node* node)
{
- if (node.op() != Call)
- ASSERT(node.op() == Construct);
+ if (node->op() != Call)
+ RELEASE_ASSERT(node->op() == Construct);
// For constructors, the this argument is not passed but we have to make space
// for it.
- int dummyThisArgument = node.op() == Call ? 0 : 1;
+ int dummyThisArgument = node->op() == Call ? 0 : 1;
- CallLinkInfo::CallType callType = node.op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
+ CallLinkInfo::CallType callType = node->op() == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
- Edge calleeEdge = m_jit.graph().m_varArgChildren[node.firstChild()];
+ Edge calleeEdge = m_jit.graph().m_varArgChildren[node->firstChild()];
JSValueOperand callee(this, calleeEdge);
GPRReg calleeGPR = callee.gpr();
use(calleeEdge);
// The call instruction's first child is the function; the subsequent children are the
// arguments.
- int numPassedArgs = node.numChildren() - 1;
+ int numPassedArgs = node->numChildren() - 1;
m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs + dummyThisArgument), callFramePayloadSlot(JSStack::ArgumentCount));
m_jit.store64(GPRInfo::callFrameRegister, callFrameSlot(JSStack::CallerFrame));
m_jit.store64(calleeGPR, callFrameSlot(JSStack::Callee));
for (int i = 0; i < numPassedArgs; i++) {
- Edge argEdge = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i];
+ Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
JSValueOperand arg(this, argEdge);
GPRReg argGPR = arg.gpr();
use(argEdge);
@@ -1030,7 +780,7 @@ void SpeculativeJIT::emitCall(Node& node)
JITCompiler::JumpList slowPath;
CallBeginToken token;
- m_jit.beginCall(node.codeOrigin, token);
+ m_jit.beginCall(node->codeOrigin, token);
m_jit.addPtr(TrustedImm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
@@ -1039,7 +789,7 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultGPR);
m_jit.store64(resultGPR, MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain));
- CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
+ CodeOrigin codeOrigin = m_currentNode->codeOrigin;
JITCompiler::Call fastCall = m_jit.nearCall();
m_jit.notifyCall(fastCall, codeOrigin, token);
@@ -1056,36 +806,38 @@ void SpeculativeJIT::emitCall(Node& node)
m_jit.move(GPRInfo::returnValueGPR, resultGPR);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJS, UseChildrenCalledExplicitly);
- m_jit.addJSCall(fastCall, slowCall, targetToCheck, callType, calleeGPR, at(m_compileIndex).codeOrigin);
+ m_jit.addJSCall(fastCall, slowCall, targetToCheck, callType, calleeGPR, m_currentNode->codeOrigin);
}
template<bool strict>
-GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateIntInternal(Edge edge, DataFormat& returnFormat)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecInt@%d ", nodeIndex);
+ dataLogF("SpecInt@%d ", edge->index());
#endif
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
+ value.filter(SpecInt32);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
- if ((node.hasConstant() && !isInt32Constant(nodeIndex)) || info.spillFormat() == DataFormatDouble) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ if ((edge->hasConstant() && !isInt32Constant(edge.node())) || info.spillFormat() == DataFormatDouble) {
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
returnFormat = DataFormatInteger;
return allocate();
}
GPRReg gpr = allocate();
- if (node.hasConstant()) {
+ if (edge->hasConstant()) {
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- ASSERT(isInt32Constant(nodeIndex));
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ ASSERT(isInt32Constant(edge.node()));
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
info.fillInteger(*m_stream, gpr);
returnFormat = DataFormatInteger;
return gpr;
@@ -1093,7 +845,7 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
DataFormat spillFormat = info.spillFormat();
- ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
+ RELEASE_ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
@@ -1125,8 +877,8 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
// Check the value is an integer.
GPRReg gpr = info.gpr();
m_gprs.lock(gpr);
- if (!isInt32Speculation(type))
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister), direction);
+ if (type & ~SpecInt32)
+ speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister));
info.fillJSValue(*m_stream, gpr, DataFormatJSInteger);
// If !strict we're done, return.
if (!strict) {
@@ -1171,10 +923,10 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
case DataFormatDouble:
case DataFormatJSDouble: {
- if (node.hasConstant() && isInt32Constant(nodeIndex)) {
+ if (edge->hasConstant() && isInt32Constant(edge.node())) {
GPRReg gpr = allocate();
- ASSERT(isInt32Constant(nodeIndex));
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ ASSERT(isInt32Constant(edge.node()));
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(edge.node())), gpr);
returnFormat = DataFormatInteger;
return gpr;
}
@@ -1183,50 +935,52 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
case DataFormatBoolean:
case DataFormatJSCell:
case DataFormatJSBoolean: {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
returnFormat = DataFormatInteger;
return allocate();
}
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateInt(Edge edge, DataFormat& returnFormat)
{
- return fillSpeculateIntInternal<false>(nodeIndex, returnFormat, direction);
+ return fillSpeculateIntInternal<false>(edge, returnFormat);
}
-GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
+GPRReg SpeculativeJIT::fillSpeculateIntStrict(Edge edge)
{
DataFormat mustBeDataFormatInteger;
- GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger, BackwardSpeculation);
- ASSERT(mustBeDataFormatInteger == DataFormatInteger);
+ GPRReg result = fillSpeculateIntInternal<true>(edge, mustBeDataFormatInteger);
+ RELEASE_ASSERT(mustBeDataFormatInteger == DataFormatInteger);
return result;
}
-FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirection direction)
+FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecDouble@%d ", nodeIndex);
+ dataLogF("SpecDouble@%d ", edge->index());
#endif
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ ASSERT(edge.useKind() != KnownNumberUse || !(value.m_type & ~SpecNumber));
+ value.filter(SpecNumber);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
if (info.registerFormat() == DataFormatNone) {
- if (node.hasConstant()) {
+ if (edge->hasConstant()) {
GPRReg gpr = allocate();
- if (isInt32Constant(nodeIndex)) {
+ if (isInt32Constant(edge.node())) {
FPRReg fpr = fprAllocate();
- m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(static_cast<double>(valueOfInt32Constant(nodeIndex)))), gpr);
+ m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(static_cast<double>(valueOfInt32Constant(edge.node())))), gpr);
m_jit.move64ToDouble(gpr, fpr);
unlock(gpr);
@@ -1234,9 +988,9 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
info.fillDouble(*m_stream, fpr);
return fpr;
}
- if (isNumberConstant(nodeIndex)) {
+ if (isNumberConstant(edge.node())) {
FPRReg fpr = fprAllocate();
- m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(nodeIndex))), gpr);
+ m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(edge.node()))), gpr);
m_jit.move64ToDouble(gpr, fpr);
unlock(gpr);
@@ -1244,7 +998,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
info.fillDouble(*m_stream, fpr);
return fpr;
}
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return fprAllocate();
}
@@ -1271,7 +1025,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
default:
GPRReg gpr = allocate();
- ASSERT(spillFormat & DataFormatJS);
+ RELEASE_ASSERT(spillFormat & DataFormatJS);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
info.fillJSValue(*m_stream, gpr, spillFormat);
@@ -1284,10 +1038,10 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
case DataFormatNone: // Should have filled, above.
case DataFormatBoolean: // This type never occurs.
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case DataFormatCell:
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return fprAllocate();
case DataFormatJSCell:
@@ -1300,8 +1054,8 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
- if (!isNumberSpeculation(type))
- speculationCheck(BadType, JSValueRegs(jsValueGpr), nodeIndex, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister), direction);
+ if (type & ~SpecNumber)
+ speculationCheck(BadType, JSValueRegs(jsValueGpr), edge, m_jit.branchTest64(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));
// First, if we get here we have a double encoded as a JSValue
m_jit.move(jsValueGpr, tempGpr);
@@ -1359,48 +1113,50 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex, SpeculationDirec
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidFPRReg;
}
}
-GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecCell@%d ", nodeIndex);
+ dataLogF("SpecCell@%d ", edge->index());
#endif
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
+ value.filter(SpecCell);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return allocate();
}
GPRReg gpr = allocate();
- if (node.hasConstant()) {
- JSValue jsValue = valueOfJSConstant(nodeIndex);
+ if (edge->hasConstant()) {
+ JSValue jsValue = valueOfJSConstant(edge.node());
if (jsValue.isCell()) {
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
return gpr;
}
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return gpr;
}
- ASSERT(info.spillFormat() & DataFormatJS);
+ RELEASE_ASSERT(info.spillFormat() & DataFormatJS);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
info.fillJSValue(*m_stream, gpr, DataFormatJS);
- if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction);
+ if (type & ~SpecCell)
+ speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
return gpr;
}
@@ -1415,8 +1171,8 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirecti
case DataFormatJS: {
GPRReg gpr = info.gpr();
m_gprs.lock(gpr);
- if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), direction);
+ if (type & ~SpecCell)
+ speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
return gpr;
}
@@ -1427,57 +1183,58 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, SpeculationDirecti
case DataFormatDouble:
case DataFormatJSBoolean:
case DataFormatBoolean: {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return allocate();
}
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
-GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDirection direction)
+GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("SpecBool@%d ", nodeIndex);
+ dataLogF("SpecBool@%d ", edge->index());
#endif
- SpeculatedType type = m_state.forNode(nodeIndex).m_type;
- Node& node = at(nodeIndex);
- VirtualRegister virtualRegister = node.virtualRegister();
+ AbstractValue& value = m_state.forNode(edge);
+ SpeculatedType type = value.m_type;
+ value.filter(SpecBoolean);
+ VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
switch (info.registerFormat()) {
case DataFormatNone: {
if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return allocate();
}
GPRReg gpr = allocate();
- if (node.hasConstant()) {
- JSValue jsValue = valueOfJSConstant(nodeIndex);
+ if (edge->hasConstant()) {
+ JSValue jsValue = valueOfJSConstant(edge.node());
if (jsValue.isBoolean()) {
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
return gpr;
}
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return gpr;
}
- ASSERT(info.spillFormat() & DataFormatJS);
+ RELEASE_ASSERT(info.spillFormat() & DataFormatJS);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
info.fillJSValue(*m_stream, gpr, DataFormatJS);
- if (!isBooleanSpeculation(type)) {
+ if (type & ~SpecBoolean) {
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction);
+ speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
}
info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
@@ -1494,9 +1251,9 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDire
case DataFormatJS: {
GPRReg gpr = info.gpr();
m_gprs.lock(gpr);
- if (!isBooleanSpeculation(type)) {
+ if (type & ~SpecBoolean) {
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg), direction);
+ speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
}
info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
@@ -1509,15 +1266,15 @@ GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex, SpeculationDire
case DataFormatDouble:
case DataFormatJSCell:
case DataFormatCell: {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode, direction);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
return allocate();
}
case DataFormatStorage:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return InvalidGPRReg;
}
}
@@ -1542,51 +1299,51 @@ JITCompiler::Jump SpeculativeJIT::convertToDouble(GPRReg value, FPRReg result, G
return notNumber;
}
-void SpeculativeJIT::compileObjectEquality(Node& node)
+void SpeculativeJIT::compileObjectEquality(Node* node)
{
- SpeculateCellOperand op1(this, node.child1());
- SpeculateCellOperand op2(this, node.child2());
+ SpeculateCellOperand op1(this, node->child1());
+ SpeculateCellOperand op2(this, node->child2());
GPRTemporary result(this, op1);
GPRReg op1GPR = op1.gpr();
GPRReg op2GPR = op2.gpr();
GPRReg resultGPR = result.gpr();
- if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op1GPR), node.child1().index(),
- m_jit.branchPtr(
+ if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op2GPR), node.child2().index(),
- m_jit.branchPtr(
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
GPRTemporary structure(this);
GPRReg structureGPR = structure.gpr();
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op1GPR), node.child1().index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op1GPR), node.child1().index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op2GPR), node.child2().index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op2GPR), node.child2().index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1600,38 +1357,46 @@ void SpeculativeJIT::compileObjectEquality(Node& node)
m_jit.move(TrustedImm32(ValueFalse), resultGPR);
done.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
}
void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
{
- Node& leftNode = m_jit.graph()[leftChild.index()];
SpeculateCellOperand op1(this, leftChild);
- JSValueOperand op2(this, rightChild);
+ JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
GPRTemporary result(this);
GPRReg op1GPR = op1.gpr();
GPRReg op2GPR = op2.gpr();
GPRReg resultGPR = result.gpr();
-
- if (m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ GPRTemporary structure;
+ GPRReg structureGPR = InvalidGPRReg;
+
+ bool masqueradesAsUndefinedWatchpointValid = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
+
+ if (!masqueradesAsUndefinedWatchpointValid) {
+ // The masquerades as undefined case will use the structure register, so allocate it here.
+ // Do this at the top of the function to avoid branching around a register allocation.
+ GPRTemporary realStructure(this);
+ structure.adopt(realStructure);
+ structureGPR = structure.gpr();
+ }
+
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op1GPR), leftChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1644,24 +1409,21 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
m_jit.branchTest64(MacroAssembler::NonZero, op2GPR, GPRInfo::tagMaskRegister);
// We know that within this branch, rightChild must be a cell.
- if (m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(leftNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op2GPR), rightChild.index(),
- m_jit.branchPtr(
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op2GPR), rightChild.index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op2GPR), rightChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1678,12 +1440,12 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
- if (!isOtherOrEmptySpeculation(m_state.forNode(rightChild).m_type & ~SpecCell)) {
+ if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
m_jit.move(op2GPR, resultGPR);
m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
- speculationCheck(
- BadType, JSValueRegs(op2GPR), rightChild.index(),
+ typeCheck(
+ JSValueRegs(op2GPR), rightChild, SpecCell | SpecOther,
m_jit.branch64(
MacroAssembler::NotEqual, resultGPR,
MacroAssembler::TrustedImm64(ValueNull)));
@@ -1696,71 +1458,76 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
m_jit.move(TrustedImm32(ValueTrue), resultGPR);
done.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
}
-void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, NodeIndex branchNodeIndex)
+void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
{
- Node& branchNode = at(branchNodeIndex);
- BlockIndex taken = branchNode.takenBlockIndex();
- BlockIndex notTaken = branchNode.notTakenBlockIndex();
+ BlockIndex taken = branchNode->takenBlockIndex();
+ BlockIndex notTaken = branchNode->notTakenBlockIndex();
SpeculateCellOperand op1(this, leftChild);
- JSValueOperand op2(this, rightChild);
+ JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
GPRTemporary result(this);
GPRReg op1GPR = op1.gpr();
GPRReg op2GPR = op2.gpr();
GPRReg resultGPR = result.gpr();
+ GPRTemporary structure;
+ GPRReg structureGPR = InvalidGPRReg;
- if (m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ bool masqueradesAsUndefinedWatchpointValid = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
+
+ if (!masqueradesAsUndefinedWatchpointValid) {
+ // The masquerades as undefined case will use the structure register, so allocate it here.
+ // Do this at the top of the function to avoid branching around a register allocation.
+ GPRTemporary realStructure(this);
+ structure.adopt(realStructure);
+ structureGPR = structure.gpr();
+ }
+
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op1GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op1GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op1GPR), leftChild.index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op1GPR), leftChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
}
-
+
// It seems that most of the time when programs do a == b where b may be either null/undefined
// or an object, b is usually an object. Balance the branches to make that case fast.
MacroAssembler::Jump rightNotCell =
m_jit.branchTest64(MacroAssembler::NonZero, op2GPR, GPRInfo::tagMaskRegister);
// We know that within this branch, rightChild must be a cell.
- if (m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(branchNode.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
- speculationCheck(BadType, JSValueRegs(op2GPR), rightChild.index(),
- m_jit.branchPtr(
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(op2GPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(op2GPR, JSCell::structureOffset()), structureGPR);
- speculationCheck(BadType, JSValueRegs(op2GPR), rightChild.index(),
- m_jit.branchPtr(
+ DFG_TYPE_CHECK(
+ JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr(
MacroAssembler::Equal,
structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- speculationCheck(BadType, JSValueRegs(op2GPR), rightChild.index(),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
+ speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
m_jit.branchTest8(
MacroAssembler::NonZero,
MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()),
@@ -1774,7 +1541,7 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
- if (isOtherOrEmptySpeculation(m_state.forNode(rightChild).m_type & ~SpecCell))
+ if (!needsTypeCheck(rightChild, SpecCell | SpecOther))
rightNotCell.link(&m_jit);
else {
jump(notTaken, ForceJump);
@@ -1783,9 +1550,8 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
m_jit.move(op2GPR, resultGPR);
m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
- speculationCheck(
- BadType, JSValueRegs(op2GPR), rightChild.index(),
- m_jit.branch64(
+ typeCheck(
+ JSValueRegs(op2GPR), rightChild, SpecCell | SpecOther, m_jit.branch64(
MacroAssembler::NotEqual, resultGPR,
MacroAssembler::TrustedImm64(ValueNull)));
}
@@ -1793,23 +1559,23 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
jump(notTaken);
}
-void SpeculativeJIT::compileIntegerCompare(Node& node, MacroAssembler::RelationalCondition condition)
+void SpeculativeJIT::compileIntegerCompare(Node* node, MacroAssembler::RelationalCondition condition)
{
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op1, op2);
m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
// If we add a DataFormatBool, we should use it here.
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
}
-void SpeculativeJIT::compileDoubleCompare(Node& node, MacroAssembler::DoubleCondition condition)
+void SpeculativeJIT::compileDoubleCompare(Node* node, MacroAssembler::DoubleCondition condition)
{
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
GPRTemporary result(this);
m_jit.move(TrustedImm32(ValueTrue), result.gpr());
@@ -1817,13 +1583,13 @@ void SpeculativeJIT::compileDoubleCompare(Node& node, MacroAssembler::DoubleCond
m_jit.xor64(TrustedImm32(true), result.gpr());
trueCase.link(&m_jit);
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
}
-void SpeculativeJIT::compileValueAdd(Node& node)
+void SpeculativeJIT::compileValueAdd(Node* node)
{
- JSValueOperand op1(this, node.child1());
- JSValueOperand op2(this, node.child2());
+ JSValueOperand op1(this, node->child1());
+ JSValueOperand op2(this, node->child2());
GPRReg op1GPR = op1.gpr();
GPRReg op2GPR = op2.gpr();
@@ -1831,45 +1597,49 @@ void SpeculativeJIT::compileValueAdd(Node& node)
flushRegisters();
GPRResult result(this);
- if (isKnownNotNumber(node.child1().index()) || isKnownNotNumber(node.child2().index()))
+ if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
else
callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
}
-void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool needSpeculationCheck)
+void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
{
- JSValueOperand value(this, nodeUse);
+ JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
GPRTemporary result(this);
GPRReg valueGPR = value.gpr();
GPRReg resultGPR = result.gpr();
-
+ GPRTemporary structure;
+ GPRReg structureGPR = InvalidGPRReg;
+
+ bool masqueradesAsUndefinedWatchpointValid = m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid();
+
+ if (!masqueradesAsUndefinedWatchpointValid) {
+ // The masquerades as undefined case will use the structure register, so allocate it here.
+ // Do this at the top of the function to avoid branching around a register allocation.
+ GPRTemporary realStructure(this);
+ structure.adopt(realStructure);
+ structureGPR = structure.gpr();
+ }
+
MacroAssembler::Jump notCell = m_jit.branchTest64(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
- if (m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
-
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
- m_jit.branchPtr(
- MacroAssembler::Equal,
- MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ if (masqueradesAsUndefinedWatchpointValid) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
- GPRTemporary structure(this);
- GPRReg structureGPR = structure.gpr();
-
m_jit.loadPtr(MacroAssembler::Address(valueGPR, JSCell::structureOffset()), structureGPR);
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
- m_jit.branchPtr(
- MacroAssembler::Equal,
- structureGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ structureGPR,
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
MacroAssembler::Jump isNotMasqueradesAsUndefined =
m_jit.branchTest8(
@@ -1881,7 +1651,7 @@ void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool ne
m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin))));
+ MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->codeOrigin))));
isNotMasqueradesAsUndefined.link(&m_jit);
}
@@ -1890,11 +1660,11 @@ void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool ne
notCell.link(&m_jit);
- if (needSpeculationCheck) {
+ if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
m_jit.move(valueGPR, resultGPR);
m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
- m_jit.branch64(
+ typeCheck(
+ JSValueRegs(valueGPR), nodeUse, SpecCell | SpecOther, m_jit.branch64(
MacroAssembler::NotEqual,
resultGPR,
MacroAssembler::TrustedImm64(ValueNull)));
@@ -1903,117 +1673,124 @@ void SpeculativeJIT::compileNonStringCellOrOtherLogicalNot(Edge nodeUse, bool ne
done.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
}
-void SpeculativeJIT::compileLogicalNot(Node& node)
+void SpeculativeJIT::compileLogicalNot(Node* node)
{
- if (at(node.child1()).shouldSpeculateNonStringCellOrOther()) {
- compileNonStringCellOrOtherLogicalNot(node.child1(),
- !isNonStringCellOrOtherSpeculation(m_state.forNode(node.child1()).m_type));
+ switch (node->child1().useKind()) {
+ case ObjectOrOtherUse: {
+ compileObjectOrOtherLogicalNot(node->child1());
return;
}
- if (at(node.child1()).shouldSpeculateInteger()) {
- SpeculateIntegerOperand value(this, node.child1());
+
+ case Int32Use: {
+ SpeculateIntegerOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), result.gpr());
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
return;
}
- if (at(node.child1()).shouldSpeculateNumber()) {
- SpeculateDoubleOperand value(this, node.child1());
+
+ case NumberUse: {
+ SpeculateDoubleOperand value(this, node->child1());
FPRTemporary scratch(this);
GPRTemporary result(this);
m_jit.move(TrustedImm32(ValueFalse), result.gpr());
MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
m_jit.xor32(TrustedImm32(true), result.gpr());
nonZero.link(&m_jit);
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
return;
}
- SpeculatedType prediction = m_jit.getSpeculation(node.child1());
- if (isBooleanSpeculation(prediction)) {
- if (isBooleanSpeculation(m_state.forNode(node.child1()).m_type)) {
- SpeculateBooleanOperand value(this, node.child1());
+ case BooleanUse: {
+ if (!needsTypeCheck(node->child1(), SpecBoolean)) {
+ SpeculateBooleanOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.move(value.gpr(), result.gpr());
m_jit.xor64(TrustedImm32(true), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
return;
}
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
m_jit.move(value.gpr(), result.gpr());
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
- speculationCheck(BadType, JSValueRegs(value.gpr()), node.child1(), m_jit.branchTest64(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
+ typeCheck(
+ JSValueRegs(value.gpr()), node->child1(), SpecBoolean, m_jit.branchTest64(
+ JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
// If we add a DataFormatBool, we should use it here.
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
return;
}
+
+ case UntypedUse: {
+ JSValueOperand arg1(this, node->child1());
+ GPRTemporary result(this);
- JSValueOperand arg1(this, node.child1());
- GPRTemporary result(this);
-
- GPRReg arg1GPR = arg1.gpr();
- GPRReg resultGPR = result.gpr();
+ GPRReg arg1GPR = arg1.gpr();
+ GPRReg resultGPR = result.gpr();
- arg1.use();
+ arg1.use();
- m_jit.move(arg1GPR, resultGPR);
- m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
- JITCompiler::Jump slowCase = m_jit.branchTest64(JITCompiler::NonZero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
+ m_jit.move(arg1GPR, resultGPR);
+ m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
+ JITCompiler::Jump slowCase = m_jit.branchTest64(JITCompiler::NonZero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
- addSlowPathGenerator(
- slowPathCall(slowCase, this, dfgConvertJSValueToBoolean, resultGPR, arg1GPR));
+ addSlowPathGenerator(
+ slowPathCall(slowCase, this, dfgConvertJSValueToBoolean, resultGPR, arg1GPR));
- m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
- jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+ m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
+ jsValueResult(resultGPR, node, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
}
-void SpeculativeJIT::emitNonStringCellOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck)
+void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, BlockIndex notTaken)
{
- JSValueOperand value(this, nodeUse);
+ JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
GPRTemporary scratch(this);
GPRReg valueGPR = value.gpr();
GPRReg scratchGPR = scratch.gpr();
MacroAssembler::Jump notCell = m_jit.branchTest64(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
- if (m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
-
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse.index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ if (m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(m_currentNode->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ MacroAssembler::Address(valueGPR, JSCell::structureOffset()),
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
} else {
m_jit.loadPtr(MacroAssembler::Address(valueGPR, JSCell::structureOffset()), scratchGPR);
- if (needSpeculationCheck) {
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse.index(),
- m_jit.branchPtr(
- MacroAssembler::Equal,
- scratchGPR,
- MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr(
+ MacroAssembler::Equal,
+ scratchGPR,
+ MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(JITCompiler::Zero, MacroAssembler::Address(scratchGPR, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse.index(),
+ speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
m_jit.branchPtr(
MacroAssembler::Equal,
MacroAssembler::Address(scratchGPR, Structure::globalObjectOffset()),
- MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_jit.graph()[nodeUse.index()].codeOrigin))));
+ MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->codeOrigin))));
isNotMasqueradesAsUndefined.link(&m_jit);
}
@@ -2021,26 +1798,32 @@ void SpeculativeJIT::emitNonStringCellOrOtherBranch(Edge nodeUse, BlockIndex tak
notCell.link(&m_jit);
- if (needSpeculationCheck) {
+ if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
m_jit.move(valueGPR, scratchGPR);
m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
- speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse.index(), m_jit.branch64(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
+ typeCheck(
+ JSValueRegs(valueGPR), nodeUse, SpecCell | SpecOther, m_jit.branch64(
+ MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
}
jump(notTaken);
- noResult(m_compileIndex);
+ noResult(m_currentNode);
}
-void SpeculativeJIT::emitBranch(Node& node)
+void SpeculativeJIT::emitBranch(Node* node)
{
- BlockIndex taken = node.takenBlockIndex();
- BlockIndex notTaken = node.notTakenBlockIndex();
+ BlockIndex taken = node->takenBlockIndex();
+ BlockIndex notTaken = node->notTakenBlockIndex();
- if (at(node.child1()).shouldSpeculateNonStringCellOrOther()) {
- emitNonStringCellOrOtherBranch(node.child1(), taken, notTaken,
- !isNonStringCellOrOtherSpeculation(m_state.forNode(node.child1()).m_type));
- } else if (at(node.child1()).shouldSpeculateNumber()) {
- if (at(node.child1()).shouldSpeculateInteger()) {
+ switch (node->child1().useKind()) {
+ case ObjectOrOtherUse: {
+ emitObjectOrOtherBranch(node->child1(), taken, notTaken);
+ return;
+ }
+
+ case Int32Use:
+ case NumberUse: {
+ if (node->child1().useKind() == Int32Use) {
bool invert = false;
if (taken == nextBlock()) {
@@ -2050,25 +1833,27 @@ void SpeculativeJIT::emitBranch(Node& node)
notTaken = tmp;
}
- SpeculateIntegerOperand value(this, node.child1());
+ SpeculateIntegerOperand value(this, node->child1());
branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr(), taken);
} else {
- SpeculateDoubleOperand value(this, node.child1());
+ SpeculateDoubleOperand value(this, node->child1());
FPRTemporary scratch(this);
branchDoubleNonZero(value.fpr(), scratch.fpr(), taken);
}
jump(notTaken);
- noResult(m_compileIndex);
- } else {
- JSValueOperand value(this, node.child1());
+ noResult(node);
+ return;
+ }
+
+ case UntypedUse:
+ case BooleanUse: {
+ JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
GPRReg valueGPR = value.gpr();
- bool predictBoolean = isBooleanSpeculation(m_jit.getSpeculation(node.child1()));
-
- if (predictBoolean) {
- if (isBooleanSpeculation(m_state.forNode(node.child1()).m_type)) {
+ if (node->child1().useKind() == BooleanUse) {
+ if (!needsTypeCheck(node->child1(), SpecBoolean)) {
MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
if (taken == nextBlock()) {
@@ -2084,17 +1869,19 @@ void SpeculativeJIT::emitBranch(Node& node)
branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
- speculationCheck(BadType, JSValueRegs(valueGPR), node.child1(), m_jit.jump());
+ typeCheck(JSValueRegs(valueGPR), node->child1(), SpecBoolean, m_jit.jump());
}
value.use();
} else {
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
-
- branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
- branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
+
+ if (node->child1()->prediction() & SpecInt32) {
+ branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
+ branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
+ }
- if (!predictBoolean) {
+ if (node->child1()->prediction() & SpecBoolean) {
branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
}
@@ -2109,106 +1896,125 @@ void SpeculativeJIT::emitBranch(Node& node)
jump(notTaken);
}
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
+ return;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
}
}
-void SpeculativeJIT::compile(Node& node)
+void SpeculativeJIT::compile(Node* node)
{
- NodeType op = node.op();
+ NodeType op = node->op();
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.clearRegisterAllocationOffsets();
+#endif
+
switch (op) {
case JSConstant:
- initConstantInfo(m_compileIndex);
+ initConstantInfo(node);
break;
case PhantomArguments:
- initConstantInfo(m_compileIndex);
+ initConstantInfo(node);
break;
case WeakJSConstant:
- m_jit.addWeakReference(node.weakConstant());
- initConstantInfo(m_compileIndex);
+ m_jit.addWeakReference(node->weakConstant());
+ initConstantInfo(node);
break;
case Identity: {
- // This could be done a lot better. We take the cheap way out because Identity
- // is only going to stick around after CSE if we had prediction weirdness.
- JSValueOperand operand(this, node.child1());
- GPRTemporary result(this, operand);
- m_jit.move(operand.gpr(), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex);
+ // CSE should always eliminate this.
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
case GetLocal: {
- SpeculatedType prediction = node.variableAccessData()->prediction();
- AbstractValue& value = block()->valuesAtHead.operand(node.local());
+ SpeculatedType prediction = node->variableAccessData()->prediction();
+ AbstractValue& value = m_state.variables().operand(node->local());
// If we have no prediction for this local, then don't attempt to compile.
if (prediction == SpecNone) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
- if (!node.variableAccessData()->isCaptured()) {
- // If the CFA is tracking this variable and it found that the variable
- // cannot have been assigned, then don't attempt to proceed.
- if (value.isClear()) {
- terminateSpeculativeExecution(InadequateCoverage, 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 the CFA is tracking this variable and it found that the variable
+ // cannot have been assigned, then don't attempt to proceed.
+ if (value.isClear()) {
+ // FIXME: We should trap instead.
+ // https://bugs.webkit.org/show_bug.cgi?id=110383
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
+ 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(node, node->refCount(), result.fpr());
+ break;
+ }
+
+ if (isInt32Speculation(value.m_type)) {
+ GPRTemporary result(this);
+ m_jit.load32(JITCompiler::payloadFor(node->local()), result.gpr());
- if (isInt32Speculation(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;
- }
+ // 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(node, node->refCount(), result.gpr());
+ break;
}
GPRTemporary result(this);
- m_jit.load64(JITCompiler::addressFor(node.local()), result.gpr());
+ m_jit.load64(JITCompiler::addressFor(node->local()), result.gpr());
// Like jsValueResult, but don't useChildren - our children are phi nodes,
// and don't represent values within this dataflow with virtual registers.
- VirtualRegister virtualRegister = node.virtualRegister();
+ VirtualRegister virtualRegister = node->virtualRegister();
m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
DataFormat format;
- if (node.variableAccessData()->isCaptured())
- format = DataFormatJS;
- else if (isCellSpeculation(value.m_type))
+ if (isCellSpeculation(value.m_type))
format = DataFormatJSCell;
else if (isBooleanSpeculation(value.m_type))
format = DataFormatJSBoolean;
else
format = DataFormatJS;
- m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
+ m_generationInfo[virtualRegister].initJSValue(node, node->refCount(), result.gpr(), format);
break;
}
case GetLocalUnlinked: {
GPRTemporary result(this);
- m_jit.load64(JITCompiler::addressFor(node.unlinkedLocal()), result.gpr());
+ m_jit.load64(JITCompiler::addressFor(node->unlinkedLocal()), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
+ break;
+ }
+
+ case MovHintAndCheck: {
+ compileMovHintAndCheck(node);
+ break;
+ }
+
+ case InlineStart: {
+ compileInlineStart(node);
+ break;
+ }
+
+ case MovHint:
+ case ZombieHint: {
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -2219,55 +2025,55 @@ void SpeculativeJIT::compile(Node& node)
// stack.
compileMovHint(node);
- if (!node.variableAccessData()->isCaptured() && !m_jit.graph().isCreatedThisArgument(node.local())) {
- if (node.variableAccessData()->shouldUseDoubleFormat()) {
- SpeculateDoubleOperand value(this, node.child1(), ForwardSpeculation);
- m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
+ if (node->variableAccessData()->shouldUnboxIfPossible()) {
+ if (node->variableAccessData()->shouldUseDoubleFormat()) {
+ SpeculateDoubleOperand value(this, node->child1());
+ m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->local()));
+ noResult(node);
// Indicate that it's no longer necessary to retrieve the value of
// this bytecode variable from registers or other locations in the stack,
// but that it is stored as a double.
- recordSetLocal(node.local(), ValueSource(DoubleInJSStack));
+ recordSetLocal(node->local(), ValueSource(DoubleInJSStack));
break;
}
- SpeculatedType predictedType = node.variableAccessData()->argumentAwarePrediction();
+ SpeculatedType predictedType = node->variableAccessData()->argumentAwarePrediction();
if (isInt32Speculation(predictedType)) {
- SpeculateIntegerOperand value(this, node.child1(), ForwardSpeculation);
- m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
- noResult(m_compileIndex);
- recordSetLocal(node.local(), ValueSource(Int32InJSStack));
+ SpeculateIntegerOperand value(this, node->child1());
+ m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(Int32InJSStack));
break;
}
if (isCellSpeculation(predictedType)) {
- SpeculateCellOperand cell(this, node.child1(), ForwardSpeculation);
+ SpeculateCellOperand cell(this, node->child1());
GPRReg cellGPR = cell.gpr();
- m_jit.store64(cellGPR, JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
- recordSetLocal(node.local(), ValueSource(CellInJSStack));
+ m_jit.store64(cellGPR, JITCompiler::addressFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(CellInJSStack));
break;
}
if (isBooleanSpeculation(predictedType)) {
- SpeculateBooleanOperand boolean(this, node.child1(), ForwardSpeculation);
- m_jit.store64(boolean.gpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
- recordSetLocal(node.local(), ValueSource(BooleanInJSStack));
+ SpeculateBooleanOperand boolean(this, node->child1());
+ m_jit.store64(boolean.gpr(), JITCompiler::addressFor(node->local()));
+ noResult(node);
+ recordSetLocal(node->local(), ValueSource(BooleanInJSStack));
break;
}
}
- JSValueOperand value(this, node.child1());
- m_jit.store64(value.gpr(), JITCompiler::addressFor(node.local()));
- noResult(m_compileIndex);
+ JSValueOperand value(this, node->child1());
+ m_jit.store64(value.gpr(), JITCompiler::addressFor(node->local()));
+ noResult(node);
- recordSetLocal(node.local(), ValueSource(ValueInJSStack));
+ recordSetLocal(node->local(), ValueSource(ValueInJSStack));
// If we're storing an arguments object that has been optimized away,
// our variable event stream for OSR exit now reflects the optimized
// value (JSValue()). On the slow path, we want an arguments object
// instead. We add an additional move hint to show OSR exit that it
// needs to reconstruct the arguments object.
- if (at(node.child1()).op() == PhantomArguments)
+ if (node->child1()->op() == PhantomArguments)
compileMovHint(node);
break;
@@ -2283,54 +2089,54 @@ void SpeculativeJIT::compile(Node& node)
case BitAnd:
case BitOr:
case BitXor:
- if (isInt32Constant(node.child1().index())) {
- SpeculateIntegerOperand op2(this, node.child2());
+ if (isInt32Constant(node->child1().node())) {
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op2);
- bitOp(op, valueOfInt32Constant(node.child1().index()), op2.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node->child1().node()), op2.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
- } else if (isInt32Constant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
+ integerResult(result.gpr(), node);
+ } else if (isInt32Constant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this, op1);
- bitOp(op, valueOfInt32Constant(node.child2().index()), op1.gpr(), result.gpr());
+ bitOp(op, valueOfInt32Constant(node->child2().node()), op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
} else {
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op1, op2);
GPRReg reg1 = op1.gpr();
GPRReg reg2 = op2.gpr();
bitOp(op, reg1, reg2, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
}
break;
case BitRShift:
case BitLShift:
case BitURShift:
- if (isInt32Constant(node.child2().index())) {
- SpeculateIntegerOperand op1(this, node.child1());
+ if (isInt32Constant(node->child2().node())) {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this, op1);
- shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2().index()) & 0x1f, result.gpr());
+ shiftOp(op, op1.gpr(), valueOfInt32Constant(node->child2().node()) & 0x1f, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
} else {
// Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
- SpeculateIntegerOperand op1(this, node.child1());
- SpeculateIntegerOperand op2(this, node.child2());
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
GPRTemporary result(this, op1);
GPRReg reg1 = op1.gpr();
GPRReg reg2 = op2.gpr();
shiftOp(op, reg1, reg2, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
}
break;
@@ -2349,28 +2155,20 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case Int32ToDouble: {
+ case Int32ToDouble:
+ case ForwardInt32ToDouble: {
compileInt32ToDouble(node);
break;
}
- case CheckNumber: {
- if (!isNumberSpeculation(m_state.forNode(node.child1()).m_type)) {
- JSValueOperand op1(this, node.child1());
- JITCompiler::Jump isInteger = m_jit.branch64(MacroAssembler::AboveOrEqual, op1.gpr(), GPRInfo::tagTypeNumberRegister);
- speculationCheck(
- BadType, JSValueRegs(op1.gpr()), node.child1().index(),
- m_jit.branchTest64(MacroAssembler::Zero, op1.gpr(), GPRInfo::tagTypeNumberRegister));
- isInteger.link(&m_jit);
- }
- noResult(m_compileIndex);
- break;
- }
-
case ValueAdd:
case ArithAdd:
compileAdd(node);
break;
+
+ case MakeRope:
+ compileMakeRope(node);
+ break;
case ArithSub:
compileArithSub(node);
@@ -2384,22 +2182,34 @@ void SpeculativeJIT::compile(Node& node)
compileArithMul(node);
break;
+ case ArithIMul:
+ compileArithIMul(node);
+ break;
+
case ArithDiv: {
- if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2()))
- && node.canSpeculateInteger()) {
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
compileIntegerArithDivForX86(node);
break;
}
-
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1);
-
- FPRReg reg1 = op1.fpr();
- FPRReg reg2 = op2.fpr();
- m_jit.divDouble(reg1, reg2, result.fpr());
-
- doubleResult(result.fpr(), m_compileIndex);
+
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
+ FPRTemporary result(this, op1);
+
+ FPRReg reg1 = op1.fpr();
+ FPRReg reg2 = op2.fpr();
+ m_jit.divDouble(reg1, reg2, result.fpr());
+
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
@@ -2409,9 +2219,9 @@ void SpeculativeJIT::compile(Node& node)
}
case ArithAbs: {
- if (at(node.child1()).shouldSpeculateIntegerForArithmetic()
- && node.canSpeculateInteger()) {
- SpeculateIntegerOperand op1(this, node.child1());
+ switch (node->child1().useKind()) {
+ case Int32Use: {
+ SpeculateIntegerOperand op1(this, node->child1());
GPRTemporary result(this);
GPRTemporary scratch(this);
@@ -2419,25 +2229,33 @@ void SpeculativeJIT::compile(Node& node)
m_jit.rshift32(result.gpr(), MacroAssembler::TrustedImm32(31), scratch.gpr());
m_jit.add32(scratch.gpr(), result.gpr());
m_jit.xor32(scratch.gpr(), result.gpr());
- speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
- integerResult(result.gpr(), m_compileIndex);
+ speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
+ integerResult(result.gpr(), node);
break;
}
- SpeculateDoubleOperand op1(this, node.child1());
- FPRTemporary result(this);
-
- m_jit.absDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRTemporary result(this);
+
+ m_jit.absDouble(op1.fpr(), result.fpr());
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
case ArithMin:
case ArithMax: {
- if (Node::shouldSpeculateIntegerForArithmetic(at(node.child1()), at(node.child2()))
- && node.canSpeculateInteger()) {
- SpeculateStrictInt32Operand op1(this, node.child1());
- SpeculateStrictInt32Operand op2(this, node.child2());
+ switch (node->binaryUseKind()) {
+ case Int32Use: {
+ SpeculateStrictInt32Operand op1(this, node->child1());
+ SpeculateStrictInt32Operand op2(this, node->child2());
GPRTemporary result(this, op1);
MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr());
@@ -2450,50 +2268,62 @@ void SpeculativeJIT::compile(Node& node)
} else
op1Less.link(&m_jit);
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), node);
break;
}
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1);
+ case NumberUse: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ SpeculateDoubleOperand op2(this, node->child2());
+ FPRTemporary result(this, op1);
+
+ FPRReg op1FPR = op1.fpr();
+ FPRReg op2FPR = op2.fpr();
+ FPRReg resultFPR = result.fpr();
- MacroAssembler::JumpList done;
+ MacroAssembler::JumpList done;
- MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
+ MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1FPR, op2FPR);
- // op2 is eather the lesser one or one of then is NaN
- MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
+ // op2 is eather the lesser one or one of then is NaN
+ MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1FPR, op2FPR);
- // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
- // op1 + op2 and putting it into result.
- m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
- done.append(m_jit.jump());
+ // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding
+ // op1 + op2 and putting it into result.
+ m_jit.addDouble(op1FPR, op2FPR, resultFPR);
+ done.append(m_jit.jump());
- op2Less.link(&m_jit);
- m_jit.moveDouble(op2.fpr(), result.fpr());
+ op2Less.link(&m_jit);
+ m_jit.moveDouble(op2FPR, resultFPR);
- if (op1.fpr() != result.fpr()) {
- done.append(m_jit.jump());
+ if (op1FPR != resultFPR) {
+ done.append(m_jit.jump());
- op1Less.link(&m_jit);
- m_jit.moveDouble(op1.fpr(), result.fpr());
- } else
- op1Less.link(&m_jit);
+ op1Less.link(&m_jit);
+ m_jit.moveDouble(op1FPR, resultFPR);
+ } else
+ op1Less.link(&m_jit);
- done.link(&m_jit);
+ done.link(&m_jit);
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(resultFPR, node);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
case ArithSqrt: {
- SpeculateDoubleOperand op1(this, node.child1());
+ SpeculateDoubleOperand op1(this, node->child1());
FPRTemporary result(this, op1);
m_jit.sqrtDouble(op1.fpr(), result.fpr());
- doubleResult(result.fpr(), m_compileIndex);
+ doubleResult(result.fpr(), node);
break;
}
@@ -2520,22 +2350,23 @@ void SpeculativeJIT::compile(Node& node)
if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
return;
break;
+
+ case CompareEqConstant:
+ ASSERT(isNullConstant(node->child2().node()));
+ if (nonSpeculativeCompareNull(node, node->child1()))
+ return;
+ break;
case CompareEq:
- if (isNullConstant(node.child1().index())) {
- if (nonSpeculativeCompareNull(node, node.child2()))
- return;
- break;
- }
- if (isNullConstant(node.child2().index())) {
- if (nonSpeculativeCompareNull(node, node.child1()))
- return;
- break;
- }
if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
return;
break;
+ case CompareStrictEqConstant:
+ if (compileStrictEqForConstant(node, node->child1(), valueOfJSConstant(node->child2().node())))
+ return;
+ break;
+
case CompareStrictEq:
if (compileStrictEq(node))
return;
@@ -2551,6 +2382,11 @@ void SpeculativeJIT::compile(Node& node)
compileGetByValOnString(node);
break;
}
+
+ case StringFromCharCode: {
+ compileFromCharCode(node);
+ break;
+ }
case CheckArray: {
checkArray(node);
@@ -2564,15 +2400,15 @@ void SpeculativeJIT::compile(Node& node)
}
case GetByVal: {
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::SelectUsingPredictions:
case Array::ForceExit:
- ASSERT_NOT_REACHED();
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ RELEASE_ASSERT_NOT_REACHED();
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
case Array::Generic: {
- JSValueOperand base(this, node.child1());
- JSValueOperand property(this, node.child2());
+ JSValueOperand base(this, node->child1());
+ JSValueOperand property(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg propertyGPR = property.gpr();
@@ -2580,14 +2416,14 @@ void SpeculativeJIT::compile(Node& node)
GPRResult result(this);
callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR);
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
break;
}
case Array::Int32:
case Array::Contiguous: {
- if (node.arrayMode().isInBounds()) {
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ if (node->arrayMode().isInBounds()) {
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
@@ -2595,18 +2431,18 @@ void SpeculativeJIT::compile(Node& node)
if (!m_compileOkay)
return;
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
GPRTemporary result(this);
m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.gpr());
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
- jsValueResult(result.gpr(), m_compileIndex, node.arrayMode().type() == Array::Int32 ? DataFormatJSInteger : DataFormatJS);
+ speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
+ jsValueResult(result.gpr(), node, node->arrayMode().type() == Array::Int32 ? DataFormatJSInteger : DataFormatJS);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2630,21 +2466,21 @@ void SpeculativeJIT::compile(Node& node)
slowCases, this, operationGetByValArrayInt,
result.gpr(), baseReg, propertyReg));
- jsValueResult(resultReg, m_compileIndex);
+ jsValueResult(resultReg, node);
break;
}
case Array::Double: {
- if (node.arrayMode().isInBounds()) {
- if (node.arrayMode().isSaneChain()) {
- JSGlobalObject* globalObject = m_jit.globalObjectFor(node.codeOrigin);
+ if (node->arrayMode().isInBounds()) {
+ if (node->arrayMode().isSaneChain()) {
+ JSGlobalObject* globalObject = m_jit.globalObjectFor(node->codeOrigin);
ASSERT(globalObject->arrayPrototypeChainIsSane());
globalObject->arrayPrototype()->structure()->addTransitionWatchpoint(speculationWatchpoint());
globalObject->objectPrototype()->structure()->addTransitionWatchpoint(speculationWatchpoint());
}
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
@@ -2652,19 +2488,19 @@ void SpeculativeJIT::compile(Node& node)
if (!m_compileOkay)
return;
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
FPRTemporary result(this);
m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr());
- if (!node.arrayMode().isSaneChain())
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr()));
- doubleResult(result.fpr(), m_compileIndex);
+ if (!node->arrayMode().isSaneChain())
+ speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr()));
+ doubleResult(result.fpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2691,15 +2527,15 @@ void SpeculativeJIT::compile(Node& node)
slowCases, this, operationGetByValArrayInt,
result.gpr(), baseReg, propertyReg));
- jsValueResult(resultReg, m_compileIndex);
+ jsValueResult(resultReg, node);
break;
}
case Array::ArrayStorage:
case Array::SlowPutArrayStorage: {
- if (node.arrayMode().isInBounds()) {
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ if (node->arrayMode().isInBounds()) {
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg propertyReg = property.gpr();
GPRReg storageReg = storage.gpr();
@@ -2707,19 +2543,19 @@ void SpeculativeJIT::compile(Node& node)
if (!m_compileOkay)
return;
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
GPRTemporary result(this);
m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
+ speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateStrictInt32Operand property(this, node.child2());
- StorageOperand storage(this, node.child3());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateStrictInt32Operand property(this, node->child2());
+ StorageOperand storage(this, node->child3());
GPRReg baseReg = base.gpr();
GPRReg propertyReg = property.gpr();
@@ -2743,7 +2579,7 @@ void SpeculativeJIT::compile(Node& node)
slowCases, this, operationGetByValArrayInt,
result.gpr(), baseReg, propertyReg));
- jsValueResult(resultReg, m_compileIndex);
+ jsValueResult(resultReg, node);
break;
}
case Array::String:
@@ -2753,34 +2589,34 @@ void SpeculativeJIT::compile(Node& node)
compileGetByValOnArguments(node);
break;
case Array::Int8Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), node, sizeof(int8_t), SignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->int8ArrayDescriptor(), node, sizeof(int8_t), SignedTypedArray);
break;
case Array::Int16Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), node, sizeof(int16_t), SignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->int16ArrayDescriptor(), node, sizeof(int16_t), SignedTypedArray);
break;
case Array::Int32Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), node, sizeof(int32_t), SignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->int32ArrayDescriptor(), node, sizeof(int32_t), SignedTypedArray);
break;
case Array::Uint8Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint8ArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
break;
case Array::Uint8ClampedArray:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint8ClampedArrayDescriptor(), node, sizeof(uint8_t), UnsignedTypedArray);
break;
case Array::Uint16Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), node, sizeof(uint16_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint16ArrayDescriptor(), node, sizeof(uint16_t), UnsignedTypedArray);
break;
case Array::Uint32Array:
- compileGetByValOnIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), node, sizeof(uint32_t), UnsignedTypedArray);
+ compileGetByValOnIntTypedArray(m_jit.vm()->uint32ArrayDescriptor(), node, sizeof(uint32_t), UnsignedTypedArray);
break;
case Array::Float32Array:
- compileGetByValOnFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), node, sizeof(float));
+ compileGetByValOnFloatTypedArray(m_jit.vm()->float32ArrayDescriptor(), node, sizeof(float));
break;
case Array::Float64Array:
- compileGetByValOnFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), node, sizeof(double));
+ compileGetByValOnFloatTypedArray(m_jit.vm()->float64ArrayDescriptor(), node, sizeof(double));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
break;
@@ -2793,18 +2629,18 @@ void SpeculativeJIT::compile(Node& node)
Edge child3 = m_jit.graph().varArgChild(node, 2);
Edge child4 = m_jit.graph().varArgChild(node, 3);
- ArrayMode arrayMode = node.arrayMode().modeForPut();
+ ArrayMode arrayMode = node->arrayMode().modeForPut();
bool alreadyHandled = false;
switch (arrayMode.type()) {
case Array::SelectUsingPredictions:
case Array::ForceExit:
- ASSERT_NOT_REACHED();
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ RELEASE_ASSERT_NOT_REACHED();
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
alreadyHandled = true;
break;
case Array::Generic: {
- ASSERT(node.op() == PutByVal);
+ RELEASE_ASSERT(node->op() == PutByVal);
JSValueOperand arg1(this, child1);
JSValueOperand arg2(this, child2);
@@ -2814,9 +2650,9 @@ void SpeculativeJIT::compile(Node& node)
GPRReg arg3GPR = arg3.gpr();
flushRegisters();
- callOperation(m_jit.strictModeFor(node.codeOrigin) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
+ callOperation(m_jit.strictModeFor(node->codeOrigin) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
- noResult(m_compileIndex);
+ noResult(node);
alreadyHandled = true;
break;
}
@@ -2839,18 +2675,18 @@ void SpeculativeJIT::compile(Node& node)
switch (arrayMode.type()) {
case Array::Int32:
case Array::Contiguous: {
- JSValueOperand value(this, child3);
+ JSValueOperand value(this, child3, ManualOperandSpeculation);
GPRReg valueReg = value.gpr();
if (!m_compileOkay)
return;
- if (arrayMode.type() == Array::Int32
- && !isInt32Speculation(m_state.forNode(child3).m_type)) {
- speculationCheck(
- BadType, JSValueRegs(valueReg), child3,
- m_jit.branch64(MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
+ if (arrayMode.type() == Array::Int32) {
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueReg), child3, SpecInt32,
+ m_jit.branch64(
+ MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
}
if (arrayMode.type() == Array::Contiguous && Heap::isWriteBarrierEnabled()) {
@@ -2861,32 +2697,32 @@ void SpeculativeJIT::compile(Node& node)
StorageOperand storage(this, child4);
GPRReg storageReg = storage.gpr();
- if (node.op() == PutByValAlias) {
+ if (node->op() == PutByValAlias) {
// Store the value to the array.
GPRReg propertyReg = property.gpr();
GPRReg valueReg = value.gpr();
m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
GPRTemporary temporary;
GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
- MacroAssembler::JumpList slowCases;
+ MacroAssembler::Jump slowCase;
if (arrayMode.isInBounds()) {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ StoreToHoleOrOutOfBounds, JSValueRegs(), 0,
m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
} else {
MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
- slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength())));
+ slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
if (!arrayMode.isOutOfBounds())
- speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases);
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
@@ -2904,12 +2740,12 @@ void SpeculativeJIT::compile(Node& node)
if (arrayMode.isOutOfBounds()) {
addSlowPathGenerator(
slowPathCall(
- slowCases, this,
+ slowCase, this,
m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
NoResult, baseReg, propertyReg, valueReg));
}
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
@@ -2935,13 +2771,13 @@ void SpeculativeJIT::compile(Node& node)
StorageOperand storage(this, child4);
GPRReg storageReg = storage.gpr();
- if (node.op() == PutByValAlias) {
+ if (node->op() == PutByValAlias) {
// Store the value to the array.
GPRReg propertyReg = property.gpr();
GPRReg valueReg = value.gpr();
m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -2952,17 +2788,14 @@ void SpeculativeJIT::compile(Node& node)
MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
if (!arrayMode.isOutOfBounds())
- speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
+ speculationCheck(OutOfBounds, JSValueRegs(), 0, beyondArrayBounds);
else
slowCases.append(beyondArrayBounds);
// Check if we're writing to a hole; if so increment m_numValuesInVector.
if (arrayMode.isInBounds()) {
- // This is uncountable because if we take this exit, then the baseline JIT
- // will immediately count the hole store. So there is no need for exit
- // profiling.
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ StoreToHole, JSValueRegs(), 0,
m_jit.branchTest64(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))));
} else {
MacroAssembler::Jump notHoleValue = m_jit.branchTest64(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
@@ -3000,7 +2833,7 @@ void SpeculativeJIT::compile(Node& node)
NoResult, baseReg, propertyReg, valueReg));
}
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
@@ -3018,12 +2851,12 @@ void SpeculativeJIT::compile(Node& node)
// Two really lame checks.
speculationCheck(
- Uncountable, JSValueSource(), NoNode,
- m_jit.branchPtr(
+ Uncountable, JSValueSource(), 0,
+ m_jit.branch32(
MacroAssembler::AboveOrEqual, propertyReg,
MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments))));
speculationCheck(
- Uncountable, JSValueSource(), NoNode,
+ Uncountable, JSValueSource(), 0,
m_jit.branchTestPtr(
MacroAssembler::NonZero,
MacroAssembler::Address(
@@ -3042,48 +2875,48 @@ void SpeculativeJIT::compile(Node& node)
scratchReg, scratch2Reg, MacroAssembler::TimesEight,
CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case Array::Int8Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), SignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->int8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int8_t), SignedTypedArray);
break;
case Array::Int16Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), SignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->int16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int16_t), SignedTypedArray);
break;
case Array::Int32Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), SignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->int32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(int32_t), SignedTypedArray);
break;
case Array::Uint8Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint8ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray);
break;
case Array::Uint8ClampedArray:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray, ClampRounding);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint8ClampedArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint8_t), UnsignedTypedArray, ClampRounding);
break;
case Array::Uint16Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), UnsignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint16ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint16_t), UnsignedTypedArray);
break;
case Array::Uint32Array:
- compilePutByValForIntTypedArray(m_jit.globalData()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), UnsignedTypedArray);
+ compilePutByValForIntTypedArray(m_jit.vm()->uint32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(uint32_t), UnsignedTypedArray);
break;
case Array::Float32Array:
- compilePutByValForFloatTypedArray(m_jit.globalData()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float));
+ compilePutByValForFloatTypedArray(m_jit.vm()->float32ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(float));
break;
case Array::Float64Array:
- compilePutByValForFloatTypedArray(m_jit.globalData()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double));
+ compilePutByValForFloatTypedArray(m_jit.vm()->float64ArrayDescriptor(), base.gpr(), property.gpr(), node, sizeof(double));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -3093,9 +2926,9 @@ void SpeculativeJIT::compile(Node& node)
case RegExpExec: {
if (compileRegExpExec(node))
return;
- if (!node.adjustedRefCount()) {
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ if (!node->adjustedRefCount()) {
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3105,12 +2938,12 @@ void SpeculativeJIT::compile(Node& node)
// Must use jsValueResult because otherwise we screw up register
// allocation, which thinks that this node has a result.
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
break;
}
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3118,13 +2951,13 @@ void SpeculativeJIT::compile(Node& node)
GPRResult result(this);
callOperation(operationRegExpExec, result.gpr(), baseGPR, argumentGPR);
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
break;
}
case RegExpTest: {
- SpeculateCellOperand base(this, node.child1());
- SpeculateCellOperand argument(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand argument(this, node->child2());
GPRReg baseGPR = base.gpr();
GPRReg argumentGPR = argument.gpr();
@@ -3134,37 +2967,38 @@ void SpeculativeJIT::compile(Node& node)
// If we add a DataFormatBool, we should use it here.
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
break;
}
case ArrayPush: {
- ASSERT(node.arrayMode().isJSArray());
+ ASSERT(node->arrayMode().isJSArray());
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary storageLength(this);
GPRReg baseGPR = base.gpr();
GPRReg storageLengthGPR = storageLength.gpr();
- StorageOperand storage(this, node.child3());
+ StorageOperand storage(this, node->child3());
GPRReg storageGPR = storage.gpr();
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::Int32:
case Array::Contiguous: {
- JSValueOperand value(this, node.child2());
+ JSValueOperand value(this, node->child2(), ManualOperandSpeculation);
GPRReg valueGPR = value.gpr();
- if (node.arrayMode().type() == Array::Int32 && !isInt32Speculation(m_state.forNode(node.child2()).m_type)) {
- speculationCheck(
- BadType, JSValueRegs(valueGPR), node.child2(),
- m_jit.branch64(MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister));
+ if (node->arrayMode().type() == Array::Int32) {
+ DFG_TYPE_CHECK(
+ JSValueRegs(valueGPR), node->child2(), SpecInt32,
+ m_jit.branch64(
+ MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister));
}
- if (node.arrayMode().type() != Array::Int32 && Heap::isWriteBarrierEnabled()) {
+ if (node->arrayMode().type() != Array::Int32 && Heap::isWriteBarrierEnabled()) {
GPRTemporary scratch(this);
- writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
+ writeBarrier(baseGPR, valueGPR, node->child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
}
m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
@@ -3179,21 +3013,17 @@ void SpeculativeJIT::compile(Node& node)
slowPath, this, operationArrayPush, NoResult, storageLengthGPR,
valueGPR, baseGPR));
- jsValueResult(storageLengthGPR, m_compileIndex);
+ jsValueResult(storageLengthGPR, node);
break;
}
case Array::Double: {
- SpeculateDoubleOperand value(this, node.child2());
+ SpeculateDoubleOperand value(this, node->child2());
FPRReg valueFPR = value.fpr();
- if (!isRealNumberSpeculation(m_state.forNode(node.child2()).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
- }
+ DFG_TYPE_CHECK(
+ JSValueRegs(), node->child2(), SpecRealNumber,
+ m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
@@ -3207,23 +3037,23 @@ void SpeculativeJIT::compile(Node& node)
slowPath, this, operationArrayPushDouble, NoResult, storageLengthGPR,
valueFPR, baseGPR));
- jsValueResult(storageLengthGPR, m_compileIndex);
+ jsValueResult(storageLengthGPR, node);
break;
}
case Array::ArrayStorage: {
- JSValueOperand value(this, node.child2());
+ JSValueOperand value(this, node->child2());
GPRReg valueGPR = value.gpr();
if (Heap::isWriteBarrierEnabled()) {
GPRTemporary scratch(this);
- writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
+ writeBarrier(baseGPR, valueGPR, node->child2(), WriteBarrierForPropertyAccess, scratch.gpr(), storageLengthGPR);
}
m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
// Refuse to handle bizarre lengths.
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
@@ -3239,7 +3069,7 @@ void SpeculativeJIT::compile(Node& node)
slowPath, this, operationArrayPush, NoResult, storageLengthGPR,
valueGPR, baseGPR));
- jsValueResult(storageLengthGPR, m_compileIndex);
+ jsValueResult(storageLengthGPR, node);
break;
}
@@ -3251,10 +3081,10 @@ void SpeculativeJIT::compile(Node& node)
}
case ArrayPop: {
- ASSERT(node.arrayMode().isJSArray());
+ ASSERT(node->arrayMode().isJSArray());
- SpeculateCellOperand base(this, node.child1());
- StorageOperand storage(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ StorageOperand storage(this, node->child2());
GPRTemporary value(this);
GPRTemporary storageLength(this);
FPRTemporary temp(this); // This is kind of lame, since we don't always need it. I'm relying on the fact that we don't have FPR pressure, especially in code that uses pop().
@@ -3265,7 +3095,7 @@ void SpeculativeJIT::compile(Node& node)
GPRReg storageLengthGPR = storageLength.gpr();
FPRReg tempFPR = temp.fpr();
- switch (node.arrayMode().type()) {
+ switch (node->arrayMode().type()) {
case Array::Int32:
case Array::Double:
case Array::Contiguous: {
@@ -3277,7 +3107,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.store32(
storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
MacroAssembler::Jump slowCase;
- if (node.arrayMode().type() == Array::Double) {
+ if (node->arrayMode().type() == Array::Double) {
m_jit.loadDouble(
MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight),
tempFPR);
@@ -3307,7 +3137,7 @@ void SpeculativeJIT::compile(Node& node)
slowCase, this, operationArrayPopAndRecoverLength, valueGPR, baseGPR));
// We can't know for sure that the result is an int because of the slow paths. :-/
- jsValueResult(valueGPR, m_compileIndex);
+ jsValueResult(valueGPR, node);
break;
}
@@ -3339,7 +3169,7 @@ void SpeculativeJIT::compile(Node& node)
slowPathCall(
slowCases, this, operationArrayPop, valueGPR, baseGPR));
- jsValueResult(valueGPR, m_compileIndex);
+ jsValueResult(valueGPR, node);
break;
}
@@ -3351,34 +3181,13 @@ void SpeculativeJIT::compile(Node& node)
}
case DFG::Jump: {
- BlockIndex taken = node.takenBlockIndex();
+ BlockIndex taken = node->takenBlockIndex();
jump(taken);
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case Branch:
- if (at(node.child1()).shouldSpeculateInteger()) {
- SpeculateIntegerOperand op(this, node.child1());
-
- BlockIndex taken = node.takenBlockIndex();
- BlockIndex notTaken = node.notTakenBlockIndex();
-
- MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
-
- if (taken == nextBlock()) {
- condition = MacroAssembler::Zero;
- BlockIndex tmp = taken;
- taken = notTaken;
- notTaken = tmp;
- }
-
- branchTest32(condition, op.gpr(), taken);
- jump(notTaken);
-
- noResult(m_compileIndex);
- break;
- }
emitBranch(node);
break;
@@ -3393,7 +3202,7 @@ void SpeculativeJIT::compile(Node& node)
#endif
// Return the result in returnValueGPR.
- JSValueOperand op1(this, node.child1());
+ JSValueOperand op1(this, node->child1());
m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
// Grab the return address.
@@ -3404,7 +3213,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT1);
m_jit.ret();
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -3412,29 +3221,13 @@ void SpeculativeJIT::compile(Node& node)
case ThrowReferenceError: {
// We expect that throw statements are rare and are intended to exit the code block
// anyway, so we just OSR back to the old JIT for now.
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
break;
}
case ToPrimitive: {
- if (at(node.child1()).shouldSpeculateInteger()) {
- // It's really profitable to speculate integer, since it's really cheap,
- // it means we don't have to do any real work, and we emit a lot less code.
-
- SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
-
- m_jit.move(op1.gpr(), result.gpr());
- if (op1.format() == DataFormatInteger)
- m_jit.or64(GPRInfo::tagTypeNumberRegister, result.gpr());
-
- jsValueResult(result.gpr(), m_compileIndex);
- break;
- }
-
- // FIXME: Add string speculation here.
-
- JSValueOperand op1(this, node.child1());
+ RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
+ JSValueOperand op1(this, node->child1());
GPRTemporary result(this, op1);
GPRReg op1GPR = op1.gpr();
@@ -3442,11 +3235,11 @@ void SpeculativeJIT::compile(Node& node)
op1.use();
- if (!(m_state.forNode(node.child1()).m_type & ~(SpecNumber | SpecBoolean)))
+ if (!(m_state.forNode(node->child1()).m_type & ~(SpecNumber | SpecBoolean)))
m_jit.move(op1GPR, resultGPR);
else {
MacroAssembler::Jump alreadyPrimitive = m_jit.branchTest64(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
- MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
+ MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get()));
alreadyPrimitive.link(&m_jit);
m_jit.move(op1GPR, resultGPR);
@@ -3455,24 +3248,63 @@ void SpeculativeJIT::compile(Node& node)
slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
}
- jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
+ break;
+ }
+
+ case ToString: {
+ if (node->child1().useKind() == UntypedUse) {
+ JSValueOperand op1(this, node->child1());
+ GPRReg op1GPR = op1.gpr();
+
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+
+ flushRegisters();
+
+ JITCompiler::Jump done;
+ if (node->child1()->prediction() & SpecString) {
+ JITCompiler::Jump slowPath1 = m_jit.branchTest64(
+ JITCompiler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
+ JITCompiler::Jump slowPath2 = m_jit.branchPtr(
+ JITCompiler::NotEqual,
+ JITCompiler::Address(op1GPR, JSCell::structureOffset()),
+ TrustedImmPtr(m_jit.vm()->stringStructure.get()));
+ m_jit.move(op1GPR, resultGPR);
+ done = m_jit.jump();
+ slowPath1.link(&m_jit);
+ slowPath2.link(&m_jit);
+ }
+ callOperation(operationToString, resultGPR, op1GPR);
+ if (done.isSet())
+ done.link(&m_jit);
+ cellResult(resultGPR, node);
+ break;
+ }
+
+ compileToStringOnCell(node);
+ break;
+ }
+
+ case NewStringObject: {
+ compileNewStringObject(node);
break;
}
case NewArray: {
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
- if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin);
+ if (!globalObject->isHavingABadTime() && !hasArrayStorage(node->indexingType())) {
globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
- Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType());
- ASSERT(structure->indexingType() == node.indexingType());
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
+ RELEASE_ASSERT(structure->indexingType() == node->indexingType());
ASSERT(
hasUndecided(structure->indexingType())
|| hasInt32(structure->indexingType())
|| hasDouble(structure->indexingType())
|| hasContiguous(structure->indexingType()));
- unsigned numElements = node.numChildren();
+ unsigned numElements = node->numChildren();
GPRTemporary result(this);
GPRTemporary storage(this);
@@ -3480,16 +3312,16 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
GPRReg storageGPR = storage.gpr();
- emitAllocateJSArray(structure, resultGPR, storageGPR, numElements);
+ emitAllocateJSArray(resultGPR, structure, storageGPR, numElements);
// At this point, one way or another, resultGPR and storageGPR have pointers to
// the JSArray and the Butterfly, respectively.
- ASSERT(!hasUndecided(structure->indexingType()) || !node.numChildren());
+ ASSERT(!hasUndecided(structure->indexingType()) || !node->numChildren());
- for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
- Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx];
- switch (node.indexingType()) {
+ for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
+ Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
+ switch (node->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
case ALL_UNDECIDED_INDEXING_TYPES:
CRASH();
@@ -3497,25 +3329,22 @@ void SpeculativeJIT::compile(Node& node)
case ALL_DOUBLE_INDEXING_TYPES: {
SpeculateDoubleOperand operand(this, use);
FPRReg opFPR = operand.fpr();
- if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
- }
-
+ DFG_TYPE_CHECK(
+ JSValueRegs(), use, SpecRealNumber,
+ m_jit.branchDouble(
+ MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
break;
}
case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES: {
- JSValueOperand operand(this, use);
+ JSValueOperand operand(this, use, ManualOperandSpeculation);
GPRReg opGPR = operand.gpr();
- if (hasInt32(node.indexingType()) && !isInt32Speculation(m_state.forNode(use).m_type)) {
- speculationCheck(
- BadType, JSValueRegs(opGPR), use.index(),
- m_jit.branch64(MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
+ if (hasInt32(node->indexingType())) {
+ DFG_TYPE_CHECK(
+ JSValueRegs(opGPR), use, SpecInt32,
+ m_jit.branch64(
+ MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
}
m_jit.store64(opGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
break;
@@ -3533,29 +3362,29 @@ void SpeculativeJIT::compile(Node& node)
// bigger problem will also likely fix the redundancy in reloading the storage
// pointer that we currently have.
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
- if (!node.numChildren()) {
+ if (!node->numChildren()) {
flushRegisters();
GPRResult result(this);
- callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()));
- cellResult(result.gpr(), m_compileIndex);
+ callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
+ cellResult(result.gpr(), node);
break;
}
- size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren();
- ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize);
+ size_t scratchSize = sizeof(EncodedJSValue) * node->numChildren();
+ ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(scratchSize);
EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
- for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
+ for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
// Need to perform the speculations that this node promises to perform. If we're
// emitting code here and the indexing type is not array storage then there is
// probably something hilarious going on and we're already failing at all the
// things, but at least we're going to be sound.
- Edge use = m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx];
- switch (node.indexingType()) {
+ Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
+ switch (node->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
case ALL_UNDECIDED_INDEXING_TYPES:
CRASH();
@@ -3565,25 +3394,22 @@ void SpeculativeJIT::compile(Node& node)
GPRTemporary scratch(this);
FPRReg opFPR = operand.fpr();
GPRReg scratchGPR = scratch.gpr();
- if (!isRealNumberSpeculation(m_state.forNode(use).m_type)) {
- // FIXME: We need a way of profiling these, and we need to hoist them into
- // SpeculateDoubleOperand.
- speculationCheck(
- BadType, JSValueRegs(), NoNode,
- m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
- }
-
+ DFG_TYPE_CHECK(
+ JSValueRegs(), use, SpecRealNumber,
+ m_jit.branchDouble(
+ MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
m_jit.boxDouble(opFPR, scratchGPR);
m_jit.store64(scratchGPR, buffer + operandIdx);
break;
}
case ALL_INT32_INDEXING_TYPES: {
- JSValueOperand operand(this, use);
+ JSValueOperand operand(this, use, ManualOperandSpeculation);
GPRReg opGPR = operand.gpr();
- if (hasInt32(node.indexingType()) && !isInt32Speculation(m_state.forNode(use).m_type)) {
- speculationCheck(
- BadType, JSValueRegs(opGPR), use.index(),
- m_jit.branch64(MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
+ if (hasInt32(node->indexingType())) {
+ DFG_TYPE_CHECK(
+ JSValueRegs(opGPR), use, SpecInt32,
+ m_jit.branch64(
+ MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
}
m_jit.store64(opGPR, buffer + operandIdx);
break;
@@ -3602,7 +3428,7 @@ void SpeculativeJIT::compile(Node& node)
}
}
- switch (node.indexingType()) {
+ switch (node->indexingType()) {
case ALL_DOUBLE_INDEXING_TYPES:
case ALL_INT32_INDEXING_TYPES:
useChildren(node);
@@ -3624,8 +3450,8 @@ void SpeculativeJIT::compile(Node& node)
GPRResult result(this);
callOperation(
- operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()),
- static_cast<void*>(buffer), node.numChildren());
+ operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
+ static_cast<void*>(buffer), node->numChildren());
if (scratchSize) {
GPRTemporary scratch(this);
@@ -3634,32 +3460,26 @@ void SpeculativeJIT::compile(Node& node)
m_jit.storePtr(TrustedImmPtr(0), scratch.gpr());
}
- cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
+ cellResult(result.gpr(), node, UseChildrenCalledExplicitly);
break;
}
case NewArrayWithSize: {
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
- if (!globalObject->isHavingABadTime() && !hasArrayStorage(node.indexingType())) {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin);
+ if (!globalObject->isHavingABadTime() && !hasArrayStorage(node->indexingType())) {
globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
- SpeculateStrictInt32Operand size(this, node.child1());
+ SpeculateStrictInt32Operand size(this, node->child1());
GPRTemporary result(this);
GPRTemporary storage(this);
GPRTemporary scratch(this);
- GPRTemporary scratch2;
+ GPRTemporary scratch2(this);
GPRReg sizeGPR = size.gpr();
GPRReg resultGPR = result.gpr();
GPRReg storageGPR = storage.gpr();
GPRReg scratchGPR = scratch.gpr();
- GPRReg scratch2GPR = InvalidGPRReg;
-
- if (hasDouble(node.indexingType())) {
- GPRTemporary realScratch2(this, size);
- scratch2.adopt(realScratch2);
- scratch2GPR = scratch2.gpr();
- }
+ GPRReg scratch2GPR = scratch2.gpr();
MacroAssembler::JumpList slowCases;
slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
@@ -3671,14 +3491,13 @@ void SpeculativeJIT::compile(Node& node)
slowCases.append(
emitAllocateBasicStorage(resultGPR, storageGPR));
m_jit.subPtr(scratchGPR, storageGPR);
- emitAllocateBasicJSObject<JSArray, MarkedBlock::None>(
- TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), resultGPR, scratchGPR,
- storageGPR, sizeof(JSArray), slowCases);
+ Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
+ emitAllocateJSObject<JSArray>(resultGPR, ImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases);
m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
- if (hasDouble(node.indexingType())) {
+ if (hasDouble(node->indexingType())) {
m_jit.move(TrustedImm64(bitwise_cast<int64_t>(QNaN)), scratchGPR);
m_jit.move(sizeGPR, scratch2GPR);
MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratch2GPR);
@@ -3692,76 +3511,38 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(adoptPtr(
new CallArrayAllocatorWithVariableSizeSlowPathGenerator(
slowCases, this, operationNewArrayWithSize, resultGPR,
- globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()),
+ globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage),
sizeGPR)));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
- SpeculateStrictInt32Operand size(this, node.child1());
+ SpeculateStrictInt32Operand size(this, node->child1());
GPRReg sizeGPR = size.gpr();
flushRegisters();
GPRResult result(this);
GPRReg resultGPR = result.gpr();
GPRReg structureGPR = selectScratchGPR(sizeGPR);
MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX));
- m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType())), structureGPR);
+ m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())), structureGPR);
MacroAssembler::Jump done = m_jit.jump();
bigLength.link(&m_jit);
m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR);
done.link(&m_jit);
callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR);
- cellResult(resultGPR, m_compileIndex);
- break;
- }
-
- case StrCat: {
- size_t scratchSize = sizeof(EncodedJSValue) * node.numChildren();
- ScratchBuffer* scratchBuffer = m_jit.globalData()->scratchBufferForSize(scratchSize);
- EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
-
- for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
- JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
- GPRReg opGPR = operand.gpr();
- operand.use();
-
- m_jit.store64(opGPR, buffer + operandIdx);
- }
-
- flushRegisters();
-
- if (scratchSize) {
- GPRTemporary scratch(this);
-
- // Tell GC mark phase how much of the scratch buffer is active during call.
- m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr());
- m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());
- }
-
- GPRResult result(this);
-
- callOperation(operationStrCat, result.gpr(), static_cast<void *>(buffer), node.numChildren());
-
- if (scratchSize) {
- GPRTemporary scratch(this);
-
- m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr());
- m_jit.storePtr(TrustedImmPtr(0), scratch.gpr());
- }
-
- cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
+ cellResult(resultGPR, node);
break;
}
case NewArrayBuffer: {
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
- IndexingType indexingType = node.indexingType();
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin);
+ IndexingType indexingType = node->indexingType();
if (!globalObject->isHavingABadTime() && !hasArrayStorage(indexingType)) {
globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
- unsigned numElements = node.numConstants();
+ unsigned numElements = node->numConstants();
GPRTemporary result(this);
GPRTemporary storage(this);
@@ -3769,35 +3550,35 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
GPRReg storageGPR = storage.gpr();
- emitAllocateJSArray(globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), resultGPR, storageGPR, numElements);
+ emitAllocateJSArray(resultGPR, globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements);
- ASSERT(indexingType & IsArray);
- JSValue* data = m_jit.codeBlock()->constantBuffer(node.startConstant());
+ RELEASE_ASSERT(indexingType & IsArray);
+ JSValue* data = m_jit.codeBlock()->constantBuffer(node->startConstant());
if (indexingType == ArrayWithDouble) {
- for (unsigned index = 0; index < node.numConstants(); ++index) {
+ for (unsigned index = 0; index < node->numConstants(); ++index) {
double value = data[index].asNumber();
m_jit.store64(
Imm64(bitwise_cast<int64_t>(value)),
MacroAssembler::Address(storageGPR, sizeof(double) * index));
}
} else {
- for (unsigned index = 0; index < node.numConstants(); ++index) {
+ for (unsigned index = 0; index < node->numConstants(); ++index) {
m_jit.store64(
Imm64(JSValue::encode(data[index])),
MacroAssembler::Address(storageGPR, sizeof(JSValue) * index));
}
}
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
flushRegisters();
GPRResult result(this);
- callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()), node.startConstant(), node.numConstants());
+ callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()), node->startConstant(), node->numConstants());
- cellResult(result.gpr(), m_compileIndex);
+ cellResult(result.gpr(), node);
break;
}
@@ -3805,54 +3586,15 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
GPRResult result(this);
- callOperation(operationNewRegexp, result.gpr(), m_jit.codeBlock()->regexp(node.regexpIndex()));
+ callOperation(operationNewRegexp, result.gpr(), m_jit.codeBlock()->regexp(node->regexpIndex()));
- cellResult(result.gpr(), m_compileIndex);
+ cellResult(result.gpr(), node);
break;
}
case ConvertThis: {
- if (isObjectSpeculation(m_state.forNode(node.child1()).m_type)) {
- SpeculateCellOperand thisValue(this, node.child1());
- GPRTemporary result(this, thisValue);
- m_jit.move(thisValue.gpr(), result.gpr());
- cellResult(result.gpr(), m_compileIndex);
- break;
- }
-
- if (isOtherSpeculation(at(node.child1()).prediction())) {
- JSValueOperand thisValue(this, node.child1());
- GPRTemporary scratch(this, thisValue);
- GPRReg thisValueGPR = thisValue.gpr();
- GPRReg scratchGPR = scratch.gpr();
-
- if (!isOtherSpeculation(m_state.forNode(node.child1()).m_type)) {
- m_jit.move(thisValueGPR, scratchGPR);
- m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
- speculationCheck(BadType, JSValueRegs(thisValueGPR), node.child1(), m_jit.branch64(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
- }
-
- m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalThisObjectFor(node.codeOrigin)), scratchGPR);
- cellResult(scratchGPR, m_compileIndex);
- break;
- }
-
- if (isObjectSpeculation(at(node.child1()).prediction())) {
- SpeculateCellOperand thisValue(this, node.child1());
- GPRTemporary result(this, thisValue);
- GPRReg thisValueGPR = thisValue.gpr();
- GPRReg resultGPR = result.gpr();
-
- if (!isObjectSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
-
- m_jit.move(thisValueGPR, resultGPR);
-
- cellResult(resultGPR, m_compileIndex);
- break;
- }
-
- JSValueOperand thisValue(this, node.child1());
+ ASSERT(node->child1().useKind() == UntypedUse);
+ JSValueOperand thisValue(this, node->child1());
GPRReg thisValueGPR = thisValue.gpr();
flushRegisters();
@@ -3860,7 +3602,7 @@ void SpeculativeJIT::compile(Node& node)
GPRResult result(this);
callOperation(operationConvertThis, result.gpr(), thisValueGPR);
- cellResult(result.gpr(), m_compileIndex);
+ cellResult(result.gpr(), node);
break;
}
@@ -3871,104 +3613,147 @@ void SpeculativeJIT::compile(Node& node)
// then we speculate because we want to get recompiled if it isn't (since
// otherwise we'd start taking slow path a lot).
- SpeculateCellOperand callee(this, node.child1());
+ SpeculateCellOperand callee(this, node->child1());
GPRTemporary result(this);
+ GPRTemporary allocator(this);
GPRTemporary structure(this);
GPRTemporary scratch(this);
GPRReg calleeGPR = callee.gpr();
GPRReg resultGPR = result.gpr();
+ GPRReg allocatorGPR = allocator.gpr();
GPRReg structureGPR = structure.gpr();
GPRReg scratchGPR = scratch.gpr();
-
- // Load the inheritorID. If the inheritorID is not set, go to slow path.
- m_jit.loadPtr(MacroAssembler::Address(calleeGPR, JSFunction::offsetOfCachedInheritorID()), structureGPR);
+
MacroAssembler::JumpList slowPath;
- slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, structureGPR));
-
- emitAllocateJSFinalObject(structureGPR, resultGPR, scratchGPR, slowPath);
-
- addSlowPathGenerator(slowPathCall(slowPath, this, operationCreateThis, resultGPR, calleeGPR));
+
+ m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorGPR);
+ m_jit.loadPtr(JITCompiler::Address(calleeGPR, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR);
+ slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR));
+ emitAllocateJSObject(resultGPR, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath);
+
+ addSlowPathGenerator(slowPathCall(slowPath, this, operationCreateThis, resultGPR, calleeGPR, node->inlineCapacity()));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
- case InheritorIDWatchpoint: {
- jsCast<JSFunction*>(node.function())->addInheritorIDWatchpoint(speculationWatchpoint());
- noResult(m_compileIndex);
+ case AllocationProfileWatchpoint: {
+ jsCast<JSFunction*>(node->function())->addAllocationProfileWatchpoint(speculationWatchpoint());
+ noResult(node);
break;
}
case NewObject: {
GPRTemporary result(this);
+ GPRTemporary allocator(this);
GPRTemporary scratch(this);
GPRReg resultGPR = result.gpr();
+ GPRReg allocatorGPR = allocator.gpr();
GPRReg scratchGPR = scratch.gpr();
MacroAssembler::JumpList slowPath;
+
+ Structure* structure = node->structure();
+ size_t allocationSize = JSObject::allocationSize(structure->inlineCapacity());
+ MarkedAllocator* allocatorPtr = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize);
+
+ m_jit.move(TrustedImmPtr(allocatorPtr), allocatorGPR);
+ emitAllocateJSObject(resultGPR, allocatorGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath);
+
+ addSlowPathGenerator(slowPathCall(slowPath, this, operationNewObject, resultGPR, structure));
- emitAllocateJSFinalObject(MacroAssembler::TrustedImmPtr(node.structure()), resultGPR, scratchGPR, slowPath);
-
- addSlowPathGenerator(slowPathCall(slowPath, this, operationNewObject, resultGPR, node.structure()));
-
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case GetCallee: {
GPRTemporary result(this);
- m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::Callee)), result.gpr());
- cellResult(result.gpr(), m_compileIndex);
+ m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::Callee))), result.gpr());
+ cellResult(result.gpr(), node);
break;
}
-
+
+ case SetCallee: {
+ SpeculateCellOperand callee(this, node->child1());
+ m_jit.storePtr(callee.gpr(), JITCompiler::addressFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::Callee))));
+ noResult(node);
+ break;
+ }
+
case GetScope: {
+ SpeculateCellOperand function(this, node->child1());
+ GPRTemporary result(this, function);
+ m_jit.loadPtr(JITCompiler::Address(function.gpr(), JSFunction::offsetOfScopeChain()), result.gpr());
+ cellResult(result.gpr(), node);
+ break;
+ }
+
+ case GetMyScope: {
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
- m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::ScopeChain)), resultGPR);
- bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain();
- int skip = node.scopeChainDepth();
- ASSERT(skip || !checkTopLevel);
- if (checkTopLevel && skip--) {
- JITCompiler::Jump activationNotCreated;
- if (checkTopLevel)
- activationNotCreated = m_jit.branchTest64(JITCompiler::Zero, JITCompiler::addressFor(static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
- m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
- activationNotCreated.link(&m_jit);
- }
- while (skip--)
- m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
+ m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::ScopeChain))), resultGPR);
+ cellResult(resultGPR, node);
+ break;
+ }
+
+ case SetMyScope: {
+ SpeculateCellOperand callee(this, node->child1());
+ m_jit.storePtr(callee.gpr(), JITCompiler::addressFor(static_cast<VirtualRegister>(node->codeOrigin.stackOffset() + static_cast<int>(JSStack::ScopeChain))));
+ noResult(node);
+ break;
+ }
+
+ case SkipTopScope: {
+ SpeculateCellOperand scope(this, node->child1());
+ GPRTemporary result(this, scope);
+ GPRReg resultGPR = result.gpr();
+ m_jit.move(scope.gpr(), resultGPR);
+ JITCompiler::Jump activationNotCreated =
+ m_jit.branchTest64(
+ JITCompiler::Zero,
+ JITCompiler::addressFor(
+ static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
+ m_jit.loadPtr(JITCompiler::Address(resultGPR, JSScope::offsetOfNext()), resultGPR);
+ activationNotCreated.link(&m_jit);
+ cellResult(resultGPR, node);
+ break;
+ }
- cellResult(resultGPR, m_compileIndex);
+ case SkipScope: {
+ SpeculateCellOperand scope(this, node->child1());
+ GPRTemporary result(this, scope);
+ m_jit.loadPtr(JITCompiler::Address(scope.gpr(), JSScope::offsetOfNext()), result.gpr());
+ cellResult(result.gpr(), node);
break;
}
+
case GetScopeRegisters: {
- SpeculateCellOperand scope(this, node.child1());
+ SpeculateCellOperand scope(this, node->child1());
GPRTemporary result(this);
GPRReg scopeGPR = scope.gpr();
GPRReg resultGPR = result.gpr();
m_jit.loadPtr(JITCompiler::Address(scopeGPR, JSVariableObject::offsetOfRegisters()), resultGPR);
- storageResult(resultGPR, m_compileIndex);
+ storageResult(resultGPR, node);
break;
}
case GetScopedVar: {
- StorageOperand registers(this, node.child1());
+ StorageOperand registers(this, node->child1());
GPRTemporary result(this);
GPRReg registersGPR = registers.gpr();
GPRReg resultGPR = result.gpr();
- m_jit.load64(JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register)), resultGPR);
- jsValueResult(resultGPR, m_compileIndex);
+ m_jit.load64(JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)), resultGPR);
+ jsValueResult(resultGPR, node);
break;
}
case PutScopedVar: {
- SpeculateCellOperand scope(this, node.child1());
- StorageOperand registers(this, node.child2());
- JSValueOperand value(this, node.child3());
+ SpeculateCellOperand scope(this, node->child1());
+ StorageOperand registers(this, node->child2());
+ JSValueOperand value(this, node->child3());
GPRTemporary scratchRegister(this);
GPRReg scopeGPR = scope.gpr();
@@ -3976,19 +3761,20 @@ void SpeculativeJIT::compile(Node& node)
GPRReg valueGPR = value.gpr();
GPRReg scratchGPR = scratchRegister.gpr();
- m_jit.store64(valueGPR, JITCompiler::Address(registersGPR, node.varNumber() * sizeof(Register)));
- writeBarrier(scopeGPR, valueGPR, node.child3(), WriteBarrierForVariableAccess, scratchGPR);
- noResult(m_compileIndex);
+ m_jit.store64(valueGPR, JITCompiler::Address(registersGPR, node->varNumber() * sizeof(Register)));
+ writeBarrier(scopeGPR, valueGPR, node->child3(), WriteBarrierForVariableAccess, scratchGPR);
+ noResult(node);
break;
}
case GetById: {
- if (!node.prediction()) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ if (!node->prediction()) {
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
-
- if (isCellSpeculation(at(node.child1()).prediction())) {
- SpeculateCellOperand base(this, node.child1());
+
+ switch (node->child1().useKind()) {
+ case CellUse: {
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary result(this, base);
GPRReg baseGPR = base.gpr();
@@ -3996,37 +3782,45 @@ void SpeculativeJIT::compile(Node& node)
base.use();
- cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber());
+ cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber());
- jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
break;
}
- JSValueOperand base(this, node.child1());
- GPRTemporary result(this, base);
-
- GPRReg baseGPR = base.gpr();
- GPRReg resultGPR = result.gpr();
+ case UntypedUse: {
+ JSValueOperand base(this, node->child1());
+ GPRTemporary result(this, base);
- base.use();
+ GPRReg baseGPR = base.gpr();
+ GPRReg resultGPR = result.gpr();
- JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+ base.use();
- cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell);
+ JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell);
+ jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
case GetByIdFlush: {
- if (!node.prediction()) {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ if (!node->prediction()) {
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
-
- if (isCellSpeculation(at(node.child1()).prediction())) {
- SpeculateCellOperand base(this, node.child1());
+
+ switch (node->child1().useKind()) {
+ case CellUse: {
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseGPR = base.gpr();
GPRResult result(this);
@@ -4037,27 +3831,34 @@ void SpeculativeJIT::compile(Node& node)
flushRegisters();
- cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), JITCompiler::Jump(), DontSpill);
+ cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), JITCompiler::Jump(), DontSpill);
- jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
break;
}
- JSValueOperand base(this, node.child1());
- GPRReg baseGPR = base.gpr();
+ case UntypedUse: {
+ JSValueOperand base(this, node->child1());
+ GPRReg baseGPR = base.gpr();
- GPRResult result(this);
- GPRReg resultGPR = result.gpr();
-
- base.use();
- flushRegisters();
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
- JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+ base.use();
+ flushRegisters();
- cachedGetById(node.codeOrigin, baseGPR, resultGPR, node.identifierNumber(), notCell, DontSpill);
+ JITCompiler::Jump notCell = m_jit.branchTest64(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
+ cachedGetById(node->codeOrigin, baseGPR, resultGPR, node->identifierNumber(), notCell, DontSpill);
+ jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
+ break;
+ }
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
break;
}
@@ -4066,39 +3867,38 @@ void SpeculativeJIT::compile(Node& node)
break;
case CheckFunction: {
- SpeculateCellOperand function(this, node.child1());
- speculationCheck(BadCache, JSValueRegs(function.gpr()), node.child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node.function()));
- noResult(m_compileIndex);
+ SpeculateCellOperand function(this, node->child1());
+ speculationCheck(BadFunction, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node->function()));
+ noResult(node);
break;
}
+
+ case CheckExecutable: {
+ SpeculateCellOperand function(this, node->child1());
+ speculationCheck(BadExecutable, JSValueSource::unboxedCell(function.gpr()), node->child1(), m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(function.gpr(), JSFunction::offsetOfExecutable()), node->executable()));
+ noResult(node);
+ break;
+ }
+
case CheckStructure:
case ForwardCheckStructure: {
- AbstractValue& value = m_state.forNode(node.child1());
- if (value.m_currentKnownStructure.isSubsetOf(node.structureSet())
- && isCellSpeculation(value.m_type)) {
- noResult(m_compileIndex);
- break;
- }
-
- SpeculationDirection direction = node.op() == ForwardCheckStructure ? ForwardSpeculation : BackwardSpeculation;
- SpeculateCellOperand base(this, node.child1(), direction);
+ SpeculateCellOperand base(this, node->child1());
- ASSERT(node.structureSet().size());
+ ASSERT(node->structureSet().size());
ExitKind exitKind;
- if (m_jit.graph()[node.child1()].op() == WeakJSConstant)
+ if (node->child1()->op() == WeakJSConstant)
exitKind = BadWeakConstantCache;
else
exitKind = BadCache;
- if (node.structureSet().size() == 1) {
+ if (node->structureSet().size() == 1) {
speculationCheck(
- exitKind, JSValueRegs(base.gpr()), NoNode,
+ exitKind, JSValueSource::unboxedCell(base.gpr()), 0,
m_jit.branchWeakPtr(
JITCompiler::NotEqual,
JITCompiler::Address(base.gpr(), JSCell::structureOffset()),
- node.structureSet()[0]),
- direction);
+ node->structureSet()[0]));
} else {
GPRTemporary structure(this);
@@ -4106,19 +3906,18 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::JumpList done;
- for (size_t i = 0; i < node.structureSet().size() - 1; ++i)
- done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node.structureSet()[i]));
+ for (size_t i = 0; i < node->structureSet().size() - 1; ++i)
+ done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node->structureSet()[i]));
speculationCheck(
- exitKind, JSValueRegs(base.gpr()), NoNode,
+ exitKind, JSValueSource::unboxedCell(base.gpr()), 0,
m_jit.branchWeakPtr(
- JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()),
- direction);
+ JITCompiler::NotEqual, structure.gpr(), node->structureSet().last()));
done.link(&m_jit);
}
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4131,54 +3930,55 @@ void SpeculativeJIT::compile(Node& node)
// we'll just rely on the fact that when a watchpoint fires then that's
// quite a hint already.
- SpeculationDirection direction = node.op() == ForwardStructureTransitionWatchpoint ? ForwardSpeculation : BackwardSpeculation;
-
- m_jit.addWeakReference(node.structure());
- node.structure()->addTransitionWatchpoint(
+ m_jit.addWeakReference(node->structure());
+ node->structure()->addTransitionWatchpoint(
speculationWatchpoint(
- m_jit.graph()[node.child1()].op() == WeakJSConstant ? BadWeakConstantCache : BadCache,
- direction));
+ node->child1()->op() == WeakJSConstant ? BadWeakConstantCache : BadCache));
#if !ASSERT_DISABLED
- SpeculateCellOperand op1(this, node.child1(), direction);
- JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node.structure()));
+ SpeculateCellOperand op1(this, node->child1());
+ JITCompiler::Jump isOK = m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(op1.gpr(), JSCell::structureOffset()), TrustedImmPtr(node->structure()));
m_jit.breakpoint();
isOK.link(&m_jit);
+#else
+ speculateCell(node->child1());
#endif
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case PhantomPutStructure: {
- ASSERT(node.structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
+ ASSERT(isKnownCell(node->child1().node()));
+
+ ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
m_jit.addWeakReferenceTransition(
- node.codeOrigin.codeOriginOwner(),
- node.structureTransitionData().previousStructure,
- node.structureTransitionData().newStructure);
- noResult(m_compileIndex);
+ node->codeOrigin.codeOriginOwner(),
+ node->structureTransitionData().previousStructure,
+ node->structureTransitionData().newStructure);
+ noResult(node);
break;
}
case PutStructure: {
- ASSERT(node.structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
+ ASSERT(node->structureTransitionData().previousStructure->transitionWatchpointSetHasBeenInvalidated());
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRReg baseGPR = base.gpr();
m_jit.addWeakReferenceTransition(
- node.codeOrigin.codeOriginOwner(),
- node.structureTransitionData().previousStructure,
- node.structureTransitionData().newStructure);
+ node->codeOrigin.codeOriginOwner(),
+ node->structureTransitionData().previousStructure,
+ node->structureTransitionData().newStructure);
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
// Must always emit this write barrier as the structure transition itself requires it
- writeBarrier(baseGPR, node.structureTransitionData().newStructure, WriteBarrierForGenericAccess);
+ writeBarrier(baseGPR, node->structureTransitionData().newStructure, WriteBarrierForGenericAccess);
#endif
- m_jit.storePtr(MacroAssembler::TrustedImmPtr(node.structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
+ m_jit.storePtr(MacroAssembler::TrustedImmPtr(node->structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4191,7 +3991,7 @@ void SpeculativeJIT::compile(Node& node)
break;
case GetButterfly: {
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary result(this, base);
GPRReg baseGPR = base.gpr();
@@ -4199,7 +3999,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::butterflyOffset()), resultGPR);
- storageResult(resultGPR, m_compileIndex);
+ storageResult(resultGPR, node);
break;
}
@@ -4209,45 +4009,45 @@ void SpeculativeJIT::compile(Node& node)
}
case GetByOffset: {
- StorageOperand storage(this, node.child1());
+ StorageOperand storage(this, node->child1());
GPRTemporary result(this, storage);
GPRReg storageGPR = storage.gpr();
GPRReg resultGPR = result.gpr();
- StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
+ StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
m_jit.load64(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue)), resultGPR);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, node);
break;
}
case PutByOffset: {
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
- SpeculateCellOperand base(this, node.child2());
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ SpeculateCellOperand base(this, node->child2());
#endif
- StorageOperand storage(this, node.child1());
- JSValueOperand value(this, node.child3());
+ StorageOperand storage(this, node->child1());
+ JSValueOperand value(this, node->child3());
GPRReg storageGPR = storage.gpr();
GPRReg valueGPR = value.gpr();
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
- writeBarrier(base.gpr(), value.gpr(), node.child3(), WriteBarrierForPropertyAccess);
+#if ENABLE(WRITE_BARRIER_PROFILING)
+ writeBarrier(base.gpr(), value.gpr(), node->child3(), WriteBarrierForPropertyAccess);
#endif
- StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
+ StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node->storageAccessDataIndex()];
m_jit.store64(valueGPR, JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case PutById: {
- SpeculateCellOperand base(this, node.child1());
- JSValueOperand value(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ JSValueOperand value(this, node->child2());
GPRTemporary scratch(this);
GPRReg baseGPR = base.gpr();
@@ -4257,15 +4057,15 @@ void SpeculativeJIT::compile(Node& node)
base.use();
value.use();
- cachedPutById(node.codeOrigin, baseGPR, valueGPR, node.child2(), scratchGPR, node.identifierNumber(), NotDirect);
+ cachedPutById(node->codeOrigin, baseGPR, valueGPR, node->child2(), scratchGPR, node->identifierNumber(), NotDirect);
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
case PutByIdDirect: {
- SpeculateCellOperand base(this, node.child1());
- JSValueOperand value(this, node.child2());
+ SpeculateCellOperand base(this, node->child1());
+ JSValueOperand value(this, node->child2());
GPRTemporary scratch(this);
GPRReg baseGPR = base.gpr();
@@ -4275,43 +4075,43 @@ void SpeculativeJIT::compile(Node& node)
base.use();
value.use();
- cachedPutById(node.codeOrigin, baseGPR, valueGPR, node.child2(), scratchGPR, node.identifierNumber(), Direct);
+ cachedPutById(node->codeOrigin, baseGPR, valueGPR, node->child2(), scratchGPR, node->identifierNumber(), Direct);
- noResult(m_compileIndex, UseChildrenCalledExplicitly);
+ noResult(node, UseChildrenCalledExplicitly);
break;
}
case GetGlobalVar: {
GPRTemporary result(this);
- m_jit.load64(node.registerPointer(), result.gpr());
+ m_jit.load64(node->registerPointer(), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), node);
break;
}
case PutGlobalVar: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
if (Heap::isWriteBarrierEnabled()) {
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
- writeBarrier(m_jit.globalObjectFor(node.codeOrigin), value.gpr(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
+ writeBarrier(m_jit.globalObjectFor(node->codeOrigin), value.gpr(), node->child1(), WriteBarrierForVariableAccess, scratchReg);
}
- m_jit.store64(value.gpr(), node.registerPointer());
+ m_jit.store64(value.gpr(), node->registerPointer());
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case PutGlobalVarCheck: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
WatchpointSet* watchpointSet =
- m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
- identifier(node.identifierNumberForCheck())->impl()).watchpointSet();
+ m_jit.globalObjectFor(node->codeOrigin)->symbolTable()->get(
+ identifier(node->identifierNumberForCheck())->impl()).watchpointSet();
addSlowPathGenerator(
slowPathCall(
m_jit.branchTest8(
@@ -4323,44 +4123,44 @@ void SpeculativeJIT::compile(Node& node)
GPRTemporary scratch(this);
GPRReg scratchReg = scratch.gpr();
- writeBarrier(m_jit.globalObjectFor(node.codeOrigin), value.gpr(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
+ writeBarrier(m_jit.globalObjectFor(node->codeOrigin), value.gpr(), node->child1(), WriteBarrierForVariableAccess, scratchReg);
}
- m_jit.store64(value.gpr(), node.registerPointer());
+ m_jit.store64(value.gpr(), node->registerPointer());
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case GlobalVarWatchpoint: {
- m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
- identifier(node.identifierNumberForCheck())->impl()).addWatchpoint(
+ m_jit.globalObjectFor(node->codeOrigin)->symbolTable()->get(
+ identifier(node->identifierNumberForCheck())->impl()).addWatchpoint(
speculationWatchpoint());
#if DFG_ENABLE(JIT_ASSERT)
GPRTemporary scratch(this);
GPRReg scratchGPR = scratch.gpr();
- m_jit.load64(node.registerPointer(), scratchGPR);
+ m_jit.load64(node->registerPointer(), scratchGPR);
JITCompiler::Jump ok = m_jit.branch64(
JITCompiler::Equal, scratchGPR,
- TrustedImm64(JSValue::encode(node.registerPointer()->get())));
+ TrustedImm64(JSValue::encode(node->registerPointer()->get())));
m_jit.breakpoint();
ok.link(&m_jit);
#endif
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case CheckHasInstance: {
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node->child1());
GPRTemporary structure(this);
// Speculate that base 'ImplementsDefaultHasInstance'.
m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
- speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
+ speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4370,18 +4170,20 @@ void SpeculativeJIT::compile(Node& node)
}
case IsUndefined: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this);
-
+ GPRTemporary localGlobalObject(this);
+ GPRTemporary remoteGlobalObject(this);
+
JITCompiler::Jump isCell = m_jit.branchTest64(JITCompiler::Zero, value.gpr(), GPRInfo::tagMaskRegister);
-
+
m_jit.compare64(JITCompiler::Equal, value.gpr(), TrustedImm32(ValueUndefined), result.gpr());
JITCompiler::Jump done = m_jit.jump();
isCell.link(&m_jit);
JITCompiler::Jump notMasqueradesAsUndefined;
- if (m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
- m_jit.graph().globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
+ if (m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
+ m_jit.graph().globalObjectFor(node->codeOrigin)->masqueradesAsUndefinedWatchpoint()->add(speculationWatchpoint());
m_jit.move(TrustedImm32(0), result.gpr());
notMasqueradesAsUndefined = m_jit.jump();
} else {
@@ -4391,11 +4193,9 @@ void SpeculativeJIT::compile(Node& node)
notMasqueradesAsUndefined = m_jit.jump();
isMasqueradesAsUndefined.link(&m_jit);
- GPRTemporary localGlobalObject(this);
- GPRTemporary remoteGlobalObject(this);
GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
- m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), localGlobalObjectGPR);
+ m_jit.move(TrustedImmPtr(m_jit.globalObjectFor(node->codeOrigin)), localGlobalObjectGPR);
m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), remoteGlobalObjectGPR);
m_jit.comparePtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, result.gpr());
}
@@ -4403,34 +4203,34 @@ void SpeculativeJIT::compile(Node& node)
notMasqueradesAsUndefined.link(&m_jit);
done.link(&m_jit);
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
break;
}
case IsBoolean: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.move(value.gpr(), result.gpr());
m_jit.xor64(JITCompiler::TrustedImm32(ValueFalse), result.gpr());
m_jit.test64(JITCompiler::Zero, result.gpr(), JITCompiler::TrustedImm32(static_cast<int32_t>(~1)), result.gpr());
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
break;
}
case IsNumber: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
m_jit.test64(JITCompiler::NonZero, value.gpr(), GPRInfo::tagTypeNumberRegister, result.gpr());
m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
break;
}
case IsString: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
JITCompiler::Jump isNotCell = m_jit.branchTest64(JITCompiler::NonZero, value.gpr(), GPRInfo::tagMaskRegister);
@@ -4444,31 +4244,90 @@ void SpeculativeJIT::compile(Node& node)
m_jit.move(TrustedImm32(ValueFalse), result.gpr());
done.link(&m_jit);
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
break;
}
case IsObject: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRReg valueGPR = value.gpr();
GPRResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
callOperation(operationIsObject, resultGPR, valueGPR);
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
break;
}
case IsFunction: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRReg valueGPR = value.gpr();
GPRResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
callOperation(operationIsFunction, resultGPR, valueGPR);
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
+ jsValueResult(result.gpr(), node, DataFormatJSBoolean);
+ break;
+ }
+
+ case TypeOf: {
+ JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
+ GPRReg valueGPR = value.gpr();
+ GPRTemporary temp(this);
+ GPRReg tempGPR = temp.gpr();
+ GPRResult result(this);
+ GPRReg resultGPR = result.gpr();
+ JITCompiler::JumpList doneJumps;
+
+ flushRegisters();
+
+ ASSERT(node->child1().useKind() == UntypedUse || node->child1().useKind() == CellUse || node->child1().useKind() == StringUse);
+
+ JITCompiler::Jump isNotCell = m_jit.branchTest64(JITCompiler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
+ if (node->child1().useKind() != UntypedUse)
+ DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecCell, isNotCell);
+
+ if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
+ m_jit.loadPtr(JITCompiler::Address(valueGPR, JSCell::structureOffset()), tempGPR);
+ JITCompiler::Jump notString = m_jit.branch8(JITCompiler::NotEqual, JITCompiler::Address(tempGPR, Structure::typeInfoTypeOffset()), TrustedImm32(StringType));
+ if (node->child1().useKind() == StringUse)
+ DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecString, notString);
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.stringString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ if (node->child1().useKind() != StringUse) {
+ notString.link(&m_jit);
+ callOperation(operationTypeOf, resultGPR, valueGPR);
+ doneJumps.append(m_jit.jump());
+ }
+ } else {
+ callOperation(operationTypeOf, resultGPR, valueGPR);
+ doneJumps.append(m_jit.jump());
+ }
+
+ if (node->child1().useKind() == UntypedUse) {
+ isNotCell.link(&m_jit);
+ JITCompiler::Jump notNumber = m_jit.branchTest64(JITCompiler::Zero, valueGPR, GPRInfo::tagTypeNumberRegister);
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.numberString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ notNumber.link(&m_jit);
+
+ JITCompiler::Jump notUndefined = m_jit.branch64(JITCompiler::NotEqual, valueGPR, JITCompiler::TrustedImm64(ValueUndefined));
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.undefinedString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ notUndefined.link(&m_jit);
+
+ JITCompiler::Jump notNull = m_jit.branch64(JITCompiler::NotEqual, valueGPR, JITCompiler::TrustedImm64(ValueNull));
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.objectString()), resultGPR);
+ doneJumps.append(m_jit.jump());
+ notNull.link(&m_jit);
+
+ // Only boolean left
+ m_jit.move(TrustedImmPtr(m_jit.vm()->smallStrings.booleanString()), resultGPR);
+ }
+ doneJumps.link(&m_jit);
+ cellResult(resultGPR, node);
break;
}
@@ -4480,7 +4339,7 @@ void SpeculativeJIT::compile(Node& node)
#if ENABLE(DEBUG_WITH_BREAKPOINT)
m_jit.breakpoint();
#else
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif
break;
@@ -4492,27 +4351,27 @@ void SpeculativeJIT::compile(Node& node)
case Resolve: {
flushRegisters();
GPRResult result(this);
- ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node.resolveOperationsDataIndex()];
- callOperation(operationResolve, result.gpr(), identifier(data.identifierNumber), resolveOperations(data.resolveOperationsIndex));
- jsValueResult(result.gpr(), m_compileIndex);
+ ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node->resolveOperationsDataIndex()];
+ callOperation(operationResolve, result.gpr(), identifier(data.identifierNumber), data.resolveOperations);
+ jsValueResult(result.gpr(), node);
break;
}
case ResolveBase: {
flushRegisters();
GPRResult result(this);
- ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node.resolveOperationsDataIndex()];
- callOperation(operationResolveBase, result.gpr(), identifier(data.identifierNumber), resolveOperations(data.resolveOperationsIndex), putToBaseOperation(data.putToBaseOperationIndex));
- jsValueResult(result.gpr(), m_compileIndex);
+ ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node->resolveOperationsDataIndex()];
+ callOperation(operationResolveBase, result.gpr(), identifier(data.identifierNumber), data.resolveOperations, data.putToBaseOperation);
+ jsValueResult(result.gpr(), node);
break;
}
case ResolveBaseStrictPut: {
flushRegisters();
GPRResult result(this);
- ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node.resolveOperationsDataIndex()];
- callOperation(operationResolveBaseStrictPut, result.gpr(), identifier(data.identifierNumber), resolveOperations(data.resolveOperationsIndex), putToBaseOperation(data.putToBaseOperationIndex));
- jsValueResult(result.gpr(), m_compileIndex);
+ ResolveOperationData& data = m_jit.graph().m_resolveOperationsData[node->resolveOperationsDataIndex()];
+ callOperation(operationResolveBaseStrictPut, result.gpr(), identifier(data.identifierNumber), data.resolveOperations, data.putToBaseOperation);
+ jsValueResult(result.gpr(), node);
break;
}
@@ -4525,11 +4384,11 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resolveInfoGPR = resolveInfo.gpr();
GPRReg resultGPR = result.gpr();
- ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node.resolveGlobalDataIndex()];
- ResolveOperation* resolveOperationAddress = &(m_jit.codeBlock()->resolveOperations(data.resolveOperationsIndex)->data()[data.resolvePropertyIndex]);
+ ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node->resolveGlobalDataIndex()];
+ ResolveOperation* resolveOperationAddress = &(data.resolveOperations->data()[data.resolvePropertyIndex]);
// Check Structure of global object
- m_jit.move(JITCompiler::TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), globalObjectGPR);
+ m_jit.move(JITCompiler::TrustedImmPtr(m_jit.globalObjectFor(node->codeOrigin)), globalObjectGPR);
m_jit.move(JITCompiler::TrustedImmPtr(resolveOperationAddress), resolveInfoGPR);
m_jit.loadPtr(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(ResolveOperation, m_structure)), resultGPR);
JITCompiler::Jump structuresDontMatch = m_jit.branchPtr(JITCompiler::NotEqual, resultGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset()));
@@ -4552,14 +4411,14 @@ void SpeculativeJIT::compile(Node& node)
resultGPR, resolveInfoGPR, globalObjectGPR,
&m_jit.codeBlock()->identifier(data.identifierNumber)));
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, node);
break;
}
case CreateActivation: {
- ASSERT(!node.codeOrigin.inlineCallFrame);
+ RELEASE_ASSERT(!node->codeOrigin.inlineCallFrame);
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
GPRReg valueGPR = value.gpr();
@@ -4572,12 +4431,12 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(
slowPathCall(notCreated, this, operationCreateActivation, resultGPR));
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case CreateArguments: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
GPRReg valueGPR = value.gpr();
@@ -4587,31 +4446,31 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
addSlowPathGenerator(
slowPathCall(
notCreated, this, operationCreateInlinedArguments, resultGPR,
- node.codeOrigin.inlineCallFrame));
+ node->codeOrigin.inlineCallFrame));
} else {
addSlowPathGenerator(
slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
}
- cellResult(resultGPR, m_compileIndex);
+ cellResult(resultGPR, node);
break;
}
case TearOffActivation: {
- ASSERT(!node.codeOrigin.inlineCallFrame);
+ RELEASE_ASSERT(!node->codeOrigin.inlineCallFrame);
- JSValueOperand activationValue(this, node.child1());
+ JSValueOperand activationValue(this, node->child1());
GPRTemporary scratch(this);
GPRReg activationValueGPR = activationValue.gpr();
GPRReg scratchGPR = scratch.gpr();
JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, activationValueGPR);
- SharedSymbolTable* symbolTable = m_jit.symbolTableFor(node.codeOrigin);
+ SharedSymbolTable* symbolTable = m_jit.symbolTableFor(node->codeOrigin);
int registersOffset = JSActivation::registersOffset(symbolTable);
int captureEnd = symbolTable->captureEnd();
@@ -4627,30 +4486,30 @@ void SpeculativeJIT::compile(Node& node)
m_jit.storePtr(scratchGPR, JITCompiler::Address(activationValueGPR, JSActivation::offsetOfRegisters()));
notCreated.link(&m_jit);
- noResult(m_compileIndex);
+ noResult(node);
break;
}
case TearOffArguments: {
- JSValueOperand unmodifiedArgumentsValue(this, node.child1());
- JSValueOperand activationValue(this, node.child2());
+ JSValueOperand unmodifiedArgumentsValue(this, node->child1());
+ JSValueOperand activationValue(this, node->child2());
GPRReg unmodifiedArgumentsValueGPR = unmodifiedArgumentsValue.gpr();
GPRReg activationValueGPR = activationValue.gpr();
JITCompiler::Jump created = m_jit.branchTest64(JITCompiler::NonZero, unmodifiedArgumentsValueGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
addSlowPathGenerator(
slowPathCall(
created, this, operationTearOffInlinedArguments, NoResult,
- unmodifiedArgumentsValueGPR, activationValueGPR, node.codeOrigin.inlineCallFrame));
+ unmodifiedArgumentsValueGPR, activationValueGPR, node->codeOrigin.inlineCallFrame));
} else {
addSlowPathGenerator(
slowPathCall(
created, this, operationTearOffArguments, NoResult, unmodifiedArgumentsValueGPR, activationValueGPR));
}
- noResult(m_compileIndex);
+ noResult(node);
break;
}
@@ -4660,19 +4519,19 @@ void SpeculativeJIT::compile(Node& node)
if (!isEmptySpeculation(
m_state.variables().operand(
- m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type)) {
+ m_jit.graph().argumentsRegisterFor(node->codeOrigin)).m_type)) {
speculationCheck(
- ArgumentsEscaped, JSValueRegs(), NoNode,
+ ArgumentsEscaped, JSValueRegs(), 0,
m_jit.branchTest64(
JITCompiler::NonZero,
JITCompiler::addressFor(
- m_jit.argumentsRegisterFor(node.codeOrigin))));
+ m_jit.argumentsRegisterFor(node->codeOrigin))));
}
- ASSERT(!node.codeOrigin.inlineCallFrame);
+ RELEASE_ASSERT(!node->codeOrigin.inlineCallFrame);
m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
m_jit.sub32(TrustedImm32(1), resultGPR);
- integerResult(resultGPR, m_compileIndex);
+ integerResult(resultGPR, node);
break;
}
@@ -4683,11 +4542,11 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::Jump created = m_jit.branchTest64(
JITCompiler::NonZero,
JITCompiler::addressFor(
- m_jit.argumentsRegisterFor(node.codeOrigin)));
+ m_jit.argumentsRegisterFor(node->codeOrigin)));
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
m_jit.move(
- Imm64(JSValue::encode(jsNumber(node.codeOrigin.inlineCallFrame->arguments.size() - 1))),
+ Imm64(JSValue::encode(jsNumber(node->codeOrigin.inlineCallFrame->arguments.size() - 1))),
resultGPR);
} else {
m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR);
@@ -4702,40 +4561,40 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(
slowPathCall(
created, this, operationGetArgumentsLength, resultGPR,
- m_jit.argumentsRegisterFor(node.codeOrigin)));
+ m_jit.argumentsRegisterFor(node->codeOrigin)));
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, node);
break;
}
case GetMyArgumentByVal: {
- SpeculateStrictInt32Operand index(this, node.child1());
+ SpeculateStrictInt32Operand index(this, node->child1());
GPRTemporary result(this);
GPRReg indexGPR = index.gpr();
GPRReg resultGPR = result.gpr();
if (!isEmptySpeculation(
m_state.variables().operand(
- m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type)) {
+ m_jit.graph().argumentsRegisterFor(node->codeOrigin)).m_type)) {
speculationCheck(
- ArgumentsEscaped, JSValueRegs(), NoNode,
+ ArgumentsEscaped, JSValueRegs(), 0,
m_jit.branchTest64(
JITCompiler::NonZero,
JITCompiler::addressFor(
- m_jit.argumentsRegisterFor(node.codeOrigin))));
+ m_jit.argumentsRegisterFor(node->codeOrigin))));
}
m_jit.add32(TrustedImm32(1), indexGPR, resultGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::AboveOrEqual,
resultGPR,
- Imm32(node.codeOrigin.inlineCallFrame->arguments.size())));
+ Imm32(node->codeOrigin.inlineCallFrame->arguments.size())));
} else {
speculationCheck(
- Uncountable, JSValueRegs(), NoNode,
+ Uncountable, JSValueRegs(), 0,
m_jit.branch32(
JITCompiler::AboveOrEqual,
resultGPR,
@@ -4744,11 +4603,11 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::JumpList slowArgument;
JITCompiler::JumpList slowArgumentOutOfBounds;
- if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node->codeOrigin)->slowArguments()) {
slowArgumentOutOfBounds.append(
m_jit.branch32(
JITCompiler::AboveOrEqual, indexGPR,
- Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+ Imm32(m_jit.symbolTableFor(node->codeOrigin)->parameterCount())));
COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
m_jit.move(ImmPtr(slowArguments), resultGPR);
@@ -4760,7 +4619,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.signExtend32ToPtr(resultGPR, resultGPR);
m_jit.load64(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node.codeOrigin)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node->codeOrigin)),
resultGPR);
slowArgument.append(m_jit.jump());
}
@@ -4771,16 +4630,16 @@ void SpeculativeJIT::compile(Node& node)
m_jit.load64(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node->codeOrigin)),
resultGPR);
slowArgument.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, node);
break;
}
case GetMyArgumentByValSafe: {
- SpeculateStrictInt32Operand index(this, node.child1());
+ SpeculateStrictInt32Operand index(this, node->child1());
GPRTemporary result(this);
GPRReg indexGPR = index.gpr();
GPRReg resultGPR = result.gpr();
@@ -4790,15 +4649,15 @@ void SpeculativeJIT::compile(Node& node)
m_jit.branchTest64(
JITCompiler::NonZero,
JITCompiler::addressFor(
- m_jit.argumentsRegisterFor(node.codeOrigin))));
+ m_jit.argumentsRegisterFor(node->codeOrigin))));
m_jit.add32(TrustedImm32(1), indexGPR, resultGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
slowPath.append(
m_jit.branch32(
JITCompiler::AboveOrEqual,
resultGPR,
- Imm32(node.codeOrigin.inlineCallFrame->arguments.size())));
+ Imm32(node->codeOrigin.inlineCallFrame->arguments.size())));
} else {
slowPath.append(
m_jit.branch32(
@@ -4809,11 +4668,11 @@ void SpeculativeJIT::compile(Node& node)
JITCompiler::JumpList slowArgument;
JITCompiler::JumpList slowArgumentOutOfBounds;
- if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node.codeOrigin)->slowArguments()) {
+ if (const SlowArgument* slowArguments = m_jit.symbolTableFor(node->codeOrigin)->slowArguments()) {
slowArgumentOutOfBounds.append(
m_jit.branch32(
JITCompiler::AboveOrEqual, indexGPR,
- Imm32(m_jit.symbolTableFor(node.codeOrigin)->parameterCount())));
+ Imm32(m_jit.symbolTableFor(node->codeOrigin)->parameterCount())));
COMPILE_ASSERT(sizeof(SlowArgument) == 8, SlowArgument_size_is_eight_bytes);
m_jit.move(ImmPtr(slowArguments), resultGPR);
@@ -4825,7 +4684,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.signExtend32ToPtr(resultGPR, resultGPR);
m_jit.load64(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node.codeOrigin)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfLocals(node->codeOrigin)),
resultGPR);
slowArgument.append(m_jit.jump());
}
@@ -4836,40 +4695,40 @@ void SpeculativeJIT::compile(Node& node)
m_jit.load64(
JITCompiler::BaseIndex(
- GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node.codeOrigin)),
+ GPRInfo::callFrameRegister, resultGPR, JITCompiler::TimesEight, m_jit.offsetOfArgumentsIncludingThis(node->codeOrigin)),
resultGPR);
- if (node.codeOrigin.inlineCallFrame) {
+ if (node->codeOrigin.inlineCallFrame) {
addSlowPathGenerator(
slowPathCall(
slowPath, this, operationGetInlinedArgumentByVal, resultGPR,
- m_jit.argumentsRegisterFor(node.codeOrigin),
- node.codeOrigin.inlineCallFrame,
+ m_jit.argumentsRegisterFor(node->codeOrigin),
+ node->codeOrigin.inlineCallFrame,
indexGPR));
} else {
addSlowPathGenerator(
slowPathCall(
slowPath, this, operationGetArgumentByVal, resultGPR,
- m_jit.argumentsRegisterFor(node.codeOrigin),
+ m_jit.argumentsRegisterFor(node->codeOrigin),
indexGPR));
}
slowArgument.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, node);
break;
}
case CheckArgumentsNotCreated: {
ASSERT(!isEmptySpeculation(
m_state.variables().operand(
- m_jit.graph().argumentsRegisterFor(node.codeOrigin)).m_type));
+ m_jit.graph().argumentsRegisterFor(node->codeOrigin)).m_type));
speculationCheck(
- ArgumentsEscaped, JSValueRegs(), NoNode,
+ ArgumentsEscaped, JSValueRegs(), 0,
m_jit.branchTest64(
JITCompiler::NonZero,
JITCompiler::addressFor(
- m_jit.argumentsRegisterFor(node.codeOrigin))));
- noResult(m_compileIndex);
+ m_jit.argumentsRegisterFor(node->codeOrigin))));
+ noResult(node);
break;
}
@@ -4878,7 +4737,7 @@ void SpeculativeJIT::compile(Node& node)
break;
case NewFunction: {
- JSValueOperand value(this, node.child1());
+ JSValueOperand value(this, node->child1());
GPRTemporary result(this, value);
GPRReg valueGPR = value.gpr();
@@ -4891,15 +4750,19 @@ void SpeculativeJIT::compile(Node& node)
addSlowPathGenerator(
slowPathCall(
notCreated, this, operationNewFunction,
- resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex())));
+ resultGPR, m_jit.codeBlock()->functionDecl(node->functionDeclIndex())));
- cellResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, node);
break;
}
case NewFunctionExpression:
compileNewFunctionExpression(node);
break;
+
+ case CountExecution:
+ m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node->executionCounter()->address()));
+ break;
case GarbageValue:
// We should never get to the point of code emission for a GarbageValue
@@ -4907,30 +4770,46 @@ void SpeculativeJIT::compile(Node& node)
break;
case ForceOSRExit: {
- terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
+ terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
break;
}
+ case CheckWatchdogTimer:
+ speculationCheck(
+ WatchdogTimerFired, JSValueRegs(), 0,
+ m_jit.branchTest8(
+ JITCompiler::NonZero,
+ JITCompiler::AbsoluteAddress(m_jit.vm()->watchdog.timerDidFireAddress())));
+ break;
+
case Phantom:
+ DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
+ noResult(node);
+ break;
+
+ case PhantomLocal:
// This is a no-op.
- noResult(m_compileIndex);
+ noResult(node);
break;
- case InlineStart:
case Nop:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
case LastNodeType:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
+#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
+ m_jit.clearRegisterAllocationOffsets();
+#endif
+
if (!m_compileOkay)
return;
- if (node.hasResult() && node.mustGenerate())
- use(m_compileIndex);
+ if (node->hasResult() && node->mustGenerate())
+ use(node);
}
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h b/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
index 626a11f0b..fb5dfdaa6 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -307,13 +307,15 @@ public:
out.print("[");
if (m_structure)
- out.print(RawPointer(m_structure));
+ out.print(RawPointer(m_structure), "(", m_structure->classInfo()->className, ")");
out.print("]");
}
private:
static Structure* topValue() { return reinterpret_cast<Structure*>(1); }
+ // NB. This must have a trivial destructor.
+
// This can only remember one structure at a time.
Structure* m_structure;
};
diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
index 4ee723d84..e69de29bb 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DFGStructureCheckHoistingPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlock.h"
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include <wtf/HashMap.h>
-
-namespace JSC { namespace DFG {
-
-enum CheckBallot { VoteOther, VoteStructureCheck };
-
-class StructureCheckHoistingPhase : public Phase {
-public:
- StructureCheckHoistingPhase(Graph& graph)
- : Phase(graph, "structure check hoisting")
- {
- }
-
- bool run()
- {
- for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
- VariableAccessData* variable = &m_graph.m_variableAccessData[i];
- if (!variable->isRoot())
- continue;
- variable->clearVotes();
- }
-
- // Identify the set of variables that are always subject to the same structure
- // checks. For now, only consider monomorphic structure checks (one structure).
-
- for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
- BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- if (!block)
- continue;
- for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
- case CheckStructure:
- case StructureTransitionWatchpoint: {
- Node& child = m_graph[node.child1()];
- if (child.op() != GetLocal)
- break;
- VariableAccessData* variable = child.variableAccessData();
- variable->vote(VoteStructureCheck);
- if (variable->isCaptured() || variable->structureCheckHoistingFailed())
- break;
- if (!isCellSpeculation(variable->prediction()))
- break;
- noticeStructureCheck(variable, node.structureSet());
- break;
- }
-
- case ForwardCheckStructure:
- case ForwardStructureTransitionWatchpoint:
- // We currently rely on the fact that we're the only ones who would
- // insert this node.
- ASSERT_NOT_REACHED();
- break;
-
- case GetByOffset:
- case PutByOffset:
- case PutStructure:
- case AllocatePropertyStorage:
- case ReallocatePropertyStorage:
- case GetButterfly:
- case GetByVal:
- case PutByVal:
- case PutByValAlias:
- case GetArrayLength:
- case CheckArray:
- case GetIndexedPropertyStorage:
- case Phantom:
- // Don't count these uses.
- break;
-
- case SetLocal: {
- // Find all uses of the source of the SetLocal. If any of them are a
- // kind of CheckStructure, then we should notice them to ensure that
- // we're not hoisting a check that would contravene checks that are
- // already being performed.
- VariableAccessData* variable = node.variableAccessData();
- if (variable->isCaptured() || variable->structureCheckHoistingFailed())
- break;
- if (!isCellSpeculation(variable->prediction()))
- break;
- NodeIndex source = node.child1().index();
- for (unsigned subIndexInBlock = 0; subIndexInBlock < block->size(); ++subIndexInBlock) {
- NodeIndex subNodeIndex = block->at(subIndexInBlock);
- Node& subNode = m_graph[subNodeIndex];
- if (!subNode.shouldGenerate())
- continue;
- switch (subNode.op()) {
- case CheckStructure: {
- if (subNode.child1().index() != source)
- break;
-
- noticeStructureCheck(variable, subNode.structureSet());
- break;
- }
- case StructureTransitionWatchpoint: {
- if (subNode.child1().index() != source)
- break;
-
- noticeStructureCheck(variable, subNode.structure());
- break;
- }
- default:
- break;
- }
- }
-
- m_graph.vote(node, VoteOther);
- break;
- }
- case GarbageValue:
- break;
-
- default:
- m_graph.vote(node, VoteOther);
- break;
- }
- }
- }
-
- // Disable structure hoisting on variables that appear to mostly be used in
- // contexts where it doesn't make sense.
-
- for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
- VariableAccessData* variable = &m_graph.m_variableAccessData[i];
- if (!variable->isRoot())
- continue;
- if (variable->voteRatio() >= Options::structureCheckVoteRatioForHoisting())
- continue;
- HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
- if (iter == m_map.end())
- continue;
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Zeroing the structure to hoist for %s because the ratio is %lf.\n",
- m_graph.nameOfVariableAccessData(variable), variable->voteRatio());
-#endif
- iter->value.m_structure = 0;
- }
-
- // Disable structure check hoisting for variables that cross the OSR entry that
- // we're currently taking, and where the value currently does not have the
- // structure we want.
-
- for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
- BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- if (!block)
- continue;
- ASSERT(block->isReachable);
- if (!block->isOSRTarget)
- continue;
- if (block->bytecodeBegin != m_graph.m_osrEntryBytecodeIndex)
- continue;
- for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) {
- int operand = m_graph.m_mustHandleValues.operandForIndex(i);
- NodeIndex nodeIndex = block->variablesAtHead.operand(operand);
- if (nodeIndex == NoNode)
- continue;
- VariableAccessData* variable = m_graph[nodeIndex].variableAccessData();
- HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
- if (iter == m_map.end())
- continue;
- if (!iter->value.m_structure)
- continue;
- JSValue value = m_graph.m_mustHandleValues[i];
- if (!value || !value.isCell()) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Zeroing the structure to hoist for %s because the OSR entry value is not a cell: %s.\n",
- m_graph.nameOfVariableAccessData(variable), value);
-#endif
- iter->value.m_structure = 0;
- continue;
- }
- if (value.asCell()->structure() != iter->value.m_structure) {
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Zeroing the structure to hoist for %s because the OSR entry value has structure %p and we wanted %p.\n",
- m_graph.nameOfVariableAccessData(variable), value.asCell()->structure(), iter->value.m_structure);
-#endif
- iter->value.m_structure = 0;
- continue;
- }
- }
- }
-
- bool changed = false;
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- for (HashMap<VariableAccessData*, CheckData>::iterator it = m_map.begin();
- it != m_map.end(); ++it) {
- if (!it->value.m_structure) {
- dataLogF("Not hoisting checks for %s because of heuristics.\n", m_graph.nameOfVariableAccessData(it->key));
- continue;
- }
- dataLogF("Hoisting checks for %s\n", m_graph.nameOfVariableAccessData(it->key));
- }
-#endif // DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
-
- // Place CheckStructure's at SetLocal sites.
-
- InsertionSet<NodeIndex> insertionSet;
- for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
- BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- if (!block)
- continue;
- for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- // Be careful not to use 'node' after appending to the graph. In those switch
- // cases where we need to append, we first carefully extract everything we need
- // from the node, before doing any appending.
- if (!node.shouldGenerate())
- continue;
- switch (node.op()) {
- case SetArgument: {
- ASSERT(!blockIndex);
- // Insert a GetLocal and a CheckStructure immediately following this
- // SetArgument, if the variable was a candidate for structure hoisting.
- // If the basic block previously only had the SetArgument as its
- // variable-at-tail, then replace it with this GetLocal.
- VariableAccessData* variable = node.variableAccessData();
- HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
- if (iter == m_map.end())
- break;
- if (!iter->value.m_structure)
- break;
-
- node.ref();
-
- CodeOrigin codeOrigin = node.codeOrigin;
-
- Node getLocal(GetLocal, codeOrigin, OpInfo(variable), nodeIndex);
- getLocal.predict(variable->prediction());
- getLocal.ref();
- NodeIndex getLocalIndex = m_graph.size();
- m_graph.append(getLocal);
- insertionSet.append(indexInBlock + 1, getLocalIndex);
-
- Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)), getLocalIndex);
- checkStructure.ref();
- NodeIndex checkStructureIndex = m_graph.size();
- m_graph.append(checkStructure);
- insertionSet.append(indexInBlock + 1, checkStructureIndex);
-
- if (block->variablesAtTail.operand(variable->local()) == nodeIndex)
- block->variablesAtTail.operand(variable->local()) = getLocalIndex;
-
- m_graph.substituteGetLocal(*block, indexInBlock, variable, getLocalIndex);
-
- changed = true;
- break;
- }
-
- case SetLocal: {
- VariableAccessData* variable = node.variableAccessData();
- HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
- if (iter == m_map.end())
- break;
- if (!iter->value.m_structure)
- break;
-
- // First insert a dead SetLocal to tell OSR that the child's value should
- // be dropped into this bytecode variable if the CheckStructure decides
- // to exit.
-
- CodeOrigin codeOrigin = node.codeOrigin;
- NodeIndex child1 = node.child1().index();
-
- Node setLocal(SetLocal, codeOrigin, OpInfo(variable), child1);
- NodeIndex setLocalIndex = m_graph.size();
- m_graph.append(setLocal);
- insertionSet.append(indexInBlock, setLocalIndex);
- m_graph[child1].ref();
- // Use a ForwardCheckStructure to indicate that we should exit to the
- // next bytecode instruction rather than reexecuting the current one.
- Node checkStructure(ForwardCheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)), child1);
- checkStructure.ref();
- NodeIndex checkStructureIndex = m_graph.size();
- m_graph.append(checkStructure);
- insertionSet.append(indexInBlock, checkStructureIndex);
- changed = true;
- break;
- }
-
- default:
- break;
- }
- }
- insertionSet.execute(*block);
- }
-
- return changed;
- }
-
-private:
- void noticeStructureCheck(VariableAccessData* variable, Structure* structure)
- {
- HashMap<VariableAccessData*, CheckData>::AddResult result =
- m_map.add(variable, CheckData(structure));
- if (result.isNewEntry)
- return;
- if (result.iterator->value.m_structure == structure)
- return;
- result.iterator->value.m_structure = 0;
- }
-
- void noticeStructureCheck(VariableAccessData* variable, const StructureSet& set)
- {
- if (set.size() != 1) {
- noticeStructureCheck(variable, 0);
- return;
- }
- noticeStructureCheck(variable, set.singletonStructure());
- }
-
- struct CheckData {
- Structure* m_structure;
-
- CheckData()
- : m_structure(0)
- {
- }
-
- CheckData(Structure* structure)
- : m_structure(structure)
- {
- }
- };
-
- HashMap<VariableAccessData*, CheckData> m_map;
-};
-
-bool performStructureCheckHoisting(Graph& graph)
-{
- SamplingRegion samplingRegion("DFG Structure Check Hoisting Phase");
- return runPhase<StructureCheckHoistingPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-
diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h
index 1e6462a92..e69de29bb 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DFGStructureCheckHoistingPhase_h
-#define DFGStructureCheckHoistingPhase_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(DFG_JIT)
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// Hoists CheckStructure on variables to assignments to those variables, if either of
-// the following is true:
-// A) The structure's transition watchpoint set is valid.
-// B) The span of code within which the variable is live has no effects that might
-// clobber the structure.
-
-bool performStructureCheckHoisting(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGStructureCheckHoistingPhase_h
-
diff --git a/Source/JavaScriptCore/dfg/DFGThunks.cpp b/Source/JavaScriptCore/dfg/DFGThunks.cpp
index ac0b45f60..66b2ce9a0 100644
--- a/Source/JavaScriptCore/dfg/DFGThunks.cpp
+++ b/Source/JavaScriptCore/dfg/DFGThunks.cpp
@@ -36,12 +36,12 @@
namespace JSC { namespace DFG {
-MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef osrExitGenerationThunkGenerator(VM* vm)
{
MacroAssembler jit;
size_t scratchSize = sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters);
- ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(scratchSize);
+ ScratchBuffer* scratchBuffer = vm->scratchBufferForSize(scratchSize);
EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer());
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
@@ -84,9 +84,9 @@ MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData* globalData)
#endif
}
- jit.jump(MacroAssembler::AbsoluteAddress(&globalData->osrExitJumpDestination));
+ jit.jump(MacroAssembler::AbsoluteAddress(&vm->osrExitJumpDestination));
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
patchBuffer.link(functionCall, compileOSRExit);
@@ -108,9 +108,9 @@ inline void emitPointerValidation(CCallHelpers& jit, GPRReg pointerGPR)
#endif
}
-MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM* vm)
{
- CCallHelpers jit(globalData);
+ CCallHelpers jit(vm);
// We will jump to here if the JIT code thinks it's making a call, but the
// linking helper (C++ code) decided to throw an exception instead. We will
@@ -137,12 +137,12 @@ MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(JSGlobalData* glob
emitPointerValidation(jit, GPRInfo::returnValueGPR2);
jit.jump(GPRInfo::returnValueGPR2);
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(patchBuffer, ("DFG throw exception from call slow path thunk"));
}
static void slowPathFor(
- CCallHelpers& jit, JSGlobalData* globalData, P_DFGOperation_E slowPathFunction)
+ CCallHelpers& jit, VM* vm, P_DFGOperation_E slowPathFunction)
{
jit.preserveReturnAddressAfterCall(GPRInfo::nonArgGPR2);
emitPointerValidation(jit, GPRInfo::nonArgGPR2);
@@ -151,7 +151,7 @@ static void slowPathFor(
CCallHelpers::Address(
GPRInfo::callFrameRegister,
static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ReturnPC));
- jit.storePtr(GPRInfo::callFrameRegister, &globalData->topCallFrame);
+ jit.storePtr(GPRInfo::callFrameRegister, &vm->topCallFrame);
#if USE(JSVALUE64)
jit.poke64(GPRInfo::nonPreservedNonReturnGPR, JITSTACKFRAME_ARGS_INDEX);
#else
@@ -183,7 +183,7 @@ static void slowPathFor(
}
static MacroAssemblerCodeRef linkForThunkGenerator(
- JSGlobalData* globalData, CodeSpecializationKind kind)
+ VM* vm, CodeSpecializationKind kind)
{
// The return address is on the stack or in the link register. We will hence
// save the return address to the call frame while we make a C++ function call
@@ -193,46 +193,46 @@ static MacroAssemblerCodeRef linkForThunkGenerator(
// and all other registers to be available for use. We use JITStackFrame::args
// to save important information across calls.
- CCallHelpers jit(globalData);
+ CCallHelpers jit(vm);
- slowPathFor(jit, globalData, kind == CodeForCall ? operationLinkCall : operationLinkConstruct);
+ slowPathFor(jit, vm, kind == CodeForCall ? operationLinkCall : operationLinkConstruct);
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(
patchBuffer,
("DFG link %s slow path thunk", kind == CodeForCall ? "call" : "construct"));
}
-MacroAssemblerCodeRef linkCallThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef linkCallThunkGenerator(VM* vm)
{
- return linkForThunkGenerator(globalData, CodeForCall);
+ return linkForThunkGenerator(vm, CodeForCall);
}
-MacroAssemblerCodeRef linkConstructThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef linkConstructThunkGenerator(VM* vm)
{
- return linkForThunkGenerator(globalData, CodeForConstruct);
+ return linkForThunkGenerator(vm, CodeForConstruct);
}
// For closure optimizations, we only include calls, since if you're using closures for
// object construction then you're going to lose big time anyway.
-MacroAssemblerCodeRef linkClosureCallThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef linkClosureCallThunkGenerator(VM* vm)
{
- CCallHelpers jit(globalData);
+ CCallHelpers jit(vm);
- slowPathFor(jit, globalData, operationLinkClosureCall);
+ slowPathFor(jit, vm, operationLinkClosureCall);
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(patchBuffer, ("DFG link closure call slow path thunk"));
}
static MacroAssemblerCodeRef virtualForThunkGenerator(
- JSGlobalData* globalData, CodeSpecializationKind kind)
+ VM* vm, CodeSpecializationKind kind)
{
// The return address is on the stack, or in the link register. We will hence
// jump to the callee, or save the return address to the call frame while we
// make a C++ function call to the appropriate DFG operation.
- CCallHelpers jit(globalData);
+ CCallHelpers jit(vm);
CCallHelpers::JumpList slowCase;
@@ -307,22 +307,22 @@ static MacroAssemblerCodeRef virtualForThunkGenerator(
// Here we don't know anything, so revert to the full slow path.
- slowPathFor(jit, globalData, kind == CodeForCall ? operationVirtualCall : operationVirtualConstruct);
+ slowPathFor(jit, vm, kind == CodeForCall ? operationVirtualCall : operationVirtualConstruct);
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(
patchBuffer,
("DFG virtual %s slow path thunk", kind == CodeForCall ? "call" : "construct"));
}
-MacroAssemblerCodeRef virtualCallThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef virtualCallThunkGenerator(VM* vm)
{
- return virtualForThunkGenerator(globalData, CodeForCall);
+ return virtualForThunkGenerator(vm, CodeForCall);
}
-MacroAssemblerCodeRef virtualConstructThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef virtualConstructThunkGenerator(VM* vm)
{
- return virtualForThunkGenerator(globalData, CodeForConstruct);
+ return virtualForThunkGenerator(vm, CodeForConstruct);
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGThunks.h b/Source/JavaScriptCore/dfg/DFGThunks.h
index c97e3bfb6..ac869fa77 100644
--- a/Source/JavaScriptCore/dfg/DFGThunks.h
+++ b/Source/JavaScriptCore/dfg/DFGThunks.h
@@ -34,21 +34,21 @@
namespace JSC {
-class JSGlobalData;
+class VM;
namespace DFG {
-MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData*);
+MacroAssemblerCodeRef osrExitGenerationThunkGenerator(VM*);
-MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(JSGlobalData*);
+MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(VM*);
-MacroAssemblerCodeRef linkCallThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef linkConstructThunkGenerator(JSGlobalData*);
+MacroAssemblerCodeRef linkCallThunkGenerator(VM*);
+MacroAssemblerCodeRef linkConstructThunkGenerator(VM*);
-MacroAssemblerCodeRef linkClosureCallThunkGenerator(JSGlobalData*);
+MacroAssemblerCodeRef linkClosureCallThunkGenerator(VM*);
-MacroAssemblerCodeRef virtualCallThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef virtualConstructThunkGenerator(JSGlobalData*);
+MacroAssemblerCodeRef virtualCallThunkGenerator(VM*);
+MacroAssemblerCodeRef virtualConstructThunkGenerator(VM*);
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp
new file mode 100644
index 000000000..8756c831b
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp
@@ -0,0 +1,392 @@
+/*
+ * 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 "DFGTypeCheckHoistingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "Operations.h"
+#include <wtf/HashMap.h>
+
+namespace JSC { namespace DFG {
+
+enum CheckBallot { VoteOther, VoteStructureCheck };
+
+class TypeCheckHoistingPhase : public Phase {
+public:
+ TypeCheckHoistingPhase(Graph& graph)
+ : Phase(graph, "structure check hoisting")
+ {
+ }
+
+ bool run()
+ {
+ ASSERT(m_graph.m_form == ThreadedCPS);
+
+ for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
+ VariableAccessData* variable = &m_graph.m_variableAccessData[i];
+ if (!variable->isRoot())
+ continue;
+ variable->clearVotes();
+ }
+
+ // Identify the set of variables that are always subject to the same structure
+ // checks. For now, only consider monomorphic structure checks (one structure).
+
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ Node* node = block->at(indexInBlock);
+ switch (node->op()) {
+ case CheckStructure:
+ case StructureTransitionWatchpoint: {
+ Node* child = node->child1().node();
+ if (child->op() != GetLocal)
+ break;
+ VariableAccessData* variable = child->variableAccessData();
+ variable->vote(VoteStructureCheck);
+ if (!shouldConsiderForHoisting(variable))
+ break;
+ noticeStructureCheck(variable, node->structureSet());
+ break;
+ }
+
+ case ForwardCheckStructure:
+ case ForwardStructureTransitionWatchpoint:
+ // We currently rely on the fact that we're the only ones who would
+ // insert this node.
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
+ case GetByOffset:
+ case PutByOffset:
+ case PutStructure:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
+ case GetButterfly:
+ case GetByVal:
+ case PutByVal:
+ case PutByValAlias:
+ case GetArrayLength:
+ case CheckArray:
+ case GetIndexedPropertyStorage:
+ case Phantom:
+ // Don't count these uses.
+ break;
+
+ case ArrayifyToStructure:
+ case Arrayify:
+ if (node->arrayMode().conversion() == Array::RageConvert) {
+ // Rage conversion changes structures. We should avoid tying to do
+ // any kind of hoisting when rage conversion is in play.
+ Node* child = node->child1().node();
+ if (child->op() != GetLocal)
+ break;
+ VariableAccessData* variable = child->variableAccessData();
+ variable->vote(VoteOther);
+ if (!shouldConsiderForHoisting(variable))
+ break;
+ noticeStructureCheck(variable, 0);
+ }
+ break;
+
+ case SetLocal: {
+ // Find all uses of the source of the SetLocal. If any of them are a
+ // kind of CheckStructure, then we should notice them to ensure that
+ // we're not hoisting a check that would contravene checks that are
+ // already being performed.
+ VariableAccessData* variable = node->variableAccessData();
+ if (!shouldConsiderForHoisting(variable))
+ break;
+ Node* source = node->child1().node();
+ for (unsigned subIndexInBlock = 0; subIndexInBlock < block->size(); ++subIndexInBlock) {
+ Node* subNode = block->at(subIndexInBlock);
+ switch (subNode->op()) {
+ case CheckStructure: {
+ if (subNode->child1() != source)
+ break;
+
+ noticeStructureCheck(variable, subNode->structureSet());
+ break;
+ }
+ case StructureTransitionWatchpoint: {
+ if (subNode->child1() != source)
+ break;
+
+ noticeStructureCheck(variable, subNode->structure());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ m_graph.voteChildren(node, VoteOther);
+ break;
+ }
+ case GarbageValue:
+ break;
+
+ default:
+ m_graph.voteChildren(node, VoteOther);
+ break;
+ }
+ }
+ }
+
+ // Disable structure hoisting on variables that appear to mostly be used in
+ // contexts where it doesn't make sense.
+
+ for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
+ VariableAccessData* variable = &m_graph.m_variableAccessData[i];
+ if (!variable->isRoot())
+ continue;
+ if (variable->voteRatio() >= Options::structureCheckVoteRatioForHoisting())
+ continue;
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ continue;
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(
+ "Zeroing the structure to hoist for ", VariableAccessDataDump(m_graph, variable),
+ " because the ratio is ", variable->voteRatio(), ".\n");
+#endif
+ iter->value.m_structure = 0;
+ }
+
+ // Disable structure check hoisting for variables that cross the OSR entry that
+ // we're currently taking, and where the value currently does not have the
+ // structure we want.
+
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(block->isReachable);
+ if (!block->isOSRTarget)
+ continue;
+ if (block->bytecodeBegin != m_graph.m_osrEntryBytecodeIndex)
+ continue;
+ for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) {
+ int operand = m_graph.m_mustHandleValues.operandForIndex(i);
+ Node* node = block->variablesAtHead.operand(operand);
+ if (!node)
+ continue;
+ VariableAccessData* variable = node->variableAccessData();
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ continue;
+ if (!iter->value.m_structure)
+ continue;
+ JSValue value = m_graph.m_mustHandleValues[i];
+ if (!value || !value.isCell()) {
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(
+ "Zeroing the structure to hoist for ", VariableAccessDataDump(m_graph, variable),
+ " because the OSR entry value is not a cell: ", value, ".\n");
+#endif
+ iter->value.m_structure = 0;
+ continue;
+ }
+ if (value.asCell()->structure() != iter->value.m_structure) {
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(
+ "Zeroing the structure to hoist for ", VariableAccessDataDump(m_graph, variable),
+ " because the OSR entry value has structure ",
+ RawPointer(value.asCell()->structure()), " and we wanted ",
+ RawPointer(iter->value.m_structure), ".\n");
+#endif
+ iter->value.m_structure = 0;
+ continue;
+ }
+ }
+ }
+
+ bool changed = false;
+
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ for (HashMap<VariableAccessData*, CheckData>::iterator it = m_map.begin();
+ it != m_map.end(); ++it) {
+ if (!it->value.m_structure) {
+ dataLog(
+ "Not hoisting checks for ", VariableAccessDataDump(m_graph, it->key),
+ " because of heuristics.\n");
+ continue;
+ }
+ dataLog("Hoisting checks for ", VariableAccessDataDump(m_graph, it->key), "\n");
+ }
+#endif // DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+
+ // Place CheckStructure's at SetLocal sites.
+
+ InsertionSet insertionSet(m_graph);
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ Node* node = block->at(indexInBlock);
+ // Be careful not to use 'node' after appending to the graph. In those switch
+ // cases where we need to append, we first carefully extract everything we need
+ // from the node, before doing any appending.
+ switch (node->op()) {
+ case SetArgument: {
+ ASSERT(!blockIndex);
+ // Insert a GetLocal and a CheckStructure immediately following this
+ // SetArgument, if the variable was a candidate for structure hoisting.
+ // If the basic block previously only had the SetArgument as its
+ // variable-at-tail, then replace it with this GetLocal.
+ VariableAccessData* variable = node->variableAccessData();
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ break;
+ if (!iter->value.m_structure)
+ break;
+
+ CodeOrigin codeOrigin = node->codeOrigin;
+
+ Node* getLocal = insertionSet.insertNode(
+ indexInBlock + 1, variable->prediction(), GetLocal, codeOrigin,
+ OpInfo(variable), Edge(node));
+ insertionSet.insertNode(
+ indexInBlock + 1, SpecNone, CheckStructure, codeOrigin,
+ OpInfo(m_graph.addStructureSet(iter->value.m_structure)),
+ Edge(getLocal, CellUse));
+
+ if (block->variablesAtTail.operand(variable->local()) == node)
+ block->variablesAtTail.operand(variable->local()) = getLocal;
+
+ m_graph.substituteGetLocal(*block, indexInBlock, variable, getLocal);
+
+ changed = true;
+ break;
+ }
+
+ case SetLocal: {
+ VariableAccessData* variable = node->variableAccessData();
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ break;
+ if (!iter->value.m_structure)
+ break;
+
+ // First insert a dead SetLocal to tell OSR that the child's value should
+ // be dropped into this bytecode variable if the CheckStructure decides
+ // to exit.
+
+ CodeOrigin codeOrigin = node->codeOrigin;
+ Edge child1 = node->child1();
+
+ insertionSet.insertNode(
+ indexInBlock, SpecNone, SetLocal, codeOrigin, OpInfo(variable), child1);
+
+ // Use a ForwardCheckStructure to indicate that we should exit to the
+ // next bytecode instruction rather than reexecuting the current one.
+ insertionSet.insertNode(
+ indexInBlock, SpecNone, ForwardCheckStructure, codeOrigin,
+ OpInfo(m_graph.addStructureSet(iter->value.m_structure)),
+ Edge(child1.node(), CellUse));
+ changed = true;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ insertionSet.execute(block);
+ }
+
+ return changed;
+ }
+
+private:
+ bool shouldConsiderForHoisting(VariableAccessData* variable)
+ {
+ if (!variable->shouldUnboxIfPossible())
+ return false;
+ if (variable->structureCheckHoistingFailed())
+ return false;
+ if (!isCellSpeculation(variable->prediction()))
+ return false;
+ return true;
+ }
+
+ void noticeStructureCheck(VariableAccessData* variable, Structure* structure)
+ {
+ HashMap<VariableAccessData*, CheckData>::AddResult result =
+ m_map.add(variable, CheckData(structure));
+ if (result.isNewEntry)
+ return;
+ if (result.iterator->value.m_structure == structure)
+ return;
+ result.iterator->value.m_structure = 0;
+ }
+
+ void noticeStructureCheck(VariableAccessData* variable, const StructureSet& set)
+ {
+ if (set.size() != 1) {
+ noticeStructureCheck(variable, 0);
+ return;
+ }
+ noticeStructureCheck(variable, set.singletonStructure());
+ }
+
+ struct CheckData {
+ Structure* m_structure;
+
+ CheckData()
+ : m_structure(0)
+ {
+ }
+
+ CheckData(Structure* structure)
+ : m_structure(structure)
+ {
+ }
+ };
+
+ HashMap<VariableAccessData*, CheckData> m_map;
+};
+
+bool performTypeCheckHoisting(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Type Check Hoisting Phase");
+ return runPhase<TypeCheckHoistingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+
diff --git a/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.h b/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.h
new file mode 100644
index 000000000..97adaf2e7
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.h
@@ -0,0 +1,50 @@
+/*
+ * 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 DFGTypeCheckHoistingPhase_h
+#define DFGTypeCheckHoistingPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Hoists CheckStructure on variables to assignments to those variables, if either of
+// the following is true:
+// A) The structure's transition watchpoint set is valid.
+// B) The span of code within which the variable is live has no effects that might
+// clobber the structure.
+
+bool performTypeCheckHoisting(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGTypeCheckHoistingPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
new file mode 100644
index 000000000..9109f0930
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGUnificationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+
+namespace JSC { namespace DFG {
+
+class UnificationPhase : public Phase {
+public:
+ UnificationPhase(Graph& graph)
+ : Phase(graph, "unification")
+ {
+ }
+
+ bool run()
+ {
+ ASSERT(m_graph.m_form == ThreadedCPS);
+ ASSERT(m_graph.m_unificationState == LocallyUnified);
+
+ // Ensure that all Phi functions are unified.
+ for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(block->isReachable);
+
+ for (unsigned phiIndex = block->phis.size(); phiIndex--;) {
+ Node* phi = block->phis[phiIndex];
+ for (unsigned childIdx = 0; childIdx < AdjacencyList::Size; ++childIdx) {
+ if (!phi->children.child(childIdx))
+ break;
+
+ phi->variableAccessData()->unify(
+ phi->children.child(childIdx)->variableAccessData());
+ }
+ }
+ }
+
+ // Ensure that all predictions are fixed up based on the unification.
+ for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
+ VariableAccessData* data = &m_graph.m_variableAccessData[i];
+ data->find()->predict(data->nonUnifiedPrediction());
+ data->find()->mergeIsCaptured(data->isCaptured());
+ data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
+ data->find()->mergeShouldNeverUnbox(data->shouldNeverUnbox());
+ data->find()->mergeIsLoadedFrom(data->isLoadedFrom());
+ }
+
+ m_graph.m_unificationState = GloballyUnified;
+ return true;
+ }
+};
+
+bool performUnification(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Unification Phase");
+ return runPhase<UnificationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGUnificationPhase.h b/Source/JavaScriptCore/dfg/DFGUnificationPhase.h
new file mode 100644
index 000000000..6713de78e
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGUnificationPhase.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGUnificationPhase_h
+#define DFGUnificationPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Unification:
+//
+// Examines all Phi functions and ensures that the variable access datas are
+// unified. This creates our "live-range split" view of variables.
+
+bool performUnification(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGUnificationPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGUseKind.cpp b/Source/JavaScriptCore/dfg/DFGUseKind.cpp
new file mode 100644
index 000000000..bfba754b7
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGUseKind.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGUseKind.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace WTF {
+
+using namespace JSC::DFG;
+
+void printInternal(PrintStream& out, UseKind useKind)
+{
+ switch (useKind) {
+ case UntypedUse:
+ out.print("Untyped");
+ break;
+ case Int32Use:
+ out.print("Int32");
+ break;
+ case KnownInt32Use:
+ out.print("KnownInt32");
+ break;
+ case RealNumberUse:
+ out.print("RealNumber");
+ break;
+ case NumberUse:
+ out.print("Number");
+ break;
+ case KnownNumberUse:
+ out.print("KnownNumber");
+ break;
+ case BooleanUse:
+ out.print("Boolean");
+ break;
+ case CellUse:
+ out.print("Cell");
+ break;
+ case KnownCellUse:
+ out.print("KnownCell");
+ break;
+ case ObjectUse:
+ out.print("Object");
+ break;
+ case ObjectOrOtherUse:
+ out.print("ObjectOrOther");
+ break;
+ case StringUse:
+ out.print("String");
+ break;
+ case KnownStringUse:
+ out.print("KnownString");
+ break;
+ case StringObjectUse:
+ out.print("StringObject");
+ break;
+ case StringOrStringObjectUse:
+ out.print("StringOrStringObject");
+ break;
+ case NotCellUse:
+ out.print("NotCell");
+ break;
+ case OtherUse:
+ out.print("Other");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGUseKind.h b/Source/JavaScriptCore/dfg/DFGUseKind.h
new file mode 100644
index 000000000..afe3d3540
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGUseKind.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGUseKind_h
+#define DFGUseKind_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "SpeculatedType.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace DFG {
+
+enum UseKind {
+ UntypedUse,
+ Int32Use,
+ KnownInt32Use,
+ RealNumberUse,
+ NumberUse,
+ KnownNumberUse,
+ BooleanUse,
+ CellUse,
+ KnownCellUse,
+ ObjectUse,
+ ObjectOrOtherUse,
+ StringUse,
+ KnownStringUse,
+ StringObjectUse,
+ StringOrStringObjectUse,
+ NotCellUse,
+ OtherUse,
+ LastUseKind // Must always be the last entry in the enum, as it is used to denote the number of enum elements.
+};
+
+ALWAYS_INLINE SpeculatedType typeFilterFor(UseKind useKind)
+{
+ switch (useKind) {
+ case UntypedUse:
+ return SpecEmptyOrTop; // TOP isn't good enough; untyped uses may use the normally unseen empty value, in the case of lazy registers.
+ case Int32Use:
+ case KnownInt32Use:
+ return SpecInt32;
+ case RealNumberUse:
+ return SpecRealNumber;
+ case NumberUse:
+ case KnownNumberUse:
+ return SpecNumber;
+ case BooleanUse:
+ return SpecBoolean;
+ case CellUse:
+ case KnownCellUse:
+ return SpecCell;
+ case ObjectUse:
+ return SpecObject;
+ case ObjectOrOtherUse:
+ return SpecObject | SpecOther;
+ case StringUse:
+ case KnownStringUse:
+ return SpecString;
+ case StringObjectUse:
+ return SpecStringObject;
+ case StringOrStringObjectUse:
+ return SpecString | SpecStringObject;
+ case NotCellUse:
+ return ~SpecCell;
+ case OtherUse:
+ return SpecOther;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return SpecTop;
+ }
+}
+
+ALWAYS_INLINE bool isNumerical(UseKind kind)
+{
+ switch (kind) {
+ case Int32Use:
+ case KnownInt32Use:
+ case RealNumberUse:
+ case NumberUse:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+void printInternal(PrintStream&, JSC::DFG::UseKind);
+
+} // namespace WTF
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGUseKind_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.cpp b/Source/JavaScriptCore/dfg/DFGValidate.cpp
index 274b544b5..6720451a1 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValidate.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,13 +28,12 @@
#if ENABLE(DFG_JIT)
+#include "CodeBlockWithJITType.h"
#include <wtf/Assertions.h>
#include <wtf/BitVector.h>
namespace JSC { namespace DFG {
-#if DFG_ENABLE(VALIDATION)
-
class Validate {
public:
Validate(Graph& graph, GraphDumpMode graphDumpMode)
@@ -59,9 +58,9 @@ public:
dataLogF("\n\n\nAt "); \
reportValidationContext context; \
dataLogF(": validation (%s = ", #left); \
- dumpData(left); \
+ dataLog(left); \
dataLogF(") == (%s = ", #right); \
- dumpData(right); \
+ dataLog(right); \
dataLogF(") (%s:%d) failed.\n", __FILE__, __LINE__); \
dumpGraphIfAppropriate(); \
WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #left " == " #right); \
@@ -76,38 +75,83 @@ public:
// NB. This code is not written for performance, since it is not intended to run
// in release builds.
+ // Validate that all local variables at the head of the root block are dead.
+ BasicBlock* root = m_graph.m_blocks[0].get();
+ for (unsigned i = 0; i < root->variablesAtHead.numberOfLocals(); ++i)
+ V_EQUAL((static_cast<VirtualRegister>(i), 0), static_cast<Node*>(0), root->variablesAtHead.local(i));
+
// Validate ref counts and uses.
- Vector<unsigned> myRefCounts;
- myRefCounts.fill(0, m_graph.size());
- BitVector acceptableNodeIndices;
+ HashMap<Node*, unsigned> myRefCounts;
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- if (!block)
+ if (!block || !block->isReachable)
continue;
- if (!block->isReachable)
+ for (size_t i = 0; i < block->numNodes(); ++i)
+ myRefCounts.add(block->node(i), 0);
+ }
+ HashSet<Node*> acceptableNodes;
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block || !block->isReachable)
continue;
for (size_t i = 0; i < block->numNodes(); ++i) {
- NodeIndex nodeIndex = block->nodeIndex(i);
- acceptableNodeIndices.set(nodeIndex);
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate())
+ Node* node = block->node(i);
+ acceptableNodes.add(node);
+ if (!node->shouldGenerate())
continue;
for (unsigned j = 0; j < m_graph.numChildren(node); ++j) {
+ // Phi children in LoadStore form are invalid.
+ if (m_graph.m_form == LoadStore && block->isPhiIndex(i))
+ continue;
+
Edge edge = m_graph.child(node, j);
if (!edge)
continue;
- myRefCounts[edge.index()]++;
+ myRefCounts.find(edge.node())->value++;
// Unless I'm a Flush, Phantom, GetLocal, or Phi, my children should hasResult().
- switch (node.op()) {
+ switch (node->op()) {
case Flush:
- case Phantom:
case GetLocal:
+ VALIDATE((node, edge), edge->hasVariableAccessData());
+ VALIDATE((node, edge), edge->variableAccessData() == node->variableAccessData());
+ break;
+ case PhantomLocal:
+ VALIDATE((node, edge), edge->hasVariableAccessData());
+ VALIDATE((node, edge), edge->variableAccessData() == node->variableAccessData());
+ VALIDATE((node, edge), edge->op() != SetLocal);
+ break;
case Phi:
+ VALIDATE((node, edge), edge->hasVariableAccessData());
+ if (m_graph.m_unificationState == LocallyUnified)
+ break;
+ VALIDATE((node, edge), edge->variableAccessData() == node->variableAccessData());
+ break;
+ case Phantom:
+ switch (m_graph.m_form) {
+ case LoadStore:
+ if (j) {
+ VALIDATE((node, edge), edge->hasResult());
+ break;
+ }
+ switch (edge->op()) {
+ case Phi:
+ case SetArgument:
+ case SetLocal:
+ break;
+ default:
+ VALIDATE((node, edge), edge->hasResult());
+ break;
+ }
+ break;
+ case ThreadedCPS:
+ VALIDATE((node, edge), edge->hasResult());
+ break;
+ }
break;
default:
- VALIDATE((nodeIndex, edge), m_graph[edge].hasResult());
+ VALIDATE((node, edge), edge->hasResult());
break;
}
}
@@ -115,54 +159,65 @@ public:
}
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- if (!block)
- continue;
- if (!block->isReachable)
+ if (!block || !block->isReachable)
continue;
- BitVector phisInThisBlock;
- BitVector nodesInThisBlock;
+ HashSet<Node*> phisInThisBlock;
+ HashSet<Node*> nodesInThisBlock;
for (size_t i = 0; i < block->numNodes(); ++i) {
- NodeIndex nodeIndex = block->nodeIndex(i);
- Node& node = m_graph[nodeIndex];
- nodesInThisBlock.set(nodeIndex);
+ Node* node = block->node(i);
+ nodesInThisBlock.add(node);
if (block->isPhiIndex(i))
- phisInThisBlock.set(nodeIndex);
- V_EQUAL((nodeIndex), myRefCounts[nodeIndex], node.adjustedRefCount());
+ phisInThisBlock.add(node);
+ if (m_graph.m_refCountState == ExactRefCount)
+ V_EQUAL((node), myRefCounts.get(node), node->adjustedRefCount());
+ else
+ V_EQUAL((node), node->refCount(), 1);
for (unsigned j = 0; j < m_graph.numChildren(node); ++j) {
Edge edge = m_graph.child(node, j);
if (!edge)
continue;
- VALIDATE((nodeIndex, edge), acceptableNodeIndices.get(edge.index()));
+ VALIDATE((node, edge), acceptableNodes.contains(edge.node()));
}
}
for (size_t i = 0; i < block->phis.size(); ++i) {
- NodeIndex nodeIndex = block->phis[i];
- Node& node = m_graph[nodeIndex];
- ASSERT(phisInThisBlock.get(nodeIndex));
- VALIDATE((nodeIndex), node.op() == Phi);
- VirtualRegister local = node.local();
+ Node* node = block->phis[i];
+ ASSERT(phisInThisBlock.contains(node));
+ VALIDATE((node), node->op() == Phi);
+ VirtualRegister local = node->local();
for (unsigned j = 0; j < m_graph.numChildren(node); ++j) {
+ // Phi children in LoadStore form are invalid.
+ if (m_graph.m_form == LoadStore && block->isPhiIndex(i))
+ continue;
+
Edge edge = m_graph.child(node, j);
if (!edge)
continue;
- VALIDATE((nodeIndex, edge),
- m_graph[edge].op() == SetLocal
- || m_graph[edge].op() == SetArgument
- || m_graph[edge].op() == Flush
- || m_graph[edge].op() == Phi);
+ VALIDATE(
+ (node, edge),
+ edge->op() == SetLocal
+ || edge->op() == SetArgument
+ || edge->op() == Flush
+ || edge->op() == Phi
+ || edge->op() == ZombieHint
+ || edge->op() == MovHint
+ || edge->op() == MovHintAndCheck);
- if (phisInThisBlock.get(edge.index()))
+ if (phisInThisBlock.contains(edge.node()))
continue;
- if (nodesInThisBlock.get(edge.index())) {
- VALIDATE((nodeIndex, edge),
- m_graph[edge].op() == SetLocal
- || m_graph[edge].op() == SetArgument
- || m_graph[edge].op() == Flush);
+ if (nodesInThisBlock.contains(edge.node())) {
+ VALIDATE(
+ (node, edge),
+ edge->op() == SetLocal
+ || edge->op() == ZombieHint
+ || edge->op() == MovHint
+ || edge->op() == MovHintAndCheck
+ || edge->op() == SetArgument
+ || edge->op() == Flush);
continue;
}
@@ -174,33 +229,40 @@ public:
BasicBlock* prevBlock = m_graph.m_blocks[block->m_predecessors[k]].get();
VALIDATE((Block, block->m_predecessors[k]), prevBlock);
VALIDATE((Block, block->m_predecessors[k]), prevBlock->isReachable);
- NodeIndex prevNodeIndex = prevBlock->variablesAtTail.operand(local);
+ Node* prevNode = prevBlock->variablesAtTail.operand(local);
// If we have a Phi that is not referring to *this* block then all predecessors
// must have that local available.
- VALIDATE((local, blockIndex, Block, block->m_predecessors[k]), prevNodeIndex != NoNode);
- Node* prevNode = &m_graph[prevNodeIndex];
- if (prevNode->op() == GetLocal) {
- prevNodeIndex = prevNode->child1().index();
- prevNode = &m_graph[prevNodeIndex];
+ VALIDATE((local, blockIndex, Block, block->m_predecessors[k]), prevNode);
+ switch (prevNode->op()) {
+ case GetLocal:
+ case Flush:
+ case PhantomLocal:
+ prevNode = prevNode->child1().node();
+ break;
+ default:
+ break;
}
- if (node.shouldGenerate()) {
- VALIDATE((local, block->m_predecessors[k], prevNodeIndex),
+ if (node->shouldGenerate()) {
+ VALIDATE((local, block->m_predecessors[k], prevNode),
prevNode->shouldGenerate());
}
- VALIDATE((local, block->m_predecessors[k], prevNodeIndex),
- prevNode->op() == SetLocal
- || prevNode->op() == SetArgument
- || prevNode->op() == Flush
- || prevNode->op() == Phi);
- if (prevNodeIndex == edge.index()) {
+ VALIDATE(
+ (local, block->m_predecessors[k], prevNode),
+ prevNode->op() == SetLocal
+ || prevNode->op() == MovHint
+ || prevNode->op() == MovHintAndCheck
+ || prevNode->op() == ZombieHint
+ || prevNode->op() == SetArgument
+ || prevNode->op() == Phi);
+ if (prevNode == edge.node()) {
found = true;
break;
}
// At this point it cannot refer into this block.
- VALIDATE((local, block->m_predecessors[k], prevNodeIndex), !prevBlock->isInBlock(edge.index()));
+ VALIDATE((local, block->m_predecessors[k], prevNode), !prevBlock->isInBlock(edge.node()));
}
- VALIDATE((nodeIndex, edge), found);
+ VALIDATE((node, edge), found);
}
}
@@ -212,49 +274,76 @@ public:
block->variablesAtHead.numberOfLocals());
for (size_t i = 0; i < block->variablesAtHead.numberOfArguments(); ++i) {
+ VALIDATE((static_cast<VirtualRegister>(argumentToOperand(i)), blockIndex), !block->variablesAtHead.argument(i) || block->variablesAtHead.argument(i)->hasVariableAccessData());
+ if (m_graph.m_form == ThreadedCPS)
+ VALIDATE((static_cast<VirtualRegister>(argumentToOperand(i)), blockIndex), !block->variablesAtTail.argument(i) || block->variablesAtTail.argument(i)->hasVariableAccessData());
+
getLocalPositions.argument(i) = notSet;
setLocalPositions.argument(i) = notSet;
}
for (size_t i = 0; i < block->variablesAtHead.numberOfLocals(); ++i) {
+ VALIDATE((static_cast<VirtualRegister>(i), blockIndex), !block->variablesAtHead.local(i) || block->variablesAtHead.local(i)->hasVariableAccessData());
+ if (m_graph.m_form == ThreadedCPS)
+ VALIDATE((static_cast<VirtualRegister>(i), blockIndex), !block->variablesAtTail.local(i) || block->variablesAtTail.local(i)->hasVariableAccessData());
+
getLocalPositions.local(i) = notSet;
setLocalPositions.local(i) = notSet;
}
for (size_t i = 0; i < block->size(); ++i) {
- NodeIndex nodeIndex = block->at(i);
- Node& node = m_graph[nodeIndex];
- ASSERT(nodesInThisBlock.get(nodeIndex));
- VALIDATE((nodeIndex), node.op() != Phi);
+ Node* node = block->at(i);
+ ASSERT(nodesInThisBlock.contains(node));
+ VALIDATE((node), node->op() != Phi);
for (unsigned j = 0; j < m_graph.numChildren(node); ++j) {
Edge edge = m_graph.child(node, j);
if (!edge)
continue;
- VALIDATE((nodeIndex, edge), nodesInThisBlock.get(nodeIndex));
+ VALIDATE((node, edge), nodesInThisBlock.contains(edge.node()));
+ switch (node->op()) {
+ case PhantomLocal:
+ case GetLocal:
+ case Flush:
+ break;
+ case Phantom:
+ if (m_graph.m_form == LoadStore && !j)
+ break;
+ default:
+ VALIDATE((node, edge), !phisInThisBlock.contains(edge.node()));
+ break;
+ }
}
- if (!node.shouldGenerate())
+ if (!node->shouldGenerate())
continue;
- switch (node.op()) {
+ switch (node->op()) {
case GetLocal:
- if (node.variableAccessData()->isCaptured())
+ if (node->variableAccessData()->isCaptured())
break;
- VALIDATE((nodeIndex, blockIndex), getLocalPositions.operand(node.local()) == notSet);
- getLocalPositions.operand(node.local()) = i;
+ // Ignore GetLocal's that we know to be dead, but that the graph
+ // doesn't yet know to be dead.
+ if (!myRefCounts.get(node))
+ break;
+ if (m_graph.m_form == ThreadedCPS)
+ VALIDATE((node, blockIndex), getLocalPositions.operand(node->local()) == notSet);
+ getLocalPositions.operand(node->local()) = i;
break;
case SetLocal:
- if (node.variableAccessData()->isCaptured())
+ if (node->variableAccessData()->isCaptured())
break;
// Only record the first SetLocal. There may be multiple SetLocals
// because of flushing.
- if (setLocalPositions.operand(node.local()) != notSet)
+ if (setLocalPositions.operand(node->local()) != notSet)
break;
- setLocalPositions.operand(node.local()) = i;
+ setLocalPositions.operand(node->local()) = i;
break;
default:
break;
}
}
+ if (m_graph.m_form == LoadStore)
+ continue;
+
for (size_t i = 0; i < block->variablesAtHead.numberOfArguments(); ++i) {
checkOperand(
blockIndex, getLocalPositions, setLocalPositions, argumentToOperand(i));
@@ -288,9 +377,9 @@ private:
getLocalPositions.operand(operand) < setLocalPositions.operand(operand));
}
- void reportValidationContext(NodeIndex nodeIndex)
+ void reportValidationContext(Node* node)
{
- dataLogF("@%u", nodeIndex);
+ dataLogF("@%u", node->index());
}
enum BlockTag { Block };
@@ -299,51 +388,51 @@ private:
dataLogF("Block #%u", blockIndex);
}
- void reportValidationContext(NodeIndex nodeIndex, Edge edge)
+ void reportValidationContext(Node* node, Edge edge)
{
- dataLogF("@%u -> %s@%u", nodeIndex, useKindToString(edge.useKind()), edge.index());
+ dataLog(node, " -> ", edge);
}
- void reportValidationContext(
- VirtualRegister local, BlockIndex sourceBlockIndex, BlockTag, BlockIndex destinationBlockIndex)
+ void reportValidationContext(VirtualRegister local, BlockIndex blockIndex)
{
- dataLogF("r%d in Block #%u -> #%u", local, sourceBlockIndex, destinationBlockIndex);
+ dataLogF("r%d in Block #%u", local, blockIndex);
}
void reportValidationContext(
- VirtualRegister local, BlockIndex sourceBlockIndex, NodeIndex prevNodeIndex)
+ VirtualRegister local, BlockIndex sourceBlockIndex, BlockTag, BlockIndex destinationBlockIndex)
{
- dataLogF("@%u for r%d in Block #%u", prevNodeIndex, local, sourceBlockIndex);
+ dataLogF("r%d in Block #%u -> #%u", local, sourceBlockIndex, destinationBlockIndex);
}
void reportValidationContext(
- NodeIndex nodeIndex, BlockIndex blockIndex)
+ VirtualRegister local, BlockIndex sourceBlockIndex, Node* prevNode)
{
- dataLogF("@%u in Block #%u", nodeIndex, blockIndex);
+ dataLogF("@%u for r%d in Block #%u", prevNode->index(), local, sourceBlockIndex);
}
void reportValidationContext(
- NodeIndex nodeIndex, NodeIndex nodeIndex2, BlockIndex blockIndex)
+ Node* node, BlockIndex blockIndex)
{
- dataLogF("@%u and @%u in Block #%u", nodeIndex, nodeIndex2, blockIndex);
+ dataLogF("@%u in Block #%u", node->index(), blockIndex);
}
void reportValidationContext(
- NodeIndex nodeIndex, BlockIndex blockIndex, NodeIndex expectedNodeIndex, Edge incomingEdge)
+ Node* node, Node* node2, BlockIndex blockIndex)
{
- dataLogF("@%u in Block #%u, searching for @%u from @%u", nodeIndex, blockIndex, expectedNodeIndex, incomingEdge.index());
+ dataLogF("@%u and @%u in Block #%u", node->index(), node2->index(), blockIndex);
}
- void dumpData(unsigned value)
+ void reportValidationContext(
+ Node* node, BlockIndex blockIndex, Node* expectedNode, Edge incomingEdge)
{
- dataLogF("%u", value);
+ dataLog(node, " in Block #", blockIndex, ", searching for ", expectedNode, " from ", incomingEdge);
}
void dumpGraphIfAppropriate()
{
if (m_graphDumpMode == DontDumpGraph)
return;
- dataLogF("Graph at time of failure:\n");
+ dataLog("At time of failure:\n");
m_graph.dump();
}
};
@@ -354,8 +443,6 @@ void validate(Graph& graph, GraphDumpMode graphDumpMode)
validationObject.validate();
}
-#endif // DFG_ENABLE(VALIDATION)
-
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.h b/Source/JavaScriptCore/dfg/DFGValidate.h
index 353c3b696..92aa293e3 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.h
+++ b/Source/JavaScriptCore/dfg/DFGValidate.h
@@ -37,11 +37,7 @@ namespace JSC { namespace DFG {
enum GraphDumpMode { DontDumpGraph, DumpGraph };
-#if DFG_ENABLE(VALIDATION)
void validate(Graph&, GraphDumpMode = DumpGraph);
-#else
-inline void validate(Graph&, GraphDumpMode = DumpGraph) { }
-#endif
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.cpp b/Source/JavaScriptCore/dfg/DFGValueSource.cpp
index d59e4842f..879aa3025 100644
--- a/Source/JavaScriptCore/dfg/DFGValueSource.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValueSource.cpp
@@ -30,35 +30,38 @@
namespace JSC { namespace DFG {
-void ValueSource::dump(FILE* out) const
+void ValueSource::dump(PrintStream& out) const
{
switch (kind()) {
case SourceNotSet:
- fprintf(out, "NotSet");
+ out.print("NotSet");
break;
case SourceIsDead:
- fprintf(out, "IsDead");
+ out.print("IsDead");
break;
case ValueInJSStack:
- fprintf(out, "InStack");
+ out.print("InStack");
break;
case Int32InJSStack:
- fprintf(out, "Int32");
+ out.print("Int32");
break;
case CellInJSStack:
- fprintf(out, "Cell");
+ out.print("Cell");
break;
case BooleanInJSStack:
- fprintf(out, "Bool");
+ out.print("Bool");
break;
case DoubleInJSStack:
- fprintf(out, "Double");
+ out.print("Double");
break;
case ArgumentsSource:
- fprintf(out, "Arguments");
+ out.print("Arguments");
break;
case HaveNode:
- fprintf(out, "Node(%d)", m_nodeIndex);
+ out.print("Node(", m_value, ")");
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.h b/Source/JavaScriptCore/dfg/DFGValueSource.h
index 8a4c66b37..362072647 100644
--- a/Source/JavaScriptCore/dfg/DFGValueSource.h
+++ b/Source/JavaScriptCore/dfg/DFGValueSource.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,6 +31,7 @@
#if ENABLE(DFG_JIT)
#include "DFGCommon.h"
+#include "DFGMinifiedID.h"
#include "DataFormat.h"
#include "SpeculatedType.h"
#include "ValueRecovery.h"
@@ -65,7 +66,7 @@ static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat)
case DataFormatArguments:
return ArgumentsSource;
default:
- ASSERT(dataFormat & DataFormatJS);
+ RELEASE_ASSERT(dataFormat & DataFormatJS);
return ValueInJSStack;
}
}
@@ -108,21 +109,21 @@ static inline bool isTriviallyRecoverable(ValueSourceKind kind)
class ValueSource {
public:
ValueSource()
- : m_nodeIndex(nodeIndexFromKind(SourceNotSet))
+ : m_value(idFromKind(SourceNotSet))
{
}
explicit ValueSource(ValueSourceKind valueSourceKind)
- : m_nodeIndex(nodeIndexFromKind(valueSourceKind))
+ : m_value(idFromKind(valueSourceKind))
{
ASSERT(kind() != SourceNotSet);
ASSERT(kind() != HaveNode);
}
- explicit ValueSource(NodeIndex nodeIndex)
- : m_nodeIndex(nodeIndex)
+ explicit ValueSource(MinifiedID id)
+ : m_value(id)
{
- ASSERT(nodeIndex != NoNode);
+ ASSERT(!!id);
ASSERT(kind() == HaveNode);
}
@@ -144,12 +145,12 @@ public:
bool isSet() const
{
- return kindFromNodeIndex(m_nodeIndex) != SourceNotSet;
+ return kindFromID(m_value) != SourceNotSet;
}
ValueSourceKind kind() const
{
- return kindFromNodeIndex(m_nodeIndex);
+ return kindFromID(m_value);
}
bool isInJSStack() const { return JSC::DFG::isInJSStack(kind()); }
@@ -186,35 +187,35 @@ public:
return ValueRecovery::argumentsThatWereNotCreated();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return ValueRecovery();
}
}
- NodeIndex nodeIndex() const
+ MinifiedID id() const
{
ASSERT(kind() == HaveNode);
- return m_nodeIndex;
+ return m_value;
}
- void dump(FILE* out) const;
+ void dump(PrintStream&) const;
private:
- static NodeIndex nodeIndexFromKind(ValueSourceKind kind)
+ static MinifiedID idFromKind(ValueSourceKind kind)
{
ASSERT(kind >= SourceNotSet && kind < HaveNode);
- return NoNode - kind;
+ return MinifiedID::fromBits(MinifiedID::invalidID() - kind);
}
- static ValueSourceKind kindFromNodeIndex(NodeIndex nodeIndex)
+ static ValueSourceKind kindFromID(MinifiedID id)
{
- unsigned kind = static_cast<unsigned>(NoNode - nodeIndex);
- if (kind >= static_cast<unsigned>(HaveNode))
+ uintptr_t kind = static_cast<uintptr_t>(MinifiedID::invalidID() - id.m_id);
+ if (kind >= static_cast<uintptr_t>(HaveNode))
return HaveNode;
return static_cast<ValueSourceKind>(kind);
}
- NodeIndex m_nodeIndex;
+ MinifiedID m_value;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
index 6d8e89799..feb02472f 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,10 +46,13 @@ public:
, m_prediction(SpecNone)
, m_argumentAwarePrediction(SpecNone)
, m_flags(0)
- , m_doubleFormatState(EmptyDoubleFormatState)
, m_isCaptured(false)
+ , m_shouldNeverUnbox(false)
, m_isArgumentsAlias(false)
, m_structureCheckHoistingFailed(false)
+ , m_isProfitableToUnbox(false)
+ , m_isLoadedFrom(false)
+ , m_doubleFormatState(EmptyDoubleFormatState)
{
clearVotes();
}
@@ -59,10 +62,12 @@ public:
, m_prediction(SpecNone)
, m_argumentAwarePrediction(SpecNone)
, m_flags(0)
- , m_doubleFormatState(EmptyDoubleFormatState)
, m_isCaptured(isCaptured)
+ , m_shouldNeverUnbox(isCaptured)
, m_isArgumentsAlias(false)
, m_structureCheckHoistingFailed(false)
+ , m_isProfitableToUnbox(false)
+ , m_doubleFormatState(EmptyDoubleFormatState)
{
clearVotes();
}
@@ -80,11 +85,8 @@ public:
bool mergeIsCaptured(bool isCaptured)
{
- bool newIsCaptured = m_isCaptured | isCaptured;
- if (newIsCaptured == m_isCaptured)
- return false;
- m_isCaptured = newIsCaptured;
- return true;
+ return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured)
+ | checkAndSet(m_isCaptured, m_isCaptured | isCaptured);
}
bool isCaptured()
@@ -92,15 +94,47 @@ public:
return m_isCaptured;
}
- bool mergeStructureCheckHoistingFailed(bool failed)
+ bool mergeIsProfitableToUnbox(bool isProfitableToUnbox)
+ {
+ return checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | isProfitableToUnbox);
+ }
+
+ bool isProfitableToUnbox()
{
- bool newFailed = m_structureCheckHoistingFailed | failed;
- if (newFailed == m_structureCheckHoistingFailed)
+ return m_isProfitableToUnbox;
+ }
+
+ bool mergeShouldNeverUnbox(bool shouldNeverUnbox)
+ {
+ bool newShouldNeverUnbox = m_shouldNeverUnbox | shouldNeverUnbox;
+ if (newShouldNeverUnbox == m_shouldNeverUnbox)
return false;
- m_structureCheckHoistingFailed = newFailed;
+ m_shouldNeverUnbox = newShouldNeverUnbox;
return true;
}
+ // Returns true if it would be unsound to store the value in an unboxed fashion.
+ // If this returns false, it simply means that it is sound to unbox; it doesn't
+ // mean that we have actually done so.
+ bool shouldNeverUnbox()
+ {
+ ASSERT(!(m_isCaptured && !m_shouldNeverUnbox));
+ return m_shouldNeverUnbox;
+ }
+
+ // Returns true if we should be unboxing the value provided that the predictions
+ // and double format vote say so. This may return false even if shouldNeverUnbox()
+ // returns false, since this incorporates heuristics of profitability.
+ bool shouldUnboxIfPossible()
+ {
+ return !shouldNeverUnbox() && isProfitableToUnbox();
+ }
+
+ bool mergeStructureCheckHoistingFailed(bool failed)
+ {
+ return checkAndSet(m_structureCheckHoistingFailed, m_structureCheckHoistingFailed | failed);
+ }
+
bool structureCheckHoistingFailed()
{
return m_structureCheckHoistingFailed;
@@ -108,11 +142,7 @@ public:
bool mergeIsArgumentsAlias(bool isArgumentsAlias)
{
- bool newIsArgumentsAlias = m_isArgumentsAlias | isArgumentsAlias;
- if (newIsArgumentsAlias == m_isArgumentsAlias)
- return false;
- m_isArgumentsAlias = newIsArgumentsAlias;
- return true;
+ return checkAndSet(m_isArgumentsAlias, m_isArgumentsAlias | isArgumentsAlias);
}
bool isArgumentsAlias()
@@ -120,6 +150,21 @@ public:
return m_isArgumentsAlias;
}
+ bool mergeIsLoadedFrom(bool isLoadedFrom)
+ {
+ return checkAndSet(m_isLoadedFrom, m_isLoadedFrom | isLoadedFrom);
+ }
+
+ void setIsLoadedFrom(bool isLoadedFrom)
+ {
+ m_isLoadedFrom = isLoadedFrom;
+ }
+
+ bool isLoadedFrom()
+ {
+ return m_isLoadedFrom;
+ }
+
bool predict(SpeculatedType prediction)
{
VariableAccessData* self = find();
@@ -177,8 +222,12 @@ public:
// If the variable is not a number prediction, then this doesn't
// make any sense.
- if (!isNumberSpeculation(prediction()))
+ if (!isNumberSpeculation(prediction())) {
+ // FIXME: we may end up forcing a local in inlined argument position to be a double even
+ // if it is sometimes not even numeric, since this never signals the fact that it doesn't
+ // want doubles. https://bugs.webkit.org/show_bug.cgi?id=109511
return false;
+ }
// If the variable is predicted to hold only doubles, then it's a
// no-brainer: it should be formatted as a double.
@@ -206,13 +255,19 @@ public:
bool shouldUseDoubleFormat()
{
ASSERT(isRoot());
- return m_doubleFormatState == UsingDoubleFormat;
+ bool doubleState = m_doubleFormatState == UsingDoubleFormat;
+ ASSERT(!(doubleState && shouldNeverUnbox()));
+ ASSERT(!(doubleState && isCaptured()));
+ return doubleState && isProfitableToUnbox();
}
bool tallyVotesForShouldUseDoubleFormat()
{
ASSERT(isRoot());
+ if (operandIsArgument(local()) || shouldNeverUnbox())
+ return DFG::mergeDoubleFormatState(m_doubleFormatState, NotUsingDoubleFormat);
+
if (m_doubleFormatState == CantUseDoubleFormat)
return false;
@@ -248,11 +303,7 @@ public:
bool mergeFlags(NodeFlags newFlags)
{
- newFlags |= m_flags;
- if (newFlags == m_flags)
- return false;
- m_flags = newFlags;
- return true;
+ return checkAndSet(m_flags, m_flags | newFlags);
}
private:
@@ -265,13 +316,16 @@ private:
SpeculatedType m_prediction;
SpeculatedType m_argumentAwarePrediction;
NodeFlags m_flags;
-
- float m_votes[2]; // Used primarily for double voting but may be reused for other purposes.
- DoubleFormatState m_doubleFormatState;
-
+
bool m_isCaptured;
+ bool m_shouldNeverUnbox;
bool m_isArgumentsAlias;
bool m_structureCheckHoistingFailed;
+ bool m_isProfitableToUnbox;
+ bool m_isLoadedFrom;
+
+ float m_votes[2]; // Used primarily for double voting but may be reused for other purposes.
+ DoubleFormatState m_doubleFormatState;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp b/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp
index 920858cef..26cca8dcf 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessDataDump.cpp
@@ -63,6 +63,10 @@ void VariableAccessDataDump::dump(PrintStream& out) const
if (m_data->isCaptured())
out.print("*");
+ else if (m_data->shouldNeverUnbox())
+ out.print("!");
+ else if (!m_data->shouldUnboxIfPossible())
+ out.print("~");
out.print(AbbreviatedSpeculationDump(m_data->prediction()));
}
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEvent.cpp b/Source/JavaScriptCore/dfg/DFGVariableEvent.cpp
index 8ea568b23..efffb19ea 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEvent.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableEvent.cpp
@@ -52,23 +52,23 @@ void VariableEvent::dump(PrintStream& out) const
dumpSpillInfo("Spill", out);
break;
case Death:
- out.printf("Death(@%u)", nodeIndex());
+ out.print("Death(", id(), ")");
break;
- case MovHint:
- out.printf("MovHint(@%u, r%d)", nodeIndex(), operand());
+ case MovHintEvent:
+ out.print("MovHint(", id(), ", r", operand(), ")");
break;
case SetLocalEvent:
out.printf("SetLocal(r%d, %s)", operand(), dataFormatToString(dataFormat()));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
void VariableEvent::dumpFillInfo(const char* name, PrintStream& out) const
{
- out.printf("%s(@%u, ", name, nodeIndex());
+ out.print(name, "(", id(), ", ");
if (dataFormat() == DataFormatDouble)
out.printf("%s", FPRInfo::debugName(fpr()));
#if USE(JSVALUE32_64)
@@ -82,7 +82,7 @@ void VariableEvent::dumpFillInfo(const char* name, PrintStream& out) const
void VariableEvent::dumpSpillInfo(const char* name, PrintStream& out) const
{
- out.printf("%s(@%u, r%d, %s)", name, nodeIndex(), virtualRegister(), dataFormatToString(dataFormat()));
+ out.print(name, "(", id(), ", r", virtualRegister(), ", ", dataFormatToString(dataFormat()), ")");
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEvent.h b/Source/JavaScriptCore/dfg/DFGVariableEvent.h
index 0d1fe0a99..1605f79b8 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEvent.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableEvent.h
@@ -31,6 +31,7 @@
#if ENABLE(DFG_JIT)
#include "DFGCommon.h"
+#include "DFGMinifiedID.h"
#include "DataFormat.h"
#include "MacroAssembler.h"
#include <stdio.h>
@@ -56,9 +57,9 @@ enum VariableEventKind {
// Death of a node - after this we no longer care about this node.
Death,
- // A MovHint means that a node is being associated with a bytecode operand,
+ // A MovHintEvent means that a node is being associated with a bytecode operand,
// but that it has not been stored into that operand.
- MovHint,
+ MovHintEvent,
// A SetLocalEvent means that a node's value has actually been stored into the
// bytecode operand that it's associated with.
@@ -95,7 +96,7 @@ public:
return event;
}
- static VariableEvent fillGPR(VariableEventKind kind, NodeIndex nodeIndex, MacroAssembler::RegisterID gpr, DataFormat dataFormat)
+ static VariableEvent fillGPR(VariableEventKind kind, MinifiedID id, MacroAssembler::RegisterID gpr, DataFormat dataFormat)
{
ASSERT(kind == BirthToFill || kind == Fill);
ASSERT(dataFormat != DataFormatDouble);
@@ -103,7 +104,7 @@ public:
ASSERT(!(dataFormat & DataFormatJS));
#endif
VariableEvent event;
- event.m_index = nodeIndex;
+ event.m_id = id;
event.u.gpr = gpr;
event.m_kind = kind;
event.m_dataFormat = dataFormat;
@@ -111,11 +112,11 @@ public:
}
#if USE(JSVALUE32_64)
- static VariableEvent fillPair(VariableEventKind kind, NodeIndex nodeIndex, MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
+ static VariableEvent fillPair(VariableEventKind kind, MinifiedID id, MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
{
ASSERT(kind == BirthToFill || kind == Fill);
VariableEvent event;
- event.m_index = nodeIndex;
+ event.m_id = id;
event.u.pair.tagGPR = tagGPR;
event.u.pair.payloadGPR = payloadGPR;
event.m_kind = kind;
@@ -124,32 +125,32 @@ public:
}
#endif // USE(JSVALUE32_64)
- static VariableEvent fillFPR(VariableEventKind kind, NodeIndex nodeIndex, MacroAssembler::FPRegisterID fpr)
+ static VariableEvent fillFPR(VariableEventKind kind, MinifiedID id, MacroAssembler::FPRegisterID fpr)
{
ASSERT(kind == BirthToFill || kind == Fill);
VariableEvent event;
- event.m_index = nodeIndex;
+ event.m_id = id;
event.u.fpr = fpr;
event.m_kind = kind;
event.m_dataFormat = DataFormatDouble;
return event;
}
- static VariableEvent spill(VariableEventKind kind, NodeIndex nodeIndex, VirtualRegister virtualRegister, DataFormat format)
+ static VariableEvent spill(VariableEventKind kind, MinifiedID id, VirtualRegister virtualRegister, DataFormat format)
{
ASSERT(kind == BirthToSpill || kind == Spill);
VariableEvent event;
- event.m_index = nodeIndex;
+ event.m_id = id;
event.u.virtualReg = virtualRegister;
event.m_kind = kind;
event.m_dataFormat = format;
return event;
}
- static VariableEvent death(NodeIndex nodeIndex)
+ static VariableEvent death(MinifiedID id)
{
VariableEvent event;
- event.m_index = nodeIndex;
+ event.m_id = id;
event.m_kind = Death;
return event;
}
@@ -163,12 +164,12 @@ public:
return event;
}
- static VariableEvent movHint(NodeIndex nodeIndex, int operand)
+ static VariableEvent movHint(MinifiedID id, int operand)
{
VariableEvent event;
- event.m_index = nodeIndex;
+ event.m_id = id;
event.u.virtualReg = operand;
- event.m_kind = MovHint;
+ event.m_kind = MovHintEvent;
return event;
}
@@ -177,12 +178,12 @@ public:
return static_cast<VariableEventKind>(m_kind);
}
- NodeIndex nodeIndex() const
+ MinifiedID id() const
{
ASSERT(m_kind == BirthToFill || m_kind == Fill
|| m_kind == BirthToSpill || m_kind == Spill
- || m_kind == Death || m_kind == MovHint);
- return m_index;
+ || m_kind == Death || m_kind == MovHintEvent);
+ return m_id;
}
DataFormat dataFormat() const
@@ -234,7 +235,7 @@ public:
int operand() const
{
- ASSERT(m_kind == SetLocalEvent || m_kind == MovHint);
+ ASSERT(m_kind == SetLocalEvent || m_kind == MovHintEvent);
return u.virtualReg;
}
@@ -246,13 +247,13 @@ private:
void dumpFillInfo(const char* name, PrintStream&) const;
void dumpSpillInfo(const char* name, PrintStream&) const;
- NodeIndex m_index;
+ MinifiedID m_id;
// For BirthToFill, Fill:
// - The GPR or FPR, or a GPR pair.
// For BirthToSpill, Spill:
// - The virtual register.
- // For MovHint, SetLocalEvent:
+ // For MovHintEvent, SetLocalEvent:
// - The bytecode operand.
// For Death:
// - Unused.
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
index 7fa109b62..a3f2ac6ff 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,9 @@
#include "CodeBlock.h"
#include "DFGValueSource.h"
+#include "Operations.h"
#include <wtf/DataLog.h>
+#include <wtf/HashMap.h>
namespace JSC { namespace DFG {
@@ -41,6 +43,8 @@ void VariableEventStream::logEvent(const VariableEvent& event)
dataLogF(" ");
}
+namespace {
+
struct MinifiedGenerationInfo {
bool filled; // true -> in gpr/fpr/pair, false -> spilled
VariableRepresentation u;
@@ -74,6 +78,33 @@ struct MinifiedGenerationInfo {
}
};
+} // namespace
+
+bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, CodeBlock* codeBlock, MinifiedNode* node) const
+{
+ if (!node)
+ return false;
+
+ if (node->hasConstantNumber()) {
+ recovery = ValueRecovery::constant(
+ codeBlock->constantRegister(
+ FirstConstantRegisterIndex + node->constantNumber()).get());
+ return true;
+ }
+
+ if (node->hasWeakConstant()) {
+ recovery = ValueRecovery::constant(node->weakConstant());
+ return true;
+ }
+
+ if (node->op() == PhantomArguments) {
+ recovery = ValueRecovery::argumentsThatWereNotCreated();
+ return true;
+ }
+
+ return false;
+}
+
void VariableEventStream::reconstruct(
CodeBlock* codeBlock, CodeOrigin codeOrigin, MinifiedGraph& graph,
unsigned index, Operands<ValueRecovery>& valueRecoveries) const
@@ -108,7 +139,7 @@ void VariableEventStream::reconstruct(
// Step 2: Create a mock-up of the DFG's state and execute the events.
Operands<ValueSource> operandSources(codeBlock->numParameters(), numVariables);
- Vector<MinifiedGenerationInfo, 32> generationInfos(graph.originalGraphSize());
+ HashMap<MinifiedID, MinifiedGenerationInfo> generationInfos;
for (unsigned i = startIndex; i < index; ++i) {
const VariableEvent& event = at(i);
switch (event.kind()) {
@@ -116,34 +147,35 @@ void VariableEventStream::reconstruct(
// nothing to do.
break;
case BirthToFill:
- case BirthToSpill:
+ case BirthToSpill: {
+ MinifiedGenerationInfo info;
+ info.update(event);
+ generationInfos.add(event.id(), info);
+ break;
+ }
case Fill:
case Spill:
- case Death:
- generationInfos[event.nodeIndex()].update(event);
+ case Death: {
+ HashMap<MinifiedID, MinifiedGenerationInfo>::iterator iter = generationInfos.find(event.id());
+ ASSERT(iter != generationInfos.end());
+ iter->value.update(event);
break;
- case MovHint:
+ }
+ case MovHintEvent:
if (operandSources.hasOperand(event.operand()))
- operandSources.setOperand(event.operand(), ValueSource(event.nodeIndex()));
+ operandSources.setOperand(event.operand(), ValueSource(event.id()));
break;
case SetLocalEvent:
if (operandSources.hasOperand(event.operand()))
operandSources.setOperand(event.operand(), ValueSource::forDataFormat(event.dataFormat()));
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
- // Step 3: Record the things that are live, so we can get to them more quickly.
- Vector<unsigned, 16> indicesOfLiveThings;
- for (unsigned i = 0; i < generationInfos.size(); ++i) {
- if (generationInfos[i].format != DataFormatNone)
- indicesOfLiveThings.append(i);
- }
-
- // Step 4: Compute value recoveries!
+ // Step 3: Compute value recoveries!
valueRecoveries = Operands<ValueRecovery>(codeBlock->numParameters(), numVariables);
for (unsigned i = 0; i < operandSources.size(); ++i) {
ValueSource& source = operandSources[i];
@@ -153,26 +185,12 @@ void VariableEventStream::reconstruct(
}
ASSERT(source.kind() == HaveNode);
- MinifiedNode* node = graph.at(source.nodeIndex());
- if (node) {
- if (node->hasConstantNumber()) {
- valueRecoveries[i] = ValueRecovery::constant(
- codeBlock->constantRegister(
- FirstConstantRegisterIndex + node->constantNumber()).get());
- continue;
- }
- if (node->hasWeakConstant()) {
- valueRecoveries[i] = ValueRecovery::constant(node->weakConstant());
- continue;
- }
- if (node->op() == PhantomArguments) {
- valueRecoveries[i] = ValueRecovery::argumentsThatWereNotCreated();
- continue;
- }
- }
+ MinifiedNode* node = graph.at(source.id());
+ if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, node))
+ continue;
- MinifiedGenerationInfo* info = &generationInfos[source.nodeIndex()];
- if (info->format == DataFormatNone) {
+ MinifiedGenerationInfo info = generationInfos.get(source.id());
+ if (info.format == DataFormatNone) {
// Try to see if there is an alternate node that would contain the value we want.
// There are four possibilities:
//
@@ -196,62 +214,65 @@ void VariableEventStream::reconstruct(
bool found = false;
if (node && node->op() == UInt32ToNumber) {
- NodeIndex nodeIndex = node->child1();
- node = graph.at(nodeIndex);
- info = &generationInfos[nodeIndex];
- if (info->format != DataFormatNone)
+ MinifiedID id = node->child1();
+ if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id)))
+ continue;
+ info = generationInfos.get(id);
+ if (info.format != DataFormatNone)
found = true;
}
if (!found) {
- NodeIndex int32ToDoubleIndex = NoNode;
- NodeIndex valueToInt32Index = NoNode;
- NodeIndex uint32ToNumberIndex = NoNode;
- NodeIndex doubleAsInt32Index = NoNode;
+ MinifiedID int32ToDoubleID;
+ MinifiedID valueToInt32ID;
+ MinifiedID uint32ToNumberID;
+ MinifiedID doubleAsInt32ID;
- for (unsigned i = 0; i < indicesOfLiveThings.size(); ++i) {
- NodeIndex nodeIndex = indicesOfLiveThings[i];
- node = graph.at(nodeIndex);
+ HashMap<MinifiedID, MinifiedGenerationInfo>::iterator iter = generationInfos.begin();
+ HashMap<MinifiedID, MinifiedGenerationInfo>::iterator end = generationInfos.end();
+ for (; iter != end; ++iter) {
+ MinifiedID id = iter->key;
+ node = graph.at(id);
if (!node)
continue;
if (!node->hasChild1())
continue;
- if (node->child1() != source.nodeIndex())
+ if (node->child1() != source.id())
+ continue;
+ if (iter->value.format == DataFormatNone)
continue;
- ASSERT(generationInfos[nodeIndex].format != DataFormatNone);
switch (node->op()) {
case Int32ToDouble:
- int32ToDoubleIndex = nodeIndex;
+ case ForwardInt32ToDouble:
+ int32ToDoubleID = id;
break;
case ValueToInt32:
- valueToInt32Index = nodeIndex;
+ valueToInt32ID = id;
break;
case UInt32ToNumber:
- uint32ToNumberIndex = nodeIndex;
+ uint32ToNumberID = id;
break;
case DoubleAsInt32:
- doubleAsInt32Index = nodeIndex;
+ doubleAsInt32ID = id;
break;
default:
break;
}
}
- NodeIndex nodeIndexToUse;
- if (doubleAsInt32Index != NoNode)
- nodeIndexToUse = doubleAsInt32Index;
- else if (int32ToDoubleIndex != NoNode)
- nodeIndexToUse = int32ToDoubleIndex;
- else if (valueToInt32Index != NoNode)
- nodeIndexToUse = valueToInt32Index;
- else if (uint32ToNumberIndex != NoNode)
- nodeIndexToUse = uint32ToNumberIndex;
- else
- nodeIndexToUse = NoNode;
+ MinifiedID idToUse;
+ if (!!doubleAsInt32ID)
+ idToUse = doubleAsInt32ID;
+ else if (!!int32ToDoubleID)
+ idToUse = int32ToDoubleID;
+ else if (!!valueToInt32ID)
+ idToUse = valueToInt32ID;
+ else if (!!uint32ToNumberID)
+ idToUse = uint32ToNumberID;
- if (nodeIndexToUse != NoNode) {
- info = &generationInfos[nodeIndexToUse];
- ASSERT(info->format != DataFormatNone);
+ if (!!idToUse) {
+ info = generationInfos.get(idToUse);
+ ASSERT(info.format != DataFormatNone);
found = true;
}
}
@@ -262,25 +283,32 @@ void VariableEventStream::reconstruct(
}
}
- ASSERT(info->format != DataFormatNone);
+ ASSERT(info.format != DataFormatNone);
- if (info->filled) {
- if (info->format == DataFormatDouble) {
- valueRecoveries[i] = ValueRecovery::inFPR(info->u.fpr);
+ if (info.filled) {
+ if (info.format == DataFormatDouble) {
+ valueRecoveries[i] = ValueRecovery::inFPR(info.u.fpr);
continue;
}
#if USE(JSVALUE32_64)
- if (info->format & DataFormatJS) {
- valueRecoveries[i] = ValueRecovery::inPair(info->u.pair.tagGPR, info->u.pair.payloadGPR);
+ if (info.format & DataFormatJS) {
+ valueRecoveries[i] = ValueRecovery::inPair(info.u.pair.tagGPR, info.u.pair.payloadGPR);
continue;
}
#endif
- valueRecoveries[i] = ValueRecovery::inGPR(info->u.gpr, info->format);
+ valueRecoveries[i] = ValueRecovery::inGPR(info.u.gpr, info.format);
continue;
}
valueRecoveries[i] =
- ValueRecovery::displacedInJSStack(static_cast<VirtualRegister>(info->u.virtualReg), info->format);
+ ValueRecovery::displacedInJSStack(static_cast<VirtualRegister>(info.u.virtualReg), info.format);
+ }
+
+ // Step 4: Make sure that for locals that coincide with true call frame headers, the exit compiler knows
+ // that those values don't have to be recovered. Signal this by using ValueRecovery::alreadyInJSStack()
+ for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
+ for (unsigned i = JSStack::CallFrameHeaderSize; i--;)
+ valueRecoveries.setLocal(inlineCallFrame->stackOffset - i - 1, ValueRecovery::alreadyInJSStack());
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.h b/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
index 0d10eb048..cfe8aaa7c 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.h
@@ -53,6 +53,8 @@ public:
unsigned index, Operands<ValueRecovery>&) const;
private:
+ bool tryToSetConstantRecovery(ValueRecovery&, CodeBlock*, MinifiedNode*) const;
+
void logEvent(const VariableEvent&);
};
diff --git a/Source/JavaScriptCore/dfg/DFGVariadicFunction.h b/Source/JavaScriptCore/dfg/DFGVariadicFunction.h
new file mode 100644
index 000000000..f5523af77
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGVariadicFunction.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGVariadicFunction_h
+#define DFGVariadicFunction_h
+
+#define DFG_COMMA ,
+
+// The signature of v is (templatePre, templatePost, typeParams, valueParams, valueArgs)
+//
+// You would use it like:
+// #define DEFINE_FUNCTION(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs)
+// templatePre typeParams templatePost void f(valueParams) { g(valueArgs); }
+// DFG_VARIADIC_TEMPLATE_FUNCTION(DEFINE_FUNCTION)
+// #undef DEFINE_FUNCTION
+//
+// Or if you wanted the defined function to take an additional template arg, you would do:
+// #define DEFINE_FUNCTION(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs)
+// template<typename T valueParamsComma typeParams> void f(T value valueParamsComma valueParams) { g(value, valueArgs); }
+// DFG_VARIADIC_TEMPLATE_FUNCTION(DEFINE_FUNCTION)
+// #undef DEFINE_FUNCTION
+
+#define DFG_VARIADIC_TEMPLATE_FUNCTION(v) \
+ v(, , , , , ) \
+ v(template<, >, typename _DFG_T1, DFG_COMMA, const _DFG_T1& _DFG_value1, _DFG_value1) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2, _DFG_value1 DFG_COMMA _DFG_value2) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2 DFG_COMMA typename _DFG_T3, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2 DFG_COMMA const _DFG_T3& _DFG_value3, _DFG_value1 DFG_COMMA _DFG_value2 DFG_COMMA _DFG_value3) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2 DFG_COMMA typename _DFG_T3 DFG_COMMA typename _DFG_T4, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2 DFG_COMMA const _DFG_T3& _DFG_value3 DFG_COMMA const _DFG_T4& _DFG_value4, _DFG_value1 DFG_COMMA _DFG_value2 DFG_COMMA _DFG_value3 DFG_COMMA _DFG_value4) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2 DFG_COMMA typename _DFG_T3 DFG_COMMA typename _DFG_T4 DFG_COMMA typename _DFG_T5, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2 DFG_COMMA const _DFG_T3& _DFG_value3 DFG_COMMA const _DFG_T4& _DFG_value4 DFG_COMMA const _DFG_T5& _DFG_value5, _DFG_value1 DFG_COMMA _DFG_value2 DFG_COMMA _DFG_value3 DFG_COMMA _DFG_value4 DFG_COMMA _DFG_value5) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2 DFG_COMMA typename _DFG_T3 DFG_COMMA typename _DFG_T4 DFG_COMMA typename _DFG_T5 DFG_COMMA typename _DFG_T6, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2 DFG_COMMA const _DFG_T3& _DFG_value3 DFG_COMMA const _DFG_T4& _DFG_value4 DFG_COMMA const _DFG_T5& _DFG_value5 DFG_COMMA const _DFG_T6& _DFG_value6, _DFG_value1 DFG_COMMA _DFG_value2 DFG_COMMA _DFG_value3 DFG_COMMA _DFG_value4 DFG_COMMA _DFG_value5 DFG_COMMA _DFG_value6) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2 DFG_COMMA typename _DFG_T3 DFG_COMMA typename _DFG_T4 DFG_COMMA typename _DFG_T5 DFG_COMMA typename _DFG_T6 DFG_COMMA typename _DFG_T7, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2 DFG_COMMA const _DFG_T3& _DFG_value3 DFG_COMMA const _DFG_T4& _DFG_value4 DFG_COMMA const _DFG_T5& _DFG_value5 DFG_COMMA const _DFG_T6& _DFG_value6 DFG_COMMA const _DFG_T7& _DFG_value7, _DFG_value1 DFG_COMMA _DFG_value2 DFG_COMMA _DFG_value3 DFG_COMMA _DFG_value4 DFG_COMMA _DFG_value5 DFG_COMMA _DFG_value6 DFG_COMMA _DFG_value7) \
+ v(template<, >, typename _DFG_T1 DFG_COMMA typename _DFG_T2 DFG_COMMA typename _DFG_T3 DFG_COMMA typename _DFG_T4 DFG_COMMA typename _DFG_T5 DFG_COMMA typename _DFG_T6 DFG_COMMA typename _DFG_T7 DFG_COMMA typename _DFG_T8, DFG_COMMA, const _DFG_T1& _DFG_value1 DFG_COMMA const _DFG_T2& _DFG_value2 DFG_COMMA const _DFG_T3& _DFG_value3 DFG_COMMA const _DFG_T4& _DFG_value4 DFG_COMMA const _DFG_T5& _DFG_value5 DFG_COMMA const _DFG_T6& _DFG_value6 DFG_COMMA const _DFG_T7& _DFG_value7 DFG_COMMA _DFG_T8& _DFG_value8, _DFG_value1 DFG_COMMA _DFG_value2 DFG_COMMA _DFG_value3 DFG_COMMA _DFG_value4 DFG_COMMA _DFG_value5 DFG_COMMA _DFG_value6 DFG_COMMA _DFG_value7 DFG_COMMA _DFG_value8)
+
+#endif // DFGVariadicFunction_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp b/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
index eb3232e69..e390300a7 100644
--- a/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp
@@ -30,6 +30,7 @@
#include "DFGGraph.h"
#include "DFGScoreBoard.h"
+#include "JSCellInlines.h"
namespace JSC { namespace DFG {
@@ -47,7 +48,7 @@ public:
m_graph.m_preservedVars.dump(WTF::dataFile());
dataLogF("\n");
#endif
- ScoreBoard scoreBoard(m_graph, m_graph.m_preservedVars);
+ ScoreBoard scoreBoard(m_graph.m_preservedVars);
scoreBoard.assertClear();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
bool needsNewLine = false;
@@ -59,47 +60,56 @@ public:
if (!block->isReachable)
continue;
for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- NodeIndex nodeIndex = block->at(indexInBlock);
+ Node* node = block->at(indexInBlock);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
if (needsNewLine)
dataLogF("\n");
- dataLogF(" @%u:", nodeIndex);
+ dataLogF(" @%u:", node->index());
needsNewLine = true;
#endif
- Node& node = m_graph[nodeIndex];
- if (!node.shouldGenerate() || node.op() == Phi || node.op() == Flush)
+ if (!node->shouldGenerate())
continue;
- if (node.op() == GetLocal)
- ASSERT(!m_graph[node.child1()].hasResult());
+ switch (node->op()) {
+ case Phi:
+ case Flush:
+ case PhantomLocal:
+ continue;
+ case GetLocal:
+ ASSERT(!node->child1()->hasResult());
+ break;
+ default:
+ break;
+ }
// 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++)
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
scoreBoard.useIfHasResult(m_graph.m_varArgChildren[childIdx]);
} else {
- scoreBoard.useIfHasResult(node.child1());
- scoreBoard.useIfHasResult(node.child2());
- scoreBoard.useIfHasResult(node.child3());
+ scoreBoard.useIfHasResult(node->child1());
+ scoreBoard.useIfHasResult(node->child2());
+ scoreBoard.useIfHasResult(node->child3());
}
- if (!node.hasResult())
+ if (!node->hasResult())
continue;
VirtualRegister virtualRegister = scoreBoard.allocate();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF(" Assigning virtual register %u to node %u.",
- virtualRegister, nodeIndex);
+ dataLogF(
+ " Assigning virtual register %u to node %u.",
+ virtualRegister, node->index());
#endif
- node.setVirtualRegister(virtualRegister);
+ node->setVirtualRegister(virtualRegister);
// 'mustGenerate' nodes have their useCount artificially elevated,
// call use now to account for this.
- if (node.mustGenerate())
- scoreBoard.use(nodeIndex);
+ if (node->mustGenerate())
+ scoreBoard.use(node);
}
scoreBoard.assertClear();
}
diff --git a/Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.cpp b/Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.cpp
new file mode 100644
index 000000000..fb6e0db83
--- /dev/null
+++ b/Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.cpp
@@ -0,0 +1,1565 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ARMV7_DISASSEMBLER)
+
+#include "ARMv7DOpcode.h"
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+namespace JSC { namespace ARMv7Disassembler {
+
+ARMv7D16BitOpcode::OpcodeGroup* ARMv7D16BitOpcode::opcodeTable[32];
+ARMv7D32BitOpcode::OpcodeGroup* ARMv7D32BitOpcode::opcodeTable[16];
+
+const char* const ARMv7DOpcode::s_conditionNames[16] = {
+ "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
+ "hi", "ls", "ge", "lt", "gt", "le", "al", "al"
+};
+
+const char* const ARMv7DOpcode::s_optionName[8] = {
+ "uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"
+};
+
+const char* const ARMv7DOpcode::s_shiftNames[4] = {
+ "lsl", "lsr", "asl", "ror"
+};
+
+const char* const ARMv7DOpcode::s_specialRegisterNames[3] = { "sp", "lr", "pc" };
+
+template <typename OpcodeType, typename InstructionType>
+struct OpcodeGroupInitializer {
+ unsigned m_opcodeGroupNumber;
+ InstructionType m_mask;
+ InstructionType m_pattern;
+ const char* (*m_format)(OpcodeType*);
+};
+
+#define OPCODE_GROUP_ENTRY(groupIndex, groupClass) \
+{ groupIndex, groupClass::s_mask, groupClass::s_pattern, groupClass::format }
+
+typedef OpcodeGroupInitializer<ARMv7D16BitOpcode, uint16_t> Opcode16GroupInitializer;
+typedef OpcodeGroupInitializer<ARMv7D32BitOpcode, uint32_t> Opcode32GroupInitializer;
+
+static Opcode16GroupInitializer opcode16BitGroupList[] = {
+ OPCODE_GROUP_ENTRY(0x0, ARMv7DOpcodeLogicalImmediateT1),
+ OPCODE_GROUP_ENTRY(0x1, ARMv7DOpcodeLogicalImmediateT1),
+ OPCODE_GROUP_ENTRY(0x2, ARMv7DOpcodeLogicalImmediateT1),
+ OPCODE_GROUP_ENTRY(0x3, ARMv7DOpcodeAddSubtractT1),
+ OPCODE_GROUP_ENTRY(0x3, ARMv7DOpcodeAddSubtractImmediate3),
+ OPCODE_GROUP_ENTRY(0x4, ARMv7DOpcodeMoveImmediateT1),
+ OPCODE_GROUP_ENTRY(0x5, ARMv7DOpcodeCompareImmediateT1),
+ OPCODE_GROUP_ENTRY(0x6, ARMv7DOpcodeAddSubtractImmediate8),
+ OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeAddSubtractImmediate8),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeDataProcessingRegisterT1),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeAddRegisterT2),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeCompareRegisterT2),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeCompareRegisterT1),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeMoveRegisterT1),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeBranchExchangeT1),
+ OPCODE_GROUP_ENTRY(0x9, ARMv7DOpcodeLoadFromLiteralPool),
+ OPCODE_GROUP_ENTRY(0xa, ARMv7DOpcodeLoadStoreRegisterOffsetT1),
+ OPCODE_GROUP_ENTRY(0xb, ARMv7DOpcodeLoadStoreRegisterOffsetT1),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte),
+ OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte),
+ OPCODE_GROUP_ENTRY(0xe, ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte),
+ OPCODE_GROUP_ENTRY(0xf, ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte),
+ OPCODE_GROUP_ENTRY(0x10, ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord),
+ OPCODE_GROUP_ENTRY(0x11, ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord),
+ OPCODE_GROUP_ENTRY(0x12, ARMv7DOpcodeLoadStoreRegisterSPRelative),
+ OPCODE_GROUP_ENTRY(0x13, ARMv7DOpcodeLoadStoreRegisterSPRelative),
+ OPCODE_GROUP_ENTRY(0x14, ARMv7DOpcodeGeneratePCRelativeAddress),
+ OPCODE_GROUP_ENTRY(0x15, ARMv7DOpcodeAddSPPlusImmediate),
+ OPCODE_GROUP_ENTRY(0x16, ARMv7DOpcodeMiscCompareAndBranch),
+ OPCODE_GROUP_ENTRY(0x16, ARMv7DOpcodeMiscByteHalfwordOps),
+ OPCODE_GROUP_ENTRY(0x16, ARMv7DOpcodeMiscPushPop),
+ OPCODE_GROUP_ENTRY(0x16, ARMv7DOpcodeMiscAddSubSP),
+ OPCODE_GROUP_ENTRY(0x17, ARMv7DOpcodeMiscHint16), // Needs to be before IfThenT1
+ OPCODE_GROUP_ENTRY(0x17, ARMv7DOpcodeMiscIfThenT1),
+ OPCODE_GROUP_ENTRY(0x17, ARMv7DOpcodeMiscByteHalfwordOps),
+ OPCODE_GROUP_ENTRY(0x17, ARMv7DOpcodeMiscCompareAndBranch),
+ OPCODE_GROUP_ENTRY(0x17, ARMv7DOpcodeMiscPushPop),
+ OPCODE_GROUP_ENTRY(0x17, ARMv7DOpcodeMiscBreakpointT1),
+ OPCODE_GROUP_ENTRY(0x1a, ARMv7DOpcodeBranchConditionalT1),
+ OPCODE_GROUP_ENTRY(0x1b, ARMv7DOpcodeBranchConditionalT1),
+ OPCODE_GROUP_ENTRY(0x1c, ARMv7DOpcodeBranchT2)
+};
+
+static Opcode32GroupInitializer opcode32BitGroupList[] = {
+ OPCODE_GROUP_ENTRY(0x5, ARMv7DOpcodeDataProcessingShiftedReg),
+ OPCODE_GROUP_ENTRY(0x6, ARMv7DOpcodeVMOVSinglePrecision),
+ OPCODE_GROUP_ENTRY(0x6, ARMv7DOpcodeVMOVDoublePrecision),
+ OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeFPTransfer),
+ OPCODE_GROUP_ENTRY(0x7, ARMv7DOpcodeVMSR),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeDataProcessingModifiedImmediate),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeConditionalBranchT3),
+ OPCODE_GROUP_ENTRY(0x8, ARMv7DOpcodeBranchOrBranchLink),
+ OPCODE_GROUP_ENTRY(0x9, ARMv7DOpcodeUnmodifiedImmediate),
+ OPCODE_GROUP_ENTRY(0x9, ARMv7DOpcodeHint32),
+ OPCODE_GROUP_ENTRY(0x9, ARMv7DOpcodeConditionalBranchT3),
+ OPCODE_GROUP_ENTRY(0x9, ARMv7DOpcodeBranchOrBranchLink),
+ OPCODE_GROUP_ENTRY(0xa, ARMv7DOpcodeDataProcessingModifiedImmediate),
+ OPCODE_GROUP_ENTRY(0xa, ARMv7DOpcodeConditionalBranchT3),
+ OPCODE_GROUP_ENTRY(0xa, ARMv7DOpcodeBranchOrBranchLink),
+ OPCODE_GROUP_ENTRY(0xb, ARMv7DOpcodeUnmodifiedImmediate),
+ OPCODE_GROUP_ENTRY(0xb, ARMv7DOpcodeConditionalBranchT3),
+ OPCODE_GROUP_ENTRY(0xb, ARMv7DOpcodeBranchOrBranchLink),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeLoadRegister),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeDataPushPopSingle), // Should be before StoreSingle*
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeStoreSingleRegister),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeStoreSingleImmediate12),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeStoreSingleImmediate8),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeLoadSignedImmediate),
+ OPCODE_GROUP_ENTRY(0xc, ARMv7DOpcodeLoadUnsignedImmediate),
+ OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeLongMultipleDivide),
+ OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegShift),
+ OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegExtend),
+ OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegParallel),
+ OPCODE_GROUP_ENTRY(0xd, ARMv7DOpcodeDataProcessingRegMisc),
+};
+
+bool ARMv7DOpcode::s_initialized = false;
+
+void ARMv7DOpcode::init()
+{
+ if (s_initialized)
+ return;
+
+ ARMv7D16BitOpcode::init();
+ ARMv7D32BitOpcode::init();
+
+ s_initialized = true;
+}
+
+void ARMv7DOpcode::startITBlock(unsigned blocksize, unsigned firstCondition)
+{
+ ASSERT(blocksize > 0 && blocksize <= MaxITBlockSize);
+ m_ITBlocksize = blocksize;
+ m_ITConditionIndex = m_ITBlocksize + 1;
+ m_currentITCondition = 0;
+ m_ifThenConditions[0] = firstCondition;
+}
+
+void ARMv7DOpcode::saveITConditionAt(unsigned blockPosition, unsigned condition)
+{
+ if (blockPosition < m_ITBlocksize)
+ m_ifThenConditions[blockPosition] = static_cast<unsigned char>(condition);
+}
+
+void ARMv7DOpcode::fetchOpcode(uint16_t*& newPC)
+{
+ m_bufferOffset = 0;
+ m_formatBuffer[0] = '\0';
+ m_currentPC = newPC;
+
+ m_opcode = *newPC++;
+
+ if (is32BitInstruction()) {
+ m_opcode <<= 16;
+ m_opcode |= *newPC++;
+ }
+
+ if (m_ITConditionIndex < m_ITBlocksize)
+ m_currentITCondition = m_ifThenConditions[m_ITConditionIndex];
+ else
+ m_currentITCondition = CondNone;
+}
+
+const char* ARMv7DOpcode::disassemble(uint16_t*& currentPC)
+{
+ const char* result;
+ fetchOpcode(currentPC);
+
+ if (is32BitInstruction())
+ result = reinterpret_cast<ARMv7D32BitOpcode*>(this)->doDisassemble();
+ else
+ result = reinterpret_cast<ARMv7D16BitOpcode*>(this)->doDisassemble();
+
+ if (startingITBlock())
+ m_ITConditionIndex = 0;
+ else if (inITBlock() && (++m_ITConditionIndex >= m_ITBlocksize))
+ endITBlock();
+
+ return result;
+}
+
+void ARMv7DOpcode::bufferPrintf(const char* format, ...)
+{
+ if (m_bufferOffset >= bufferSize)
+ return;
+
+ va_list argList;
+ va_start(argList, format);
+
+ m_bufferOffset += vsnprintf(m_formatBuffer + m_bufferOffset, bufferSize - m_bufferOffset, format, argList);
+
+ va_end(argList);
+}
+
+void ARMv7DOpcode::appendInstructionName(const char* instructionName, bool addS)
+{
+ if (!inITBlock() && !addS) {
+ appendInstructionNameNoITBlock(instructionName);
+
+ return;
+ }
+
+ const char sevenSpaces[8] = " ";
+
+ unsigned length = strlen(instructionName);
+
+ bufferPrintf(" %s", instructionName);
+ if (inITBlock()) {
+ const char* condition = conditionName(m_currentITCondition);
+ length += strlen(condition);
+ appendString(condition);
+ } else if (addS) {
+ length++;
+ appendCharacter('s');
+ }
+
+ if (length >= 7)
+ length = 6;
+
+ appendString(sevenSpaces + length);
+}
+
+void ARMv7DOpcode::appendRegisterName(unsigned registerNumber)
+{
+ registerNumber &= 0xf;
+
+ if (registerNumber > 12) {
+ appendString(s_specialRegisterNames[registerNumber - 13]);
+ return;
+ }
+
+ bufferPrintf("r%u", registerNumber);
+}
+
+void ARMv7DOpcode::appendRegisterList(unsigned registers)
+{
+ unsigned numberPrinted = 0;
+
+ appendCharacter('{');
+
+ for (unsigned i = 0; i < 16; i++) {
+ if (registers & i) {
+ if (numberPrinted++)
+ appendSeparator();
+ appendRegisterName(i);
+ }
+ }
+
+ appendCharacter('}');
+}
+
+void ARMv7DOpcode::appendFPRegisterName(char registerPrefix, unsigned registerNumber)
+{
+ bufferPrintf("%c%u", registerPrefix, registerNumber);
+}
+
+// 16 Bit Instructions
+
+void ARMv7D16BitOpcode::init()
+{
+ OpcodeGroup* lastGroups[OpcodeGroup::opcodeTableSize];
+
+ for (unsigned i = 0; i < OpcodeGroup::opcodeTableSize; i++) {
+ opcodeTable[i] = 0;
+ lastGroups[i] = 0;
+ }
+
+ for (unsigned i = 0; i < sizeof(opcode16BitGroupList) / sizeof(Opcode16GroupInitializer); i++) {
+ OpcodeGroup* newOpcodeGroup = new OpcodeGroup(opcode16BitGroupList[i].m_mask, opcode16BitGroupList[i].m_pattern, opcode16BitGroupList[i].m_format);
+ uint16_t opcodeGroupNumber = opcode16BitGroupList[i].m_opcodeGroupNumber;
+
+ if (!opcodeTable[opcodeGroupNumber])
+ opcodeTable[opcodeGroupNumber] = newOpcodeGroup;
+ else
+ lastGroups[opcodeGroupNumber]->setNext(newOpcodeGroup);
+ lastGroups[opcodeGroupNumber] = newOpcodeGroup;
+ }
+}
+
+const char* ARMv7D16BitOpcode::doDisassemble()
+{
+ OpcodeGroup* opGroup = opcodeTable[opcodeGroupNumber(m_opcode)];
+
+ while (opGroup) {
+ if (opGroup->matches(static_cast<uint16_t>(m_opcode)))
+ return opGroup->format(this);
+ opGroup = opGroup->next();
+ }
+
+ return defaultFormat();
+}
+
+const char* ARMv7D16BitOpcode::defaultFormat()
+{
+ bufferPrintf(" .word %04x", m_opcode);
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeAddRegisterT2::format()
+{
+ appendInstructionName("add");
+ appendRegisterName(rdn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeAddSPPlusImmediate::format()
+{
+ appendInstructionName("add");
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(RegSP);
+ appendSeparator();
+ appendUnsignedImmediate(immediate8());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeAddSubtract::s_opNames[2] = { "add", "sub" };
+
+const char* ARMv7DOpcodeAddSubtractT1::format()
+{
+ appendInstructionName(opName(), !inITBlock());
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeAddSubtractImmediate3::format()
+{
+ appendInstructionName(opName(), !inITBlock());
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendUnsignedImmediate(immediate3());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeAddSubtractImmediate8::format()
+{
+ appendInstructionName(opName(), !inITBlock());
+ appendRegisterName(rdn());
+ appendSeparator();
+ appendUnsignedImmediate(immediate8());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeBranchConditionalT1::format()
+{
+ if (condition() == 0xe)
+ return defaultFormat();
+
+ if (condition() == 0xf) {
+ appendInstructionName("svc");
+ appendUnsignedImmediate(offset());
+
+ return m_formatBuffer;
+ }
+
+ bufferPrintf(" b%-6.6s", conditionName(condition()));
+ appendPCRelativeOffset(static_cast<int32_t>(offset()) + 2);
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeBranchExchangeT1::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeBranchT2::format()
+{
+ appendInstructionName("b");
+ appendPCRelativeOffset(static_cast<int32_t>(immediate11()) + 2);
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeCompareImmediateT1::format()
+{
+ appendInstructionName("cmp");
+ appendRegisterName(rn());
+ appendSeparator();
+ appendUnsignedImmediate(immediate8());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeCompareRegisterT1::format()
+{
+ appendInstructionName("cmp");
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeCompareRegisterT2::format()
+{
+ appendInstructionName("compare");
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataProcessingRegisterT1::s_opNames[16] = {
+ "and", "eor", "lsl", "lsr", "asr", "adc", "sbc", "ror", "tst", "rsb", "cmp", "cmn", "orr", "mul", "bic", "mvn"
+};
+
+const char* ARMv7DOpcodeDataProcessingRegisterT1::format()
+{
+ appendInstructionName(opName(), inITBlock() && (!(op() == 0x8) || (op() == 0xa) || (op() == 0xb)));
+ appendRegisterName(rdn());
+ appendSeparator();
+ appendRegisterName(rm());
+ if (op() == 0x9) // rsb T1
+ appendString(", #0");
+ else if (op() == 0xd) { // mul T1
+ appendSeparator();
+ appendRegisterName(rdn());
+ }
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeGeneratePCRelativeAddress::format()
+{
+ appendInstructionName("adr");
+ appendRegisterName(rd());
+ appendSeparator();
+ appendPCRelativeOffset(static_cast<int32_t>(immediate8()));
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeLoadFromLiteralPool::format()
+{
+ appendInstructionName("ldr");
+ appendRegisterName(rt());
+ appendSeparator();
+ appendPCRelativeOffset(static_cast<int32_t>(immediate8()));
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeLoadStoreRegisterImmediate::s_opNames[6] = {
+ "str", "ldr", "strb", "ldrb", "strh", "ldrh"
+};
+
+const char* ARMv7DOpcodeLoadStoreRegisterImmediate::format()
+{
+ const char* instructionName = opName();
+
+ if (!instructionName)
+ return defaultFormat();
+
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ if (immediate5()) {
+ appendSeparator();
+ appendUnsignedImmediate(immediate5() << scale());
+ }
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeLoadStoreRegisterOffsetT1::s_opNames[8] = {
+ "str", "strh", "strb", "ldrsb", "ldr", "ldrh", "ldrb", "ldrsh"
+};
+
+const char* ARMv7DOpcodeLoadStoreRegisterOffsetT1::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeLoadStoreRegisterSPRelative::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(RegSP);
+ if (immediate8()) {
+ appendSeparator();
+ appendUnsignedImmediate(immediate8() << 2);
+ }
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeLogicalImmediateT1::format()
+{
+ if (!op() && !immediate5()) {
+ // mov T2
+ appendInstructionName("movs");
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+ }
+
+ appendInstructionName(opName(), !inITBlock());
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendSeparator();
+ appendUnsignedImmediate((op() && !immediate5()) ? 32 : immediate5());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMiscAddSubSP::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(RegSP);
+ appendSeparator();
+ appendRegisterName(RegSP);
+ appendSeparator();
+ appendUnsignedImmediate(immediate7());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMiscBreakpointT1::format()
+{
+ appendInstructionNameNoITBlock("bkpt");
+ appendUnsignedImmediate(immediate8());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeMiscByteHalfwordOps::s_opNames[8] = {
+ "sxth", "sxb", "uxth", "uxtb", "rev", "rev16", "revsh"
+};
+
+const char* ARMv7DOpcodeMiscByteHalfwordOps::format()
+{
+ const char* instructionName = opName();
+
+ if (!instructionName)
+ return defaultFormat();
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMiscCompareAndBranch::format()
+{
+ appendInstructionName(opName());
+ appendPCRelativeOffset(immediate6() + 2);
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeMiscHint16::s_opNames[16] = {
+ "nop", "yield", "wfe", "wfi", "sev"
+};
+
+const char* ARMv7DOpcodeMiscHint16::format()
+{
+ if (opA() > 4)
+ return defaultFormat();
+
+ appendInstructionName(opName());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMiscIfThenT1::format()
+{
+ char opName[6];
+ opName[0] = 'i';
+ opName[1] = 't';
+
+ unsigned condition = firstCondition();
+ unsigned maskBits = mask();
+ unsigned blockLength = 0;
+
+ for (unsigned i = 0; i < 4; ++i) {
+ if (maskBits & (1 << i)) {
+ blockLength = 4 - i;
+ break;
+ }
+ }
+
+ startITBlock(blockLength, condition);
+
+ for (unsigned i = 1; i < blockLength; ++i) {
+ unsigned currMaskBit = (maskBits >> (4-i)) & 0x1;
+ opName[i + 1] = (currMaskBit ^ (condition & 1)) ? 'e' : 't';
+ saveITConditionAt(i, (condition & ~1) | currMaskBit);
+ }
+ opName[blockLength + 1] = '\0';
+
+ appendInstructionNameNoITBlock(opName);
+ appendString(conditionName(condition));
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMiscPushPop::format()
+{
+ appendInstructionName(opName());
+ appendRegisterList(registerMask());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMoveImmediateT1::format()
+{
+ appendInstructionName("mov", !inITBlock());
+ appendRegisterName(rd());
+ appendSeparator();
+ appendUnsignedImmediate(immediate8());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeMoveRegisterT1::format()
+{
+ appendInstructionName("mov");
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+// 32 bit Intructions
+
+void ARMv7D32BitOpcode::init()
+{
+ OpcodeGroup* lastGroups[OpcodeGroup::opcodeTableSize];
+
+ for (unsigned i = 0; i < OpcodeGroup::opcodeTableSize; i++) {
+ opcodeTable[i] = 0;
+ lastGroups[i] = 0;
+ }
+
+ for (unsigned i = 0; i < sizeof(opcode32BitGroupList) / sizeof(Opcode32GroupInitializer); i++) {
+ OpcodeGroup* newOpcodeGroup = new OpcodeGroup(opcode32BitGroupList[i].m_mask, opcode32BitGroupList[i].m_pattern, opcode32BitGroupList[i].m_format);
+ uint16_t opcodeGroupNumber = opcode32BitGroupList[i].m_opcodeGroupNumber;
+
+ if (!opcodeTable[opcodeGroupNumber])
+ opcodeTable[opcodeGroupNumber] = newOpcodeGroup;
+ else
+ lastGroups[opcodeGroupNumber]->setNext(newOpcodeGroup);
+ lastGroups[opcodeGroupNumber] = newOpcodeGroup;
+ }
+}
+
+const char* ARMv7D32BitOpcode::doDisassemble()
+{
+ OpcodeGroup* opGroup = opcodeTable[opcodeGroupNumber(m_opcode)];
+
+ while (opGroup) {
+ if (opGroup->matches(m_opcode))
+ return opGroup->format(this);
+ opGroup = opGroup->next();
+ }
+
+ return defaultFormat();
+}
+
+const char* ARMv7D32BitOpcode::defaultFormat()
+{
+ bufferPrintf(" .long %08x", m_opcode);
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeConditionalBranchT3::format()
+{
+ if (condition() < 0xe)
+ bufferPrintf(" b%-6.6s", conditionName(condition()));
+ else
+ appendInstructionName("b");
+ appendPCRelativeOffset(offset() + 2);
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeBranchOrBranchLink::format()
+{
+ appendInstructionName(isBL() ? "bl" : "b");
+ appendPCRelativeOffset(offset() + 2);
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataProcessingLogicalAndRithmetic::s_opNames[16] = {
+ "and", "bic", "orr", "orn", "eor", 0, "pkh", 0, "add", 0, "adc", "sbc", 0, "sub", "rsb", 0
+};
+
+void ARMv7DOpcodeDataProcessingModifiedImmediate::appendModifiedImmediate(unsigned immediate12)
+{
+ if (!(immediate12 & 0xc00)) {
+ unsigned immediate = 0;
+ unsigned lower8Bits = immediate12 & 0xff;
+
+ switch ((immediate12 >> 8) & 3) {
+ case 0:
+ immediate = lower8Bits;
+ break;
+ case 1:
+ immediate = (lower8Bits << 16) | lower8Bits;
+ break;
+ case 2:
+ immediate = (lower8Bits << 24) | (lower8Bits << 8);
+ break;
+ case 3:
+ immediate = (lower8Bits << 24) | (lower8Bits << 16) | (lower8Bits << 8) | lower8Bits;
+ break;
+ }
+ appendUnsignedImmediate(immediate);
+ return;
+ }
+
+ unsigned immediate8 = 0x80 | (immediate12 & 0x7f);
+ unsigned shiftAmount = 32 - ((immediate12 >> 7) & 0x1f);
+
+ appendUnsignedImmediate(immediate8 << shiftAmount);
+}
+
+const char* ARMv7DOpcodeDataProcessingModifiedImmediate::format()
+{
+ if ((op() == 0x5) || (op() == 0x6) || (op() == 0x7) || (op() == 0x9) || (op() == 0xc) || (op() == 0xf))
+ return defaultFormat();
+
+ const char* instructionName = opName();
+
+ if (rn() == 15) {
+ if (op() == 2) {
+ // MOV T2
+ instructionName = sBit() ? "movs" : "mov";
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendModifiedImmediate(immediate12());
+
+ return m_formatBuffer;
+ }
+
+ if (op() == 3) {
+ // MVN T1
+ instructionName = sBit() ? "mvns" : "mvn";
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendModifiedImmediate(immediate12());
+
+ return m_formatBuffer;
+ }
+ }
+
+ if (rd() == 15) {
+ if (sBit()) {
+ bool testOrCmpInstruction = false;
+
+ switch (op()) {
+ case 0x0:
+ instructionName = "tst";
+ testOrCmpInstruction = true;
+ break;
+ case 0x4:
+ instructionName = "teq";
+ testOrCmpInstruction = true;
+ break;
+ case 0x8:
+ instructionName = "cmn";
+ testOrCmpInstruction = true;
+ break;
+ case 0xd:
+ instructionName = "cmp";
+ testOrCmpInstruction = true;
+ break;
+ }
+
+ if (testOrCmpInstruction) {
+ appendInstructionName(instructionName);
+ appendRegisterName(rn());
+ appendSeparator();
+ appendModifiedImmediate(immediate12());
+
+ return m_formatBuffer;
+ }
+ }
+ }
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendModifiedImmediate(immediate12());
+
+ return m_formatBuffer;
+}
+
+void ARMv7DOpcodeDataProcessingShiftedReg::appendImmShift(unsigned type, unsigned immediate)
+{
+ if (type || immediate) {
+ appendSeparator();
+
+ if (!immediate) {
+ switch (type) {
+ case 1:
+ case 2:
+ immediate = 32;
+ break;
+ case 3:
+ appendString("rrx");
+ return;
+ }
+ }
+
+ appendShiftType(type);
+ appendUnsignedImmediate(immediate);
+ }
+}
+
+const char* ARMv7DOpcodeDataProcessingShiftedReg::format()
+{
+ if ((op() == 0x5) || (op() == 0x7) || (op() == 0x9) || (op() == 0xc) || (op() == 0xf))
+ return defaultFormat();
+
+ if (op() == 6) {
+ // pkhbt or pkhtb
+ if (sBit() || tBit())
+ return defaultFormat();
+
+ if (tbBit())
+ appendInstructionName("pkhtb");
+ else
+ appendInstructionName("pkhbt");
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendImmShift(tbBit() << 1, immediate5());
+
+ return m_formatBuffer;
+ }
+
+ const char* instructionName = opName();
+
+ if (rn() == 15) {
+ if (op() == 2) {
+ if (!type() && !immediate5()) {
+ // MOV T3
+ instructionName = sBit() ? "movs" : "mov";
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+ }
+
+ if (type() == 3 && !immediate5()) {
+ // RRX T1
+ instructionName = sBit() ? "rrx" : "rrx";
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+ }
+
+ // Logical
+ if (sBit())
+ bufferPrintf("%ss ", shiftName(type()));
+ else
+ appendInstructionName(shiftName(type()));
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendSeparator();
+ appendUnsignedImmediate(immediate5());
+
+ return m_formatBuffer;
+ }
+
+ if (op() == 3) {
+ // MVN T2
+ instructionName = sBit() ? "mvns" : "mvn";
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendImmShift(type(), immediate5());
+
+ return m_formatBuffer;
+ }
+ }
+
+ if (rd() == 15) {
+ if (sBit()) {
+ bool testOrCmpInstruction = false;
+
+ switch (op()) {
+ case 0x0:
+ instructionName = "tst";
+ testOrCmpInstruction = true;
+ break;
+ case 0x4:
+ instructionName = "teq";
+ testOrCmpInstruction = true;
+ break;
+ case 0x8:
+ instructionName = "cmn";
+ testOrCmpInstruction = true;
+ break;
+ case 0xd:
+ instructionName = "cmp";
+ testOrCmpInstruction = true;
+ break;
+ }
+
+ if (testOrCmpInstruction) {
+ appendInstructionName(instructionName);
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendImmShift(type(), immediate5());
+
+ return m_formatBuffer;
+ }
+ }
+ }
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+ appendImmShift(type(), immediate5());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeFPTransfer::format()
+{
+ appendInstructionName("vmov");
+
+ if (opL()) {
+ appendFPRegister();
+ appendSeparator();
+ }
+
+ appendRegisterName(rt());
+
+ if (!opL()) {
+ appendSeparator();
+ appendFPRegister();
+ }
+
+ return m_formatBuffer;
+}
+
+void ARMv7DOpcodeFPTransfer::appendFPRegister()
+{
+ if (opC()) {
+ appendFPRegisterName('d', vd());
+ bufferPrintf("[%u]", opH());
+ } else
+ appendFPRegisterName('s', vn());
+}
+
+const char* ARMv7DOpcodeDataProcessingRegShift::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataProcessingRegExtend::s_opExtendNames[8] = {
+ "sxth", "uxth", "sxtb16", "uxtb16", "sxtb", "uxtb"
+};
+
+const char* const ARMv7DOpcodeDataProcessingRegExtend::s_opExtendAndAddNames[8] = {
+ "sxtah", "uxtah", "sxtab16", "uxtab16", "sxtab", "uxtab"
+};
+
+const char* ARMv7DOpcodeDataProcessingRegExtend::format()
+{
+ const char* instructionName;
+
+ if (rn() == 0xf)
+ instructionName = opExtendName();
+ else
+ instructionName = opExtendAndAddName();
+
+ if (!instructionName)
+ return defaultFormat();
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ if (rotate()) {
+ appendSeparator();
+ appendString("ror ");
+ appendUnsignedImmediate(rotate() * 8);
+ }
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataProcessingRegParallel::s_opNames[16] = {
+ "sadd8", "sadd16", "sasx", 0, "ssub8", "ssub16", "ssax", 0,
+ "qadd8", "qadd16", "qasx", 0, "qsub8", "qsub16", "qsax", 0
+};
+
+const char* ARMv7DOpcodeDataProcessingRegParallel::format()
+{
+ const char* instructionName;
+
+ instructionName = opName();
+
+ if (!instructionName)
+ return defaultFormat();
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataProcessingRegMisc::s_opNames[16] = {
+ "qadd", "qdadd", "qsub", "qdsub", "rev", "rev16", "rbit", "revsh",
+ "sel", 0, 0, 0, "clz"
+};
+
+const char* ARMv7DOpcodeDataProcessingRegMisc::format()
+{
+ const char* instructionName;
+
+ instructionName = opName();
+
+ if (!instructionName)
+ return defaultFormat();
+
+ if ((op1() & 0x1) && (rn() != rm()))
+ return defaultFormat();
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+
+ if (op1() == 0x2) { // sel
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+ }
+
+ appendRegisterName(rm());
+
+ if (!(op1() & 0x1)) {
+ appendSeparator();
+ appendRegisterName(rn());
+ }
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeHint32::s_opNames[8] = {
+ "nop", "yield", "wfe", "wfi", "sev"
+};
+
+const char* ARMv7DOpcodeHint32::format()
+{
+ if (isDebugHint()) {
+ appendInstructionName("debug");
+ appendUnsignedImmediate(debugOption());
+
+ return m_formatBuffer;
+ }
+
+ if (op() > 0x4)
+ return defaultFormat();
+
+ appendInstructionName(opName());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataLoad::s_opNames[8] = {
+ "ldrb", "ldrh", "ldr", 0, "ldrsb", "ldrsh"
+};
+
+const char* ARMv7DOpcodeLoadRegister::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+ if (immediate2()) {
+ appendSeparator();
+ appendUnsignedImmediate(immediate2());
+ }
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeLoadSignedImmediate::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ if (pBit()) {
+ if (wBit() || immediate8()) {
+ appendSeparator();
+ if (uBit())
+ appendUnsignedImmediate(immediate8());
+ else
+ appendSignedImmediate(0 - static_cast<int>(immediate8()));
+ }
+ appendCharacter(']');
+ if (wBit())
+ appendCharacter('!');
+ } else {
+ appendCharacter(']');
+ appendSeparator();
+ if (uBit())
+ appendUnsignedImmediate(immediate8());
+ else
+ appendSignedImmediate(0 - static_cast<int>(immediate8()));
+ }
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeLoadUnsignedImmediate::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ if (immediate12()) {
+ appendSeparator();
+ appendUnsignedImmediate(immediate12());
+ }
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeLongMultipleDivide::s_opNames[8] = {
+ "smull", "sdiv", "umull", "udiv", "smlal", "smlsld", "umlal", 0
+};
+
+const char* const ARMv7DOpcodeLongMultipleDivide::s_smlalOpNames[4] = {
+ "smlalbb", "smlalbt", "smlaltb", "smlaltt"
+};
+
+const char* const ARMv7DOpcodeLongMultipleDivide::s_smlaldOpNames[2] = {
+ "smlald", "smlaldx"
+};
+
+const char* const ARMv7DOpcodeLongMultipleDivide::s_smlsldOpNames[2] = {
+ "smlsld", "smlsldx"
+};
+
+const char* ARMv7DOpcodeLongMultipleDivide::format()
+{
+ const char* instructionName = opName();
+
+ switch (op1()) {
+ case 0x0:
+ case 0x2:
+ if (op2())
+ return defaultFormat();
+ break;
+ case 0x1:
+ case 0x3:
+ if (op2() != 0xf)
+ return defaultFormat();
+ break;
+ case 0x4:
+ if ((op2() & 0xc) == 0x8)
+ instructionName = smlalOpName();
+ else if ((op2() & 0xe) == 0xc)
+ instructionName = smlaldOpName();
+ else if (op2())
+ return defaultFormat();
+ break;
+ case 0x5:
+ if ((op2() & 0xe) == 0xc)
+ instructionName = smlaldOpName();
+ else
+ return defaultFormat();
+ break;
+ case 0x6:
+ if (op2() == 0x5)
+ instructionName = "umaal";
+ else if (op2())
+ return defaultFormat();
+ break;
+ case 0x7:
+ return defaultFormat();
+ break;
+ }
+
+ appendInstructionName(instructionName);
+ if ((op1() & 0x5) == 0x1) { // sdiv and udiv
+ if (rt() != 0xf)
+ return defaultFormat();
+ } else {
+ appendRegisterName(rdLo());
+ appendSeparator();
+ }
+ appendRegisterName(rdHi());
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeUnmodifiedImmediate::s_opNames[16] = {
+ "addw", 0, "movw", 0, 0, "subw", "movt", 0,
+ "ssat", "ssat16", "sbfx", "bfi", "usat" , "usat16", "ubfx", 0
+};
+
+const char* ARMv7DOpcodeUnmodifiedImmediate::format()
+{
+ const char* instructionName = opName();
+
+ switch (op() >> 1) {
+ case 0x0:
+ case 0x5:
+ if (rn() == 0xf)
+ instructionName = "adr";
+ break;
+ case 0x9:
+ if (immediate5())
+ instructionName = "ssat";
+ break;
+ case 0xb:
+ if (rn() == 0xf)
+ instructionName = "bfc";
+ break;
+ case 0xd:
+ if (immediate5())
+ instructionName = "usat";
+ break;
+ }
+
+ if (!instructionName)
+ return defaultFormat();
+
+ appendInstructionName(instructionName);
+ appendRegisterName(rd());
+ appendSeparator();
+
+ if ((op() & 0x17) == 0x4) { // movw or movt
+ appendUnsignedImmediate(immediate16());
+
+ return m_formatBuffer;
+ }
+
+ if (!op() || (op() == 0xa)) { // addw, subw and adr
+ if (rn() == 0xf) {
+ int32_t offset;
+
+ if ((op() == 0xa) && (rn() == 0xf))
+ offset = 0 - static_cast<int32_t>(immediate12());
+ else
+ offset = static_cast<int32_t>(immediate12());
+
+ appendPCRelativeOffset(offset);
+
+ return m_formatBuffer;
+ }
+
+ appendRegisterName(rn());
+ appendSeparator();
+ appendUnsignedImmediate(immediate12());
+
+ return m_formatBuffer;
+ }
+
+ if (((op() & 0x15) == 0x10) || (((op() & 0x17) == 0x12) && immediate5())) { // ssat, usat, ssat16 & usat16
+ appendSeparator();
+ appendUnsignedImmediate(bitNumOrSatImmediate() + 1);
+ appendSeparator();
+ appendRegisterName(rn());
+ if (shBit() || immediate5()) {
+ appendSeparator();
+ appendShiftType(shBit() << 1);
+ appendUnsignedImmediate(immediate5());
+ }
+
+ return m_formatBuffer;
+ }
+
+ if (op() == 0x16) { // bfi or bfc
+ int width = static_cast<int>(bitNumOrSatImmediate()) - static_cast<int>(immediate5()) + 1;
+
+ if (width < 0)
+ return defaultFormat();
+
+ if (rn() != 0xf) {
+ appendSeparator();
+ appendRegisterName(rn());
+ }
+ appendSeparator();
+ appendUnsignedImmediate(immediate5());
+ appendSeparator();
+ appendSignedImmediate(width);
+
+ return m_formatBuffer;
+ }
+
+ // Must be sbfx or ubfx
+ appendSeparator();
+ appendRegisterName(rn());
+ appendSeparator();
+ appendUnsignedImmediate(immediate5());
+ appendSeparator();
+ appendUnsignedImmediate(bitNumOrSatImmediate() + 1);
+
+ return m_formatBuffer;
+}
+
+const char* const ARMv7DOpcodeDataStoreSingle::s_opNames[4] = {
+ "strb", "strh", "str", 0
+};
+
+const char* ARMv7DOpcodeDataPushPopSingle::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeStoreSingleImmediate12::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ if (immediate12()) {
+ appendSeparator();
+ appendUnsignedImmediate(immediate12());
+ }
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeStoreSingleImmediate8::format()
+{
+ if (pBit() && uBit() && !wBit()) // Really undecoded strt
+ return defaultFormat();
+
+ if ((rn() == 0xf) || (!pBit() && !wBit()))
+ return defaultFormat();
+
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+
+ if (!pBit()) {
+ appendCharacter(']');
+ appendSeparator();
+ appendSignedImmediate(uBit() ? static_cast<int32_t>(immediate8()) : (0 - static_cast<int32_t>(immediate8())));
+
+ return m_formatBuffer;
+ }
+
+ if (immediate8()) {
+ appendSeparator();
+ appendSignedImmediate(uBit() ? static_cast<int32_t>(immediate8()) : (0 - static_cast<int32_t>(immediate8())));
+ }
+ appendCharacter(']');
+
+ if (wBit())
+ appendCharacter('!');
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeStoreSingleRegister::format()
+{
+ appendInstructionName(opName());
+ appendRegisterName(rt());
+ appendSeparator();
+ appendCharacter('[');
+ appendRegisterName(rn());
+ appendSeparator();
+ appendRegisterName(rm());
+ if (immediate2()) {
+ appendSeparator();
+ appendString("lsl ");
+ appendUnsignedImmediate(immediate2());
+ }
+ appendCharacter(']');
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVMOVDoublePrecision::format()
+{
+ appendInstructionName("vmov");
+ if (op()) {
+ appendRegisterName(rt());
+ appendSeparator();
+ appendRegisterName(rt2());
+ appendSeparator();
+ }
+
+ appendFPRegisterName('d', vm());
+
+ if (!op()) {
+ appendSeparator();
+ appendRegisterName(rt());
+ appendSeparator();
+ appendRegisterName(rt2());
+ }
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVMOVSinglePrecision::format()
+{
+ appendInstructionName("vmov");
+ if (op()) {
+ appendRegisterName(rt());
+ appendSeparator();
+ appendRegisterName(rt2());
+ appendSeparator();
+ }
+
+ appendFPRegisterName('s', vm());
+ appendSeparator();
+ appendFPRegisterName('s', (vm() + 1) % 32);
+
+ if (!op()) {
+ appendSeparator();
+ appendRegisterName(rt());
+ appendSeparator();
+ appendRegisterName(rt2());
+ }
+
+ return m_formatBuffer;
+}
+
+const char* ARMv7DOpcodeVMSR::format()
+{
+ appendInstructionName("vmrs");
+ if (opL()) {
+ if (rt() == 0xf)
+ appendString("apsr_nzcv");
+ else
+ appendRegisterName(rt());
+ appendSeparator();
+ }
+
+ appendString("fpscr");
+
+ if (!opL()) {
+ appendSeparator();
+ appendRegisterName(rt());
+ }
+
+ return m_formatBuffer;
+}
+
+} } // namespace JSC::ARMv7Disassembler
+
+#endif // #if USE(ARMV7_DISASSEMBLER)
diff --git a/Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.h b/Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.h
new file mode 100644
index 000000000..28bddd53e
--- /dev/null
+++ b/Source/JavaScriptCore/disassembler/ARMv7/ARMv7DOpcode.h
@@ -0,0 +1,1142 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ARMv7DOpcode_h
+#define ARMv7DOpcode_h
+
+#if USE(ARMV7_DISASSEMBLER)
+
+#include <stdint.h>
+#include <wtf/Assertions.h>
+
+namespace JSC { namespace ARMv7Disassembler {
+
+class ARMv7DOpcode {
+public:
+ static void init();
+
+ ARMv7DOpcode()
+ : m_opcode(0)
+ , m_bufferOffset(0)
+ {
+ init();
+
+ for (unsigned i = 0; i < 4; i++)
+ m_ifThenConditions[i] = CondNone;
+
+ endITBlock();
+
+ m_formatBuffer[0] = '\0';
+ }
+
+ const char* disassemble(uint16_t*& currentPC);
+
+protected:
+ const unsigned RegSP = 0xd;
+ const unsigned RegLR = 0xe;
+ const unsigned RegPC = 0xf;
+
+ void fetchOpcode(uint16_t*&);
+ bool is32BitInstruction() { return (m_opcode & 0xfffff800) > 0xe000; }
+ bool isFPInstruction() { return (m_opcode & 0xfc000e00) == 0xec000a00; }
+
+ static const char* const s_conditionNames[16];
+ static const char* const s_shiftNames[4];
+ static const char* const s_optionName[8];
+ static const char* const s_specialRegisterNames[3];
+
+ static const char* conditionName(unsigned condition) { return s_conditionNames[condition & 0xf]; }
+ static const char* shiftName(unsigned shiftValue) { return s_shiftNames[shiftValue & 0x3]; }
+
+ bool inITBlock() { return m_ITConditionIndex < m_ITBlocksize; }
+ bool startingITBlock() { return m_ITConditionIndex == m_ITBlocksize + 1; }
+
+ void startITBlock(unsigned, unsigned);
+ void saveITConditionAt(unsigned, unsigned);
+ void endITBlock()
+ {
+ m_currentITCondition = CondNone;
+ m_ITConditionIndex = 0;
+ m_ITBlocksize = 0;
+ }
+
+ void bufferPrintf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
+ void appendInstructionName(const char*, bool addS = false);
+
+ void appendInstructionNameNoITBlock(const char* instructionName)
+ {
+ bufferPrintf(" %-7.7s", instructionName);
+ }
+
+ void appendRegisterName(unsigned);
+ void appendRegisterList(unsigned);
+ void appendFPRegisterName(char, unsigned);
+
+ void appendSeparator()
+ {
+ bufferPrintf(", ");
+ }
+
+ void appendCharacter(const char c)
+ {
+ bufferPrintf("%c", c);
+ }
+
+ void appendString(const char* string)
+ {
+ bufferPrintf("%s", string);
+ }
+
+ void appendShiftType(unsigned shiftValue)
+ {
+ bufferPrintf("%s ", shiftName(shiftValue));
+ }
+
+ void appendSignedImmediate(int immediate)
+ {
+ bufferPrintf("#%d", immediate);
+ }
+
+ void appendUnsignedImmediate(unsigned immediate)
+ {
+ bufferPrintf("#%u", immediate);
+ }
+
+ void appendPCRelativeOffset(int32_t immediate)
+ {
+ bufferPrintf("0x%x", reinterpret_cast<uint32_t>(m_currentPC + immediate));
+ }
+
+ void appendShiftAmount(unsigned amount)
+ {
+ bufferPrintf("lsl #%u", 16 * amount);
+ }
+
+ static const int bufferSize = 81;
+ static const unsigned char CondNone = 0xe;
+ static const unsigned MaxITBlockSize = 4;
+
+ char m_formatBuffer[bufferSize];
+ unsigned char m_ifThenConditions[MaxITBlockSize];
+ uint16_t* m_currentPC;
+ uint32_t m_opcode;
+ int m_bufferOffset;
+ int m_currentITCondition;
+ unsigned m_ITConditionIndex;
+ unsigned m_ITBlocksize;
+
+private:
+ static bool s_initialized;
+};
+
+#define DEFINE_STATIC_FORMAT16(klass, thisObj) \
+ static const char* format(ARMv7D16BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
+
+class ARMv7D16BitOpcode : public ARMv7DOpcode {
+private:
+ class OpcodeGroup {
+ public:
+ OpcodeGroup(uint16_t opcodeMask, uint16_t opcodePattern, const char* (*format)(ARMv7D16BitOpcode*))
+ : m_opcodeMask(opcodeMask)
+ , m_opcodePattern(opcodePattern)
+ , m_format(format)
+ , m_next(0)
+ {
+ }
+
+ void setNext(OpcodeGroup* next)
+ {
+ m_next = next;
+ }
+
+ OpcodeGroup* next()
+ {
+ return m_next;
+ }
+
+ bool matches(uint16_t opcode)
+ {
+ return (opcode & m_opcodeMask) == m_opcodePattern;
+ }
+
+ const char* format(ARMv7D16BitOpcode* thisObj)
+ {
+ return m_format(thisObj);
+ }
+
+ public:
+ static const unsigned opcodeTableSize = 32;
+ static const unsigned opcodeTableMask = opcodeTableSize-1;
+
+ // private:
+ uint16_t m_opcodeMask;
+ uint16_t m_opcodePattern;
+ const char* (*m_format)(ARMv7D16BitOpcode*);
+ OpcodeGroup* m_next;
+ };
+
+public:
+ static void init();
+
+ const char* defaultFormat();
+ const char* doDisassemble();
+
+protected:
+ unsigned rm() { return (m_opcode >> 3) & 0x7; }
+ unsigned rd() { return m_opcode & 0x7; }
+ unsigned opcodeGroupNumber(unsigned opcode) { return (opcode >> 11) & OpcodeGroup::opcodeTableMask; }
+
+private:
+ static OpcodeGroup* opcodeTable[OpcodeGroup::opcodeTableSize];
+};
+
+class ARMv7DOpcodeAddRegisterT2 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0x4400;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddRegisterT2, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rdn() { return ((m_opcode >> 4) & 0x8) | (m_opcode & 0x7); }
+ unsigned rm() { return ((m_opcode >> 3) & 0xf); }
+};
+
+class ARMv7DOpcodeAddSPPlusImmediate : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0xc800;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSPPlusImmediate, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rd() { return (m_opcode >> 8) & 0x7; }
+ unsigned immediate8() { return m_opcode & 0x0ff; }
+};
+
+class ARMv7DOpcodeAddSubtract : public ARMv7D16BitOpcode {
+protected:
+ static const char* const s_opNames[2];
+};
+
+class ARMv7DOpcodeAddSubtractT1 : public ARMv7DOpcodeAddSubtract {
+public:
+ static const uint16_t s_mask = 0xfc00;
+ static const uint16_t s_pattern = 0x1800;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractT1, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return (m_opcode >> 9) & 0x1; }
+ unsigned rm() { return (m_opcode >> 6) & 0x7; }
+ unsigned rn() { return (m_opcode >> 3) & 0x7; }
+};
+
+class ARMv7DOpcodeAddSubtractImmediate3 : public ARMv7DOpcodeAddSubtract {
+public:
+ static const uint16_t s_mask = 0xfc00;
+ static const uint16_t s_pattern = 0x1c00;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractImmediate3, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return (m_opcode >> 9) & 0x1; }
+ unsigned immediate3() { return (m_opcode >> 6) & 0x3; }
+ unsigned rn() { return (m_opcode >> 3) & 0x7; }
+};
+
+class ARMv7DOpcodeAddSubtractImmediate8 : public ARMv7DOpcodeAddSubtract {
+public:
+ static const uint16_t s_mask = 0xf000;
+ static const uint16_t s_pattern = 0x3000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeAddSubtractImmediate8, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return (m_opcode >> 11) & 0x1; }
+ unsigned rdn() { return (m_opcode >> 8) & 0x7; }
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeBranchConditionalT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf000;
+ static const uint16_t s_pattern = 0xd000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchConditionalT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned condition() { return (m_opcode >> 8) & 0xf; }
+ int offset() { return static_cast<int>(m_opcode & 0xff); }
+};
+
+class ARMv7DOpcodeBranchExchangeT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0x4700;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchExchangeT1, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return (m_opcode & 0x80) ? "blx" : "bx"; }
+ unsigned rm() { return ((m_opcode >> 3) & 0xf); }
+};
+
+class ARMv7DOpcodeBranchT2 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0xe000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeBranchT2, thisObj);
+
+protected:
+ const char* format();
+
+ int immediate11() { return static_cast<int>(m_opcode & 0x7ff); }
+};
+
+class ARMv7DOpcodeCompareImmediateT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0x2800;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareImmediateT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rn() { return (m_opcode >> 8) & 0x3; }
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeCompareRegisterT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xffc0;
+ static const uint16_t s_pattern = 0x4280;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareRegisterT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rn() { return m_opcode & 0x7; }
+};
+
+class ARMv7DOpcodeCompareRegisterT2 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0x4500;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeCompareRegisterT2, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rn() { return ((m_opcode >> 4) & 0x8) | (m_opcode & 0x7); }
+ unsigned rm() { return ((m_opcode >> 3) & 0xf); }
+};
+
+class ARMv7DOpcodeDataProcessingRegisterT1 : public ARMv7D16BitOpcode {
+private:
+ static const char* const s_opNames[16];
+
+public:
+ static const uint16_t s_mask = 0xfc00;
+ static const uint16_t s_pattern = 0x4000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeDataProcessingRegisterT1, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return (m_opcode >> 6) & 0xf; }
+
+ unsigned rm() { return (m_opcode >> 3) & 0x7; }
+ unsigned rdn() { return m_opcode & 0x7; }
+};
+
+class ARMv7DOpcodeGeneratePCRelativeAddress : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0xa000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeGeneratePCRelativeAddress, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rd() { return (m_opcode >> 8) & 0x7; }
+ unsigned immediate8() { return m_opcode & 0x0ff; }
+};
+
+class ARMv7DOpcodeLoadFromLiteralPool : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0x4800;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadFromLiteralPool, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rt() { return (m_opcode >> 8) & 0x7; }
+ unsigned immediate8() { return m_opcode & 0x0ff; }
+};
+
+class ARMv7DOpcodeLoadStoreRegisterImmediate : public ARMv7D16BitOpcode {
+private:
+ static const char* const s_opNames[6];
+
+public:
+ const char* format();
+
+protected:
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return ((m_opcode >> 11) & 0x1f) - 0xc; }
+ unsigned immediate5() { return (m_opcode >> 6) & 0x01f; }
+ unsigned rn() { return (m_opcode >> 3) & 0x7; }
+ unsigned rt() { return m_opcode & 0x7; }
+ unsigned scale() { return 2 - (op() >> 1); }
+};
+
+class ARMv7DOpcodeLoadStoreRegisterImmediateWordAndByte : public ARMv7DOpcodeLoadStoreRegisterImmediate {
+public:
+ static const uint16_t s_mask = 0xe000;
+ static const uint16_t s_pattern = 0x6000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate, thisObj);
+};
+
+class ARMv7DOpcodeLoadStoreRegisterImmediateHalfWord : public ARMv7DOpcodeLoadStoreRegisterImmediate {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0x8000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterImmediate, thisObj);
+};
+
+class ARMv7DOpcodeLoadStoreRegisterOffsetT1 : public ARMv7D16BitOpcode {
+private:
+ static const char* const s_opNames[8];
+
+public:
+ static const uint16_t s_mask = 0xf000;
+ static const uint16_t s_pattern = 0x5000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterOffsetT1, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[opB()]; }
+
+ unsigned opB() { return (m_opcode >> 9) & 0x7; }
+ unsigned rm() { return (m_opcode >> 6) & 0x7; }
+ unsigned rn() { return (m_opcode >> 3) & 0x7; }
+ unsigned rt() { return m_opcode & 0x7; }
+};
+
+class ARMv7DOpcodeLoadStoreRegisterSPRelative : public ARMv7D16BitOpcode {
+private:
+ static const char* const s_opNames[8];
+
+public:
+ static const uint16_t s_mask = 0xf000;
+ static const uint16_t s_pattern = 0x9000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLoadStoreRegisterSPRelative, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return op() ? "ldr" : "str"; }
+
+ unsigned op() { return (m_opcode >> 11) & 0x1; }
+ unsigned rt() { return (m_opcode >> 8) & 0x7; }
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeLogicalImmediateT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xe000;
+ static const uint16_t s_pattern = 0x0000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeLogicalImmediateT1, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return shiftName(op()); }
+
+ unsigned op() { return (m_opcode >> 12) & 0x3; }
+ unsigned immediate5() { return (m_opcode >> 6) & 0x1f; }
+};
+
+class ARMv7DOpcodeMiscAddSubSP : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0xb000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscAddSubSP, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return op() ? "sub" : "add"; }
+ unsigned op() { return (m_opcode >> 7) & 0x1; }
+ unsigned immediate7() { return m_opcode & 0x7f; }
+};
+
+class ARMv7DOpcodeMiscByteHalfwordOps : public ARMv7D16BitOpcode {
+private:
+ static const char* const s_opNames[8];
+
+public:
+ static const uint16_t s_mask = 0xf700;
+ static const uint16_t s_pattern = 0xb200;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscByteHalfwordOps, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+ unsigned op() { return ((m_opcode >> 9) & 0x4) || ((m_opcode >> 6) & 0x3); }
+};
+
+class ARMv7DOpcodeMiscBreakpointT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0xbe00;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscBreakpointT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeMiscCompareAndBranch : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf500;
+ static const uint16_t s_pattern = 0xb100;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscCompareAndBranch, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return op() ? "cbnz" : "cbz"; }
+ unsigned op() { return (m_opcode >> 11) & 0x1; }
+ int32_t immediate6() { return ((m_opcode >> 4) & 0x20) | ((m_opcode >> 3) & 0x1f); }
+ unsigned rn() { return m_opcode & 0x7; }
+};
+
+class ARMv7DOpcodeMiscHint16 : public ARMv7D16BitOpcode {
+private:
+ static const char* const s_opNames[16];
+
+public:
+ static const uint16_t s_mask = 0xff0f;
+ static const uint16_t s_pattern = 0xbf00;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscHint16, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[opA()]; }
+ unsigned opA() { return (m_opcode >> 4) & 0xf; }
+};
+
+class ARMv7DOpcodeMiscIfThenT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0xbf00;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscIfThenT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned firstCondition() { return (m_opcode >> 4) & 0xf; }
+ unsigned mask() { return m_opcode & 0xf; }
+};
+
+class ARMv7DOpcodeMiscPushPop : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf600;
+ static const uint16_t s_pattern = 0xb400;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMiscPushPop, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return op() ? "pop" : "push"; }
+ unsigned op() { return (m_opcode >> 11) & 0x1; }
+ unsigned registerMask() { return ((m_opcode << 6) & 0x4000) | (m_opcode & 0x7f); }
+};
+
+class ARMv7DOpcodeMoveImmediateT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xf800;
+ static const uint16_t s_pattern = 0x2000;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveImmediateT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rd() { return (m_opcode >> 8) & 0x3; }
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeMoveRegisterT1 : public ARMv7D16BitOpcode {
+public:
+ static const uint16_t s_mask = 0xff00;
+ static const uint16_t s_pattern = 0x4600;
+
+ DEFINE_STATIC_FORMAT16(ARMv7DOpcodeMoveRegisterT1, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned rd() { return ((m_opcode >> 4) & 0x8) | (m_opcode & 0x7); }
+ unsigned rm() { return ((m_opcode >> 3) & 0xf); }
+};
+
+// 32 Bit instructions
+
+#define DEFINE_STATIC_FORMAT32(klass, thisObj) \
+ static const char* format(ARMv7D32BitOpcode* thisObj) { return reinterpret_cast< klass *>(thisObj)->format(); }
+
+class ARMv7D32BitOpcode : public ARMv7DOpcode {
+private:
+ class OpcodeGroup {
+ public:
+ OpcodeGroup(uint32_t opcodeMask, uint32_t opcodePattern, const char* (*format)(ARMv7D32BitOpcode*))
+ : m_opcodeMask(opcodeMask)
+ , m_opcodePattern(opcodePattern)
+ , m_format(format)
+ , m_next(0)
+ {
+ }
+
+ void setNext(OpcodeGroup* next)
+ {
+ m_next = next;
+ }
+
+ OpcodeGroup* next()
+ {
+ return m_next;
+ }
+
+ bool matches(uint32_t opcode)
+ {
+ return (opcode & m_opcodeMask) == m_opcodePattern;
+ }
+
+ const char* format(ARMv7D32BitOpcode* thisObj)
+ {
+ return m_format(thisObj);
+ }
+
+ public:
+ static const unsigned opcodeTableSize = 16;
+ static const unsigned opcodeTableMask = opcodeTableSize-1;
+
+ private:
+ uint32_t m_opcodeMask;
+ uint32_t m_opcodePattern;
+ const char* (*m_format)(ARMv7D32BitOpcode*);
+ OpcodeGroup* m_next;
+ };
+
+public:
+ static void init();
+
+ const char* defaultFormat();
+ const char* doDisassemble();
+
+protected:
+ unsigned rd() { return (m_opcode >> 8) & 0xf; }
+ unsigned rm() { return m_opcode & 0xf; }
+ unsigned rn() { return (m_opcode >> 16) & 0xf; }
+ unsigned rt() { return (m_opcode >> 12) & 0xf; }
+
+ unsigned opcodeGroupNumber(unsigned opcode) { return (opcode >> 25) & OpcodeGroup::opcodeTableMask; }
+
+private:
+ static OpcodeGroup* opcodeTable[OpcodeGroup::opcodeTableSize];
+};
+
+class ARMv7DOpcodeBranchRelative : public ARMv7D32BitOpcode {
+protected:
+ unsigned sBit() { return (m_opcode >> 26) & 0x1; }
+ unsigned j1() { return (m_opcode >> 13) & 0x1; }
+ unsigned j2() { return (m_opcode >> 11) & 0x1; }
+ unsigned immediate11() { return m_opcode & 0x7ff; }
+};
+
+class ARMv7DOpcodeConditionalBranchT3 : public ARMv7DOpcodeBranchRelative {
+public:
+ static const uint32_t s_mask = 0xf800d000;
+ static const uint32_t s_pattern = 0xf0008000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeConditionalBranchT3, thisObj);
+
+protected:
+ const char* format();
+
+ int32_t offset() { return ((static_cast<int32_t>(sBit() << 31)) >> 12) | static_cast<int32_t>((j1() << 18) | (j2() << 17) | (immediate6() << 11) | immediate11()); }
+ unsigned condition() { return (m_opcode >> 22) & 0xf; }
+ unsigned immediate6() { return (m_opcode >> 16) & 0x3f; }
+};
+
+class ARMv7DOpcodeBranchOrBranchLink : public ARMv7DOpcodeBranchRelative {
+public:
+ static const uint32_t s_mask = 0xf8009000;
+ static const uint32_t s_pattern = 0xf0009000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeBranchOrBranchLink, thisObj);
+
+protected:
+ const char* format();
+
+ int32_t offset() { return ((static_cast<int32_t>(sBit() << 31)) >> 8) | static_cast<int32_t>((~(j1() ^ sBit()) << 22) | (~(j2() ^ sBit()) << 21) | (immediate10() << 11) | immediate11()); }
+ unsigned immediate10() { return (m_opcode >> 16) & 0x3ff; }
+ bool isBL() { return !!((m_opcode >> 14) & 0x1); }
+};
+
+class ARMv7DOpcodeDataProcessingLogicalAndRithmetic : public ARMv7D32BitOpcode {
+protected:
+ static const char* const s_opNames[16];
+};
+
+class ARMv7DOpcodeDataProcessingModifiedImmediate : public ARMv7DOpcodeDataProcessingLogicalAndRithmetic {
+private:
+ void appendImmShift(unsigned, unsigned);
+
+public:
+ static const uint32_t s_mask = 0xfa008000;
+ static const uint32_t s_pattern = 0xf0000000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingModifiedImmediate, thisObj);
+
+protected:
+ const char* format();
+ void appendModifiedImmediate(unsigned);
+
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return (m_opcode >> 21) & 0xf; }
+ unsigned sBit() { return (m_opcode >> 20) & 0x1; }
+ unsigned immediate12() { return ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
+};
+
+class ARMv7DOpcodeDataProcessingShiftedReg : public ARMv7DOpcodeDataProcessingLogicalAndRithmetic {
+private:
+ void appendImmShift(unsigned, unsigned);
+
+public:
+ static const uint32_t s_mask = 0xfe000000;
+ static const uint32_t s_pattern = 0xea000000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingShiftedReg, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned sBit() { return (m_opcode >> 20) & 0x1; }
+ unsigned op() { return (m_opcode >> 21) & 0xf; }
+ unsigned immediate5() { return ((m_opcode >> 10) & 0x1c) | ((m_opcode >> 6) & 0x3); }
+ unsigned type() { return (m_opcode >> 4) & 0x3; }
+ unsigned tbBit() { return (m_opcode >> 5) & 0x1; }
+ unsigned tBit() { return (m_opcode >> 4) & 0x1; }
+};
+
+class ARMv7DOpcodeDataProcessingReg : public ARMv7D32BitOpcode {
+protected:
+ unsigned op1() { return (m_opcode >> 20) & 0xf; }
+ unsigned op2() { return (m_opcode >> 4) & 0xf; }
+};
+
+class ARMv7DOpcodeDataProcessingRegShift : public ARMv7DOpcodeDataProcessingReg {
+public:
+ static const uint32_t s_mask = 0xffe0f0f0;
+ static const uint32_t s_pattern = 0xfa00f000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegShift, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return shiftName((op1() >> 1) & 0x3); }
+};
+
+class ARMv7DOpcodeDataProcessingRegExtend : public ARMv7DOpcodeDataProcessingReg {
+private:
+ static const char* const s_opExtendNames[8];
+ static const char* const s_opExtendAndAddNames[8];
+
+public:
+ static const uint32_t s_mask = 0xff80f0c0;
+ static const uint32_t s_pattern = 0xfa00f080;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegExtend, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opExtendName() { return s_opExtendNames[op1()]; }
+ const char* opExtendAndAddName() { return s_opExtendAndAddNames[op1()]; }
+ unsigned rotate() { return (m_opcode >> 4) & 0x3; }
+};
+
+class ARMv7DOpcodeDataProcessingRegParallel : public ARMv7DOpcodeDataProcessingReg {
+private:
+ static const char* const s_opNames[16];
+
+public:
+ static const uint32_t s_mask = 0xff80f0e0;
+ static const uint32_t s_pattern = 0xfa00f000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegParallel, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[((op1() & 0x7) << 1) | (op2() & 0x1)]; }
+};
+
+class ARMv7DOpcodeDataProcessingRegMisc : public ARMv7DOpcodeDataProcessingReg {
+private:
+ static const char* const s_opNames[16];
+
+public:
+ static const uint32_t s_mask = 0xffc0f0c0;
+ static const uint32_t s_pattern = 0xfa80f080;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataProcessingRegMisc, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[((op1() & 0x3) << 2) | (op2() & 0x3)]; }
+};
+
+class ARMv7DOpcodeHint32 : public ARMv7D32BitOpcode {
+private:
+ static const char* const s_opNames[8];
+
+public:
+ static const uint32_t s_mask = 0xfff0d000;
+ static const uint32_t s_pattern = 0xf3a08000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeHint32, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op()]; }
+
+ bool isDebugHint() { return (m_opcode & 0xf0) == 0xf0; }
+ unsigned debugOption() { return m_opcode & 0xf; }
+ unsigned op() { return m_opcode & 0x7; }
+};
+
+class ARMv7DOpcodeFPTransfer : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffc00e7f;
+ static const uint32_t s_pattern = 0xee000a10;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeFPTransfer, thisObj);
+
+protected:
+ const char* format();
+
+ void appendFPRegister();
+
+ unsigned opH() { return (m_opcode >> 21) & 0x1; }
+ unsigned opL() { return (m_opcode >> 20) & 0x1; }
+ unsigned rt() { return (m_opcode >> 12) & 0xf; }
+ unsigned opC() { return (m_opcode >> 8) & 0x1; }
+ unsigned opB() { return (m_opcode >> 5) & 0x3; }
+ unsigned vd() { return ((m_opcode >> 3) & 0x10) | ((m_opcode >> 16) & 0xf); }
+ unsigned vn() { return ((m_opcode >> 7) & 0x1) | ((m_opcode >> 15) & 0x1e); }
+};
+
+class ARMv7DOpcodeDataLoad : public ARMv7D32BitOpcode {
+protected:
+ static const char* const s_opNames[8];
+
+protected:
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return ((m_opcode >> 22) & 0x4) | ((m_opcode >> 21) & 0x3); }
+};
+
+class ARMv7DOpcodeLoadRegister : public ARMv7DOpcodeDataLoad {
+public:
+ static const uint32_t s_mask = 0xfe900800;
+ static const uint32_t s_pattern = 0xf8100000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadRegister, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned immediate2() { return (m_opcode >> 4) & 0x3; }
+};
+
+class ARMv7DOpcodeLoadSignedImmediate : public ARMv7DOpcodeDataLoad {
+public:
+ static const uint32_t s_mask = 0xfe900800;
+ static const uint32_t s_pattern = 0xf8100800;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadSignedImmediate, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned pBit() { return (m_opcode >> 10) & 0x1; }
+ unsigned uBit() { return (m_opcode >> 9) & 0x1; }
+ unsigned wBit() { return (m_opcode >> 8) & 0x1; }
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeLoadUnsignedImmediate : public ARMv7DOpcodeDataLoad {
+public:
+ static const uint32_t s_mask = 0xfe900000;
+ static const uint32_t s_pattern = 0xf8900000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLoadUnsignedImmediate, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned immediate12() { return m_opcode & 0xfff; }
+};
+
+class ARMv7DOpcodeLongMultipleDivide : public ARMv7D32BitOpcode {
+protected:
+ static const char* const s_opNames[8];
+ static const char* const s_smlalOpNames[4];
+ static const char* const s_smlaldOpNames[2];
+ static const char* const s_smlsldOpNames[2];
+
+public:
+ static const uint32_t s_mask = 0xff800000;
+ static const uint32_t s_pattern = 0xfb800000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeLongMultipleDivide, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op1()]; }
+ const char* smlalOpName() { return s_smlalOpNames[(nBit() << 1) | mBit()]; }
+ const char* smlaldOpName() { return s_smlaldOpNames[mBit()]; }
+ const char* smlsldOpName() { return s_smlsldOpNames[mBit()]; }
+
+ unsigned rdLo() { return rt(); }
+ unsigned rdHi() { return rd(); }
+ unsigned op1() { return (m_opcode >> 20) & 0x7; }
+ unsigned op2() { return (m_opcode >> 4) & 0xf; }
+ unsigned nBit() { return (m_opcode >> 5) & 0x1; }
+ unsigned mBit() { return (m_opcode >> 4) & 0x1; }
+};
+
+class ARMv7DOpcodeDataPushPopSingle : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffef0fff;
+ static const uint32_t s_pattern = 0xf84d0d04;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeDataPushPopSingle, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return op() ? "pop" : "push"; }
+ unsigned op() { return (m_opcode >> 20) & 0x1; }
+};
+
+class ARMv7DOpcodeDataStoreSingle : public ARMv7D32BitOpcode {
+protected:
+ static const char* const s_opNames[4];
+
+protected:
+ const char* opName() { return s_opNames[op()]; }
+
+ unsigned op() { return (m_opcode >> 21) & 0x3; }
+};
+
+class ARMv7DOpcodeStoreSingleImmediate12 : public ARMv7DOpcodeDataStoreSingle {
+public:
+ static const uint32_t s_mask = 0xfff00000;
+ static const uint32_t s_pattern = 0xf8c00000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate12, thisObj);
+
+ const char* format();
+
+protected:
+ unsigned immediate12() { return m_opcode & 0xfff; }
+};
+
+class ARMv7DOpcodeStoreSingleImmediate8 : public ARMv7DOpcodeDataStoreSingle {
+public:
+ static const uint32_t s_mask = 0xfff00800;
+ static const uint32_t s_pattern = 0xf8400800;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleImmediate8, thisObj);
+
+ const char* format();
+
+protected:
+ unsigned pBit() { return (m_opcode >> 10) & 0x1; }
+ unsigned uBit() { return (m_opcode >> 9) & 0x1; }
+ unsigned wBit() { return (m_opcode >> 8) & 0x1; }
+ unsigned immediate8() { return m_opcode & 0xff; }
+};
+
+class ARMv7DOpcodeStoreSingleRegister : public ARMv7DOpcodeDataStoreSingle {
+public:
+ static const uint32_t s_mask = 0xfff00fc0;
+ static const uint32_t s_pattern = 0xf8400000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeStoreSingleRegister, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned immediate2() { return (m_opcode >> 4) & 0x3; }
+};
+
+class ARMv7DOpcodeUnmodifiedImmediate : public ARMv7D32BitOpcode {
+protected:
+ static const char* const s_opNames[16];
+
+public:
+ static const uint32_t s_mask = 0xfa008000;
+ static const uint32_t s_pattern = 0xf2000000;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeUnmodifiedImmediate, thisObj);
+
+protected:
+ const char* format();
+
+ const char* opName() { return s_opNames[op() >> 1]; }
+
+ unsigned op() { return (m_opcode >> 20) & 0x1f; }
+ unsigned shBit() { return (m_opcode >> 21) & 0x1; }
+ unsigned bitNumOrSatImmediate() { return m_opcode & 0x1f; }
+ unsigned immediate5() { return ((m_opcode >> 9) & 0x1c) | ((m_opcode >> 6) & 0x3); }
+ unsigned immediate12() { return ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
+ unsigned immediate16() { return ((m_opcode >> 4) & 0xf000) | ((m_opcode >> 15) & 0x0800) | ((m_opcode >> 4) & 0x0700) | (m_opcode & 0x00ff); }
+};
+
+class ARMv7DOpcodeVMOVDoublePrecision : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffe00fd0;
+ static const uint32_t s_pattern = 0xec400b10;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVDoublePrecision, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned op() { return (m_opcode >> 20) & 0x1; }
+ unsigned rt2() { return (m_opcode >> 16) & 0xf; }
+ unsigned rt() { return (m_opcode >> 16) & 0xf; }
+ unsigned vm() { return (m_opcode & 0xf) | ((m_opcode >> 1) & 0x10); }
+};
+
+class ARMv7DOpcodeVMOVSinglePrecision : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffe00fd0;
+ static const uint32_t s_pattern = 0xec400a10;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMOVSinglePrecision, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned op() { return (m_opcode >> 20) & 0x1; }
+ unsigned rt2() { return (m_opcode >> 16) & 0xf; }
+ unsigned rt() { return (m_opcode >> 16) & 0xf; }
+ unsigned vm() { return ((m_opcode << 1) & 0x1e) | ((m_opcode >> 5) & 0x1); }
+};
+
+class ARMv7DOpcodeVMSR : public ARMv7D32BitOpcode {
+public:
+ static const uint32_t s_mask = 0xffef0fff;
+ static const uint32_t s_pattern = 0xeee10a10;
+
+ DEFINE_STATIC_FORMAT32(ARMv7DOpcodeVMSR, thisObj);
+
+protected:
+ const char* format();
+
+ unsigned opL() { return (m_opcode >> 20) & 0x1; }
+ unsigned rt() { return (m_opcode >> 12) & 0xf; }
+};
+
+
+} } // namespace JSC::ARMv7Disassembler
+
+using JSC::ARMv7Disassembler::ARMv7DOpcode;
+
+#endif // #if USE(ARMV7_DISASSEMBLER)
+
+#endif // ARMv7DOpcode_h
diff --git a/Source/JavaScriptCore/disassembler/ARMv7Disassembler.cpp b/Source/JavaScriptCore/disassembler/ARMv7Disassembler.cpp
new file mode 100644
index 000000000..bfb48953c
--- /dev/null
+++ b/Source/JavaScriptCore/disassembler/ARMv7Disassembler.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Disassembler.h"
+
+#if USE(ARMV7_DISASSEMBLER)
+
+#include "ARMv7/ARMv7DOpcode.h"
+#include "MacroAssemblerCodeRef.h"
+
+namespace JSC {
+
+bool tryToDisassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char* prefix, PrintStream& out)
+{
+ ARMv7DOpcode armOpcode;
+
+ uint16_t* currentPC = reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(codePtr.executableAddress())&~1);
+ uint16_t* endPC = currentPC + (size / sizeof(uint16_t));
+
+ while (currentPC < endPC) {
+ char pcString[12];
+ snprintf(pcString, sizeof(pcString), "0x%x", reinterpret_cast<unsigned>(currentPC));
+ out.printf("%s%10s: %s\n", prefix, pcString, armOpcode.disassemble(currentPC));
+ }
+
+ return true;
+}
+
+} // namespace JSC
+
+#endif // USE(ARMV7_DISASSEMBLER)
+
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86.c b/Source/JavaScriptCore/disassembler/udis86/udis86.c
index fbf76707a..264103423 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86.c
@@ -25,7 +25,6 @@
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86_decode.c b/Source/JavaScriptCore/disassembler/udis86/udis86_decode.c
index a3fd57665..3d567b6df 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86_decode.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86_decode.c
@@ -25,7 +25,6 @@
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86_input.c b/Source/JavaScriptCore/disassembler/udis86/udis86_input.c
index 76c6cccf3..4dbe32876 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86_input.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86_input.c
@@ -24,7 +24,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86_itab_holder.c b/Source/JavaScriptCore/disassembler/udis86/udis86_itab_holder.c
index d5d8726d6..80dda3a19 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86_itab_holder.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86_itab_holder.c
@@ -24,7 +24,6 @@
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86_syn-att.c b/Source/JavaScriptCore/disassembler/udis86/udis86_syn-att.c
index 155a34ca2..0d1c57d48 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86_syn-att.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86_syn-att.c
@@ -24,7 +24,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86_syn-intel.c b/Source/JavaScriptCore/disassembler/udis86/udis86_syn-intel.c
index d250bd449..38251db88 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86_syn-intel.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86_syn-intel.c
@@ -24,7 +24,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/disassembler/udis86/udis86_syn.c b/Source/JavaScriptCore/disassembler/udis86/udis86_syn.c
index 80391b4a0..31a45ea5c 100644
--- a/Source/JavaScriptCore/disassembler/udis86/udis86_syn.c
+++ b/Source/JavaScriptCore/disassembler/udis86/udis86_syn.c
@@ -25,7 +25,6 @@
*/
#include "config.h"
-#include <wtf/Platform.h>
#if USE(UDIS86)
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp
index f94025c1a..aebee6a4e 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.cpp
+++ b/Source/JavaScriptCore/heap/BlockAllocator.cpp
@@ -35,16 +35,17 @@
namespace JSC {
BlockAllocator::BlockAllocator()
- : m_copiedRegionSet(CopiedBlock::blockSize)
+ : m_superRegion()
+ , m_copiedRegionSet(CopiedBlock::blockSize)
, m_markedRegionSet(MarkedBlock::blockSize)
- , m_weakAndMarkStackRegionSet(WeakBlock::blockSize)
+ , m_fourKBBlockRegionSet(WeakBlock::blockSize)
, m_workListRegionSet(CopyWorkListSegment::blockSize)
, m_numberOfEmptyRegions(0)
, m_isCurrentlyAllocating(false)
, m_blockFreeingThreadShouldQuit(false)
, m_blockFreeingThread(createThread(blockFreeingThreadStartFunc, this, "JavaScriptCore::BlockFree"))
{
- ASSERT(m_blockFreeingThread);
+ RELEASE_ASSERT(m_blockFreeingThread);
m_regionLock.Init();
}
@@ -57,6 +58,16 @@ BlockAllocator::~BlockAllocator()
m_emptyRegionCondition.broadcast();
}
waitForThreadCompletion(m_blockFreeingThread);
+ ASSERT(allRegionSetsAreEmpty());
+ ASSERT(m_emptyRegions.isEmpty());
+}
+
+bool BlockAllocator::allRegionSetsAreEmpty() const
+{
+ return m_copiedRegionSet.isEmpty()
+ && m_markedRegionSet.isEmpty()
+ && m_fourKBBlockRegionSet.isEmpty()
+ && m_workListRegionSet.isEmpty();
}
void BlockAllocator::releaseFreeRegions()
@@ -69,7 +80,7 @@ void BlockAllocator::releaseFreeRegions()
region = 0;
else {
region = m_emptyRegions.removeHead();
- ASSERT(region);
+ RELEASE_ASSERT(region);
m_numberOfEmptyRegions--;
}
}
@@ -77,7 +88,7 @@ void BlockAllocator::releaseFreeRegions()
if (!region)
break;
- delete region;
+ region->destroy();
}
}
@@ -141,7 +152,7 @@ void BlockAllocator::blockFreeingThreadMain()
region = 0;
else {
region = m_emptyRegions.removeHead();
- ASSERT(region);
+ RELEASE_ASSERT(region);
m_numberOfEmptyRegions--;
}
}
@@ -149,7 +160,7 @@ void BlockAllocator::blockFreeingThreadMain()
if (!region)
break;
- delete region;
+ region->destroy();
}
}
}
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h
index 90210c1fa..afd3259fe 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.h
+++ b/Source/JavaScriptCore/heap/BlockAllocator.h
@@ -27,6 +27,7 @@
#define BlockAllocator_h
#include "HeapBlock.h"
+#include "Region.h"
#include <wtf/DoublyLinkedList.h>
#include <wtf/Forward.h>
#include <wtf/PageAllocationAligned.h>
@@ -38,123 +39,15 @@ namespace JSC {
class BlockAllocator;
class CopiedBlock;
class CopyWorkListSegment;
+class HandleBlock;
+class VM;
class MarkStackSegment;
class MarkedBlock;
-class Region;
class WeakBlock;
// Simple allocator to reduce VM cost by holding onto blocks of memory for
// short periods of time and then freeing them on a secondary thread.
-class DeadBlock : public HeapBlock<DeadBlock> {
-public:
- DeadBlock(Region*);
-};
-
-inline DeadBlock::DeadBlock(Region* region)
- : HeapBlock<DeadBlock>(region)
-{
-}
-
-class Region : public DoublyLinkedListNode<Region> {
- friend CLASS_IF_GCC DoublyLinkedListNode<Region>;
- friend class BlockAllocator;
-public:
- ~Region();
- static Region* create(size_t blockSize);
- static Region* createCustomSize(size_t blockSize, size_t blockAlignment);
- Region* reset(size_t blockSize);
-
- size_t blockSize() const { return m_blockSize; }
- bool isFull() const { return m_blocksInUse == m_totalBlocks; }
- bool isEmpty() const { return !m_blocksInUse; }
- bool isCustomSize() const { return m_isCustomSize; }
-
- DeadBlock* allocate();
- void deallocate(void*);
-
- static const size_t s_regionSize = 64 * KB;
-
-private:
- Region(PageAllocationAligned&, size_t blockSize, size_t totalBlocks);
-
- PageAllocationAligned m_allocation;
- size_t m_totalBlocks;
- size_t m_blocksInUse;
- size_t m_blockSize;
- bool m_isCustomSize;
- Region* m_prev;
- Region* m_next;
- DoublyLinkedList<DeadBlock> m_deadBlocks;
-};
-
-inline Region* Region::create(size_t blockSize)
-{
- ASSERT(blockSize <= s_regionSize);
- ASSERT(!(s_regionSize % blockSize));
- PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages);
- if (!static_cast<bool>(allocation))
- CRASH();
- return new Region(allocation, blockSize, s_regionSize / blockSize);
-}
-
-inline Region* Region::createCustomSize(size_t blockSize, size_t blockAlignment)
-{
- PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages);
- if (!static_cast<bool>(allocation))
- CRASH();
- Region* region = new Region(allocation, blockSize, 1);
- region->m_isCustomSize = true;
- return region;
-}
-
-inline Region::Region(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks)
- : DoublyLinkedListNode<Region>()
- , m_allocation(allocation)
- , m_totalBlocks(totalBlocks)
- , m_blocksInUse(0)
- , m_blockSize(blockSize)
- , m_isCustomSize(false)
- , m_prev(0)
- , m_next(0)
-{
- ASSERT(allocation);
- char* start = static_cast<char*>(m_allocation.base());
- char* end = start + m_allocation.size();
- for (char* current = start; current < end; current += blockSize)
- m_deadBlocks.append(new (NotNull, current) DeadBlock(this));
-}
-
-inline Region::~Region()
-{
- ASSERT(isEmpty());
- m_allocation.deallocate();
-}
-
-inline Region* Region::reset(size_t blockSize)
-{
- ASSERT(isEmpty());
- PageAllocationAligned allocation = m_allocation;
- return new (NotNull, this) Region(allocation, blockSize, s_regionSize / blockSize);
-}
-
-inline DeadBlock* Region::allocate()
-{
- ASSERT(!isFull());
- m_blocksInUse++;
- return m_deadBlocks.removeHead();
-}
-
-inline void Region::deallocate(void* base)
-{
- ASSERT(base);
- ASSERT(m_blocksInUse);
- ASSERT(base >= m_allocation.base() && base < static_cast<char*>(m_allocation.base()) + m_allocation.size());
- DeadBlock* block = new (NotNull, base) DeadBlock(this);
- m_deadBlocks.push(block);
- m_blocksInUse--;
-}
-
class BlockAllocator {
public:
BlockAllocator();
@@ -178,6 +71,12 @@ private:
, m_blockSize(blockSize)
{
}
+
+ bool isEmpty() const
+ {
+ return m_fullRegions.isEmpty() && m_partialRegions.isEmpty();
+ }
+
DoublyLinkedList<Region> m_fullRegions;
DoublyLinkedList<Region> m_partialRegions;
size_t m_numberOfPartialRegions;
@@ -186,14 +85,16 @@ private:
DeadBlock* tryAllocateFromRegion(RegionSet&, DoublyLinkedList<Region>&, size_t&);
+ bool allRegionSetsAreEmpty() const;
void releaseFreeRegions();
template <typename T> RegionSet& regionSetFor();
+ SuperRegion m_superRegion;
RegionSet m_copiedRegionSet;
RegionSet m_markedRegionSet;
// WeakBlocks and MarkStackSegments use the same RegionSet since they're the same size.
- RegionSet m_weakAndMarkStackRegionSet;
+ RegionSet m_fourKBBlockRegionSet;
RegionSet m_workListRegionSet;
DoublyLinkedList<Region> m_emptyRegions;
@@ -248,7 +149,7 @@ inline DeadBlock* BlockAllocator::allocate()
return block;
}
- Region* newRegion = Region::create(T::blockSize);
+ Region* newRegion = Region::create(&m_superRegion, T::blockSize);
SpinLockHolder locker(&m_regionLock);
m_emptyRegions.push(newRegion);
@@ -261,7 +162,7 @@ inline DeadBlock* BlockAllocator::allocate()
inline DeadBlock* BlockAllocator::allocateCustomSize(size_t blockSize, size_t blockAlignment)
{
size_t realSize = WTF::roundUpToMultipleOf(blockAlignment, blockSize);
- Region* newRegion = Region::createCustomSize(realSize, blockAlignment);
+ Region* newRegion = Region::createCustomSize(&m_superRegion, realSize, blockAlignment);
DeadBlock* block = newRegion->allocate();
ASSERT(block);
return block;
@@ -307,7 +208,7 @@ inline void BlockAllocator::deallocateCustomSize(T* block)
Region* region = block->region();
ASSERT(region->isCustomSize());
region->deallocate(block);
- delete region;
+ region->destroy();
}
template <>
@@ -325,13 +226,13 @@ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkedBlock>()
template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<WeakBlock>()
{
- return m_weakAndMarkStackRegionSet;
+ return m_fourKBBlockRegionSet;
}
template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkStackSegment>()
{
- return m_weakAndMarkStackRegionSet;
+ return m_fourKBBlockRegionSet;
}
template <>
@@ -341,6 +242,12 @@ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<CopyWorkListSegme
}
template <>
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HandleBlock>()
+{
+ return m_fourKBBlockRegionSet;
+}
+
+template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<CopiedBlock> >()
{
return m_copiedRegionSet;
@@ -355,13 +262,13 @@ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkedB
template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<WeakBlock> >()
{
- return m_weakAndMarkStackRegionSet;
+ return m_fourKBBlockRegionSet;
}
template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkStackSegment> >()
{
- return m_weakAndMarkStackRegionSet;
+ return m_fourKBBlockRegionSet;
}
template <>
@@ -370,10 +277,16 @@ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<CopyWor
return m_workListRegionSet;
}
+template <>
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<HandleBlock> >()
+{
+ return m_fourKBBlockRegionSet;
+}
+
template <typename T>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor()
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return *(RegionSet*)0;
}
diff --git a/Source/JavaScriptCore/heap/CardSet.h b/Source/JavaScriptCore/heap/CardSet.h
deleted file mode 100644
index dc44c024d..000000000
--- a/Source/JavaScriptCore/heap/CardSet.h
+++ /dev/null
@@ -1,91 +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. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (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 CardSet_h
-#define CardSet_h
-
-#include <stdint.h>
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
-
-namespace JSC {
-
-template <size_t cardSize, size_t blockSize> class CardSet {
- WTF_MAKE_NONCOPYABLE(CardSet);
-
-public:
- static const size_t cardCount = (blockSize + cardSize - 1) / cardSize;
-
- CardSet()
- {
- memset(m_cards, 0, cardCount);
- }
-
- bool isCardMarkedForAtom(const void*);
- void markCardForAtom(const void*);
- uint8_t& cardForAtom(const void*);
- bool isCardMarked(size_t);
- bool testAndClear(size_t);
-
-private:
- uint8_t m_cards[cardCount];
- COMPILE_ASSERT(!(cardSize & (cardSize - 1)), cardSet_cardSize_is_power_of_two);
- COMPILE_ASSERT(!(cardCount & (cardCount - 1)), cardSet_cardCount_is_power_of_two);
-};
-
-template <size_t cardSize, size_t blockSize> uint8_t& CardSet<cardSize, blockSize>::cardForAtom(const void* ptr)
-{
- ASSERT(ptr > this && ptr < (reinterpret_cast<char*>(this) + cardCount * cardSize));
- uintptr_t card = (reinterpret_cast<uintptr_t>(ptr) / cardSize) % cardCount;
- return m_cards[card];
-}
-
-template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::isCardMarkedForAtom(const void* ptr)
-{
- return cardForAtom(ptr);
-}
-
-template <size_t cardSize, size_t blockSize> void CardSet<cardSize, blockSize>::markCardForAtom(const void* ptr)
-{
- cardForAtom(ptr) = 1;
-}
-
-template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::isCardMarked(size_t i)
-{
- ASSERT(i < cardCount);
- return m_cards[i];
-}
-
-template <size_t cardSize, size_t blockSize> bool CardSet<cardSize, blockSize>::testAndClear(size_t i)
-{
- ASSERT(i < cardCount);
- bool result = m_cards[i];
- m_cards[i] = 0;
- return result;
-}
-
-}
-
-#endif
diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h
index cc60a0103..86cca8cbe 100644
--- a/Source/JavaScriptCore/heap/CopiedBlock.h
+++ b/Source/JavaScriptCore/heap/CopiedBlock.h
@@ -29,8 +29,7 @@
#include "BlockAllocator.h"
#include "CopyWorkList.h"
#include "HeapBlock.h"
-#include "JSValue.h"
-#include "JSValueInlines.h"
+#include "JSCJSValue.h"
#include "Options.h"
#include <wtf/Atomics.h>
#include <wtf/OwnPtr.h>
@@ -117,7 +116,7 @@ inline void CopiedBlock::zeroFillWilderness()
#else
JSValue emptyValue;
JSValue* limit = reinterpret_cast_ptr<JSValue*>(wildernessEnd());
- for (JSValue* currentValue = reinterpret_cast<JSValue*>(wilderness()); currentValue < limit; currentValue++)
+ for (JSValue* currentValue = reinterpret_cast_ptr<JSValue*>(wilderness()); currentValue < limit; currentValue++)
*currentValue = emptyValue;
#endif
}
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp
index b235de1dd..b23e87397 100644
--- a/Source/JavaScriptCore/heap/CopiedSpace.cpp
+++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp
@@ -28,6 +28,7 @@
#include "CopiedSpaceInlines.h"
#include "GCActivityCallback.h"
+#include "Operations.h"
#include "Options.h"
namespace JSC {
@@ -68,7 +69,7 @@ CheckedBoolean CopiedSpace::tryAllocateSlowCase(size_t bytes, void** outPtr)
if (isOversize(bytes))
return tryAllocateOversize(bytes, outPtr);
- ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock());
+ ASSERT(m_heap->vm()->apiLock().currentThreadIsHoldingLock());
m_heap->didAllocate(m_allocator.currentCapacity());
allocateBlock();
@@ -102,7 +103,7 @@ CheckedBoolean CopiedSpace::tryReallocate(void** ptr, size_t oldSize, size_t new
return true;
void* oldPtr = *ptr;
- ASSERT(!m_heap->globalData()->isInitializingObject());
+ ASSERT(!m_heap->vm()->isInitializingObject());
if (CopiedSpace::blockFor(oldPtr)->isOversize() || isOversize(newSize))
return tryReallocateOversize(ptr, oldSize, newSize);
diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlines.h b/Source/JavaScriptCore/heap/CopiedSpaceInlines.h
index 6087cf4c2..47f2414f3 100644
--- a/Source/JavaScriptCore/heap/CopiedSpaceInlines.h
+++ b/Source/JavaScriptCore/heap/CopiedSpaceInlines.h
@@ -30,7 +30,7 @@
#include "CopiedSpace.h"
#include "Heap.h"
#include "HeapBlock.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include <wtf/CheckedBoolean.h>
namespace JSC {
@@ -150,7 +150,7 @@ inline void CopiedSpace::allocateBlock()
inline CheckedBoolean CopiedSpace::tryAllocate(size_t bytes, void** outPtr)
{
- ASSERT(!m_heap->globalData()->isInitializingObject());
+ ASSERT(!m_heap->vm()->isInitializingObject());
if (!m_allocator.tryAllocate(bytes, outPtr))
return tryAllocateSlowCase(bytes, outPtr);
diff --git a/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp b/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp
index f0d7c0c89..e3cc75919 100644
--- a/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp
+++ b/Source/JavaScriptCore/heap/DFGCodeBlocks.cpp
@@ -38,14 +38,12 @@ DFGCodeBlocks::DFGCodeBlocks() { }
DFGCodeBlocks::~DFGCodeBlocks()
{
- Vector<CodeBlock*, 16> toRemove;
+ Vector<OwnPtr<CodeBlock>, 16> toRemove;
for (HashSet<CodeBlock*>::iterator iter = m_set.begin(); iter != m_set.end(); ++iter) {
if ((*iter)->m_dfgData->isJettisoned)
- toRemove.append(*iter);
+ toRemove.append(adoptPtr(*iter));
}
-
- WTF::deleteAllValues(toRemove);
}
void DFGCodeBlocks::jettison(PassOwnPtr<CodeBlock> codeBlockPtr)
@@ -75,14 +73,12 @@ void DFGCodeBlocks::clearMarks()
void DFGCodeBlocks::deleteUnmarkedJettisonedCodeBlocks()
{
- Vector<CodeBlock*, 16> toRemove;
+ Vector<OwnPtr<CodeBlock>, 16> toRemove;
for (HashSet<CodeBlock*>::iterator iter = m_set.begin(); iter != m_set.end(); ++iter) {
if ((*iter)->m_dfgData->isJettisoned && !(*iter)->m_dfgData->mayBeExecuting)
- toRemove.append(*iter);
+ toRemove.append(adoptPtr(*iter));
}
-
- WTF::deleteAllValues(toRemove);
}
void DFGCodeBlocks::traceMarkedCodeBlocks(SlotVisitor& visitor)
diff --git a/Source/JavaScriptCore/heap/GCAssertions.h b/Source/JavaScriptCore/heap/GCAssertions.h
index 9feefe1d1..7c7054deb 100644
--- a/Source/JavaScriptCore/heap/GCAssertions.h
+++ b/Source/JavaScriptCore/heap/GCAssertions.h
@@ -30,16 +30,13 @@
#if ENABLE(GC_VALIDATION)
#define ASSERT_GC_OBJECT_LOOKS_VALID(cell) do { \
- if (!(cell))\
- CRASH();\
- if (cell->unvalidatedStructure()->unvalidatedStructure() != cell->unvalidatedStructure()->unvalidatedStructure()->unvalidatedStructure())\
- CRASH();\
+ RELEASE_ASSERT(cell);\
+ RELEASE_ASSERT(cell->unvalidatedStructure()->unvalidatedStructure() == cell->unvalidatedStructure()->unvalidatedStructure()->unvalidatedStructure()); \
} while (0)
#define ASSERT_GC_OBJECT_INHERITS(object, classInfo) do {\
ASSERT_GC_OBJECT_LOOKS_VALID(object); \
- if (!object->inherits(classInfo)) \
- CRASH();\
+ RELEASE_ASSERT(object->inherits(classInfo)); \
} while (0)
#else
diff --git a/Source/JavaScriptCore/heap/GCThread.cpp b/Source/JavaScriptCore/heap/GCThread.cpp
index 7caa7d588..aa868f1b3 100644
--- a/Source/JavaScriptCore/heap/GCThread.cpp
+++ b/Source/JavaScriptCore/heap/GCThread.cpp
@@ -119,10 +119,10 @@ void GCThread::gcThreadMain()
m_copyVisitor->doneCopying();
break;
case NoPhase:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
case Exit:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
}
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
index 5d2e908f1..b39ab5763 100644
--- a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
+++ b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
@@ -29,7 +29,7 @@
#include "CopyVisitor.h"
#include "CopyVisitorInlines.h"
#include "GCThread.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "MarkStack.h"
#include "SlotVisitor.h"
#include "SlotVisitorInlines.h"
@@ -52,11 +52,11 @@ size_t GCThreadSharedData::childVisitCount()
}
#endif
-GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData)
- : m_globalData(globalData)
- , m_copiedSpace(&globalData->heap.m_storageSpace)
- , m_shouldHashConst(false)
- , m_sharedMarkStack(globalData->heap.blockAllocator())
+GCThreadSharedData::GCThreadSharedData(VM* vm)
+ : m_vm(vm)
+ , m_copiedSpace(&vm->heap.m_storageSpace)
+ , m_shouldHashCons(false)
+ , m_sharedMarkStack(vm->heap.blockAllocator())
, m_numberOfActiveParallelMarkers(0)
, m_parallelMarkersShouldExit(false)
, m_copyIndex(0)
@@ -115,9 +115,9 @@ void GCThreadSharedData::reset()
#endif
m_weakReferenceHarvesters.removeAll();
- if (m_shouldHashConst) {
- m_globalData->resetNewStringsSinceLastHashConst();
- m_shouldHashConst = false;
+ if (m_shouldHashCons) {
+ m_vm->resetNewStringsSinceLastHashCons();
+ m_shouldHashCons = false;
}
}
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.h b/Source/JavaScriptCore/heap/GCThreadSharedData.h
index dbc11b552..47a53ebd8 100644
--- a/Source/JavaScriptCore/heap/GCThreadSharedData.h
+++ b/Source/JavaScriptCore/heap/GCThreadSharedData.h
@@ -39,7 +39,7 @@
namespace JSC {
class GCThread;
-class JSGlobalData;
+class VM;
class CopiedSpace;
class CopyVisitor;
@@ -52,7 +52,7 @@ enum GCPhase {
class GCThreadSharedData {
public:
- GCThreadSharedData(JSGlobalData*);
+ GCThreadSharedData(VM*);
~GCThreadSharedData();
void reset();
@@ -77,10 +77,10 @@ private:
void startNextPhase(GCPhase);
void endCurrentPhase();
- JSGlobalData* m_globalData;
+ VM* m_vm;
CopiedSpace* m_copiedSpace;
- bool m_shouldHashConst;
+ bool m_shouldHashCons;
Vector<GCThread*> m_gcThreads;
diff --git a/Source/JavaScriptCore/heap/Handle.h b/Source/JavaScriptCore/heap/Handle.h
index 3b62e2054..28ac30cd9 100644
--- a/Source/JavaScriptCore/heap/Handle.h
+++ b/Source/JavaScriptCore/heap/Handle.h
@@ -43,14 +43,11 @@ template <class T> class Handle;
// Creating a JSValue Handle is invalid
template <> class Handle<JSValue>;
-// Forward declare WeakGCMap
-template<typename KeyType, typename MappedType, typename FinalizerCallback, typename HashArg, typename KeyTraitsArg> class WeakGCMap;
-
class HandleBase {
template <typename T> friend class Weak;
+ template <typename T> friend class Strong;
friend class HandleSet;
friend struct JSCallbackObjectData;
- template <typename KeyType, typename MappedType, typename FinalizerCallback, typename HashArg, typename KeyTraitsArg> friend class WeakGCMap;
public:
bool operator!() const { return !m_slot || !*m_slot; }
diff --git a/Source/JavaScriptCore/heap/HandleBlock.h b/Source/JavaScriptCore/heap/HandleBlock.h
new file mode 100644
index 000000000..962d37c5e
--- /dev/null
+++ b/Source/JavaScriptCore/heap/HandleBlock.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HandleBlock_h
+#define HandleBlock_h
+
+#include "HeapBlock.h"
+
+namespace JSC {
+
+class DeadBlock;
+class HandleSet;
+class HandleNode;
+
+class HandleBlock : public HeapBlock<HandleBlock> {
+public:
+ static HandleBlock* create(DeadBlock*, HandleSet*);
+ static HandleBlock* blockFor(HandleNode*);
+
+ static const size_t blockSize = 4 * KB;
+
+ HandleSet* handleSet();
+
+ HandleNode* nodes();
+ HandleNode* nodeAtIndex(unsigned);
+ unsigned nodeCapacity();
+
+private:
+ HandleBlock(Region*, HandleSet*);
+
+ char* payload();
+ char* payloadEnd();
+
+ static const size_t s_blockMask = ~(blockSize - 1);
+
+ HandleSet* m_handleSet;
+};
+
+inline HandleBlock* HandleBlock::blockFor(HandleNode* node)
+{
+ return reinterpret_cast<HandleBlock*>(reinterpret_cast<size_t>(node) & s_blockMask);
+}
+
+inline HandleSet* HandleBlock::handleSet()
+{
+ return m_handleSet;
+}
+
+} // namespace JSC
+
+#endif // HandleBlock_h
diff --git a/Source/JavaScriptCore/heap/HandleBlockInlines.h b/Source/JavaScriptCore/heap/HandleBlockInlines.h
new file mode 100644
index 000000000..7c771935e
--- /dev/null
+++ b/Source/JavaScriptCore/heap/HandleBlockInlines.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HandleBlockInlines_h
+#define HandleBlockInlines_h
+
+#include "BlockAllocator.h"
+#include "HandleBlock.h"
+
+namespace JSC {
+
+inline HandleBlock* HandleBlock::create(DeadBlock* block, HandleSet* handleSet)
+{
+ Region* region = block->region();
+ return new (NotNull, block) HandleBlock(region, handleSet);
+}
+
+inline HandleBlock::HandleBlock(Region* region, HandleSet* handleSet)
+ : HeapBlock<HandleBlock>(region)
+ , m_handleSet(handleSet)
+{
+}
+
+inline char* HandleBlock::payloadEnd()
+{
+ return reinterpret_cast<char*>(this) + region()->blockSize();
+}
+
+inline char* HandleBlock::payload()
+{
+ return reinterpret_cast<char*>(this) + WTF::roundUpToMultipleOf<sizeof(double)>(sizeof(HandleBlock));
+}
+
+inline HandleNode* HandleBlock::nodes()
+{
+ return reinterpret_cast_ptr<HandleNode*>(payload());
+}
+
+inline HandleNode* HandleBlock::nodeAtIndex(unsigned i)
+{
+ ASSERT(i < nodeCapacity());
+ return &nodes()[i];
+}
+
+inline unsigned HandleBlock::nodeCapacity()
+{
+ return (payloadEnd() - payload()) / sizeof(HandleNode);
+}
+
+} // namespace JSC
+
+#endif // HandleBlockInlines_h
diff --git a/Source/JavaScriptCore/heap/HandleSet.cpp b/Source/JavaScriptCore/heap/HandleSet.cpp
index a6ccf29eb..fdb554448 100644
--- a/Source/JavaScriptCore/heap/HandleSet.cpp
+++ b/Source/JavaScriptCore/heap/HandleSet.cpp
@@ -26,24 +26,36 @@
#include "config.h"
#include "HandleSet.h"
+#include "HandleBlock.h"
+#include "HandleBlockInlines.h"
#include "HeapRootVisitor.h"
#include "JSObject.h"
+#include "Operations.h"
+#include <wtf/DataLog.h>
namespace JSC {
-HandleSet::HandleSet(JSGlobalData* globalData)
- : m_globalData(globalData)
+HandleSet::HandleSet(VM* vm)
+ : m_vm(vm)
, m_nextToFinalize(0)
{
grow();
}
+HandleSet::~HandleSet()
+{
+ while (!m_blockList.isEmpty())
+ m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead()));
+}
+
void HandleSet::grow()
{
- Node* block = m_blockStack.grow();
- for (int i = m_blockStack.blockLength - 1; i >= 0; --i) {
- Node* node = &block[i];
- new (NotNull, node) Node(this);
+ HandleBlock* newBlock = HandleBlock::create(m_vm->heap.blockAllocator().allocate<HandleBlock>(), this);
+ m_blockList.append(newBlock);
+
+ for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) {
+ Node* node = newBlock->nodeAtIndex(i);
+ new (NotNull, node) Node;
m_freeList.push(node);
}
}
@@ -53,8 +65,7 @@ void HandleSet::visitStrongHandles(HeapRootVisitor& heapRootVisitor)
Node* end = m_strongList.end();
for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
#if ENABLE(GC_VALIDATION)
- if (!isLiveNode(node))
- CRASH();
+ RELEASE_ASSERT(isLiveNode(node));
#endif
heapRootVisitor.visit(node->slot());
}
@@ -64,16 +75,14 @@ void HandleSet::writeBarrier(HandleSlot slot, const JSValue& value)
{
// Forbid assignment to handles during the finalization phase, since it would violate many GC invariants.
// File a bug with stack trace if you hit this.
- if (m_nextToFinalize)
- CRASH();
+ RELEASE_ASSERT(!m_nextToFinalize);
if (!value == !*slot && slot->isCell() == value.isCell())
return;
Node* node = toNode(slot);
#if ENABLE(GC_VALIDATION)
- if (!isLiveNode(node))
- CRASH();
+ RELEASE_ASSERT(isLiveNode(node));
#endif
SentinelLinkedList<Node>::remove(node);
if (!value || !value.isCell()) {
@@ -83,8 +92,7 @@ void HandleSet::writeBarrier(HandleSlot slot, const JSValue& value)
m_strongList.push(node);
#if ENABLE(GC_VALIDATION)
- if (!isLiveNode(node))
- CRASH();
+ RELEASE_ASSERT(isLiveNode(node));
#endif
}
diff --git a/Source/JavaScriptCore/heap/HandleSet.h b/Source/JavaScriptCore/heap/HandleSet.h
index c22ffa418..58251f66a 100644
--- a/Source/JavaScriptCore/heap/HandleSet.h
+++ b/Source/JavaScriptCore/heap/HandleSet.h
@@ -26,27 +26,51 @@
#ifndef HandleSet_h
#define HandleSet_h
-#include <wtf/BlockStack.h>
#include "Handle.h"
+#include "HandleBlock.h"
+#include <wtf/DoublyLinkedList.h>
#include <wtf/HashCountedSet.h>
#include <wtf/SentinelLinkedList.h>
#include <wtf/SinglyLinkedList.h>
namespace JSC {
+class HandleBlock;
class HandleSet;
class HeapRootVisitor;
-class JSGlobalData;
+class VM;
class JSValue;
class SlotVisitor;
+class HandleNode {
+public:
+ HandleNode(WTF::SentinelTag);
+ HandleNode();
+
+ HandleSlot slot();
+ HandleSet* handleSet();
+
+ void setPrev(HandleNode*);
+ HandleNode* prev();
+
+ void setNext(HandleNode*);
+ HandleNode* next();
+
+private:
+ JSValue m_value;
+ HandleNode* m_prev;
+ HandleNode* m_next;
+};
+
class HandleSet {
+ friend class HandleBlock;
public:
static HandleSet* heapFor(HandleSlot);
- HandleSet(JSGlobalData*);
-
- JSGlobalData* globalData();
+ HandleSet(VM*);
+ ~HandleSet();
+
+ VM* vm();
HandleSlot allocate();
void deallocate(HandleSlot);
@@ -60,27 +84,7 @@ public:
template<typename Functor> void forEachStrongHandle(Functor&, const HashCountedSet<JSCell*>& skipSet);
private:
- class Node {
- public:
- Node(WTF::SentinelTag);
- Node(HandleSet*);
-
- HandleSlot slot();
- HandleSet* handleSet();
-
- void setPrev(Node*);
- Node* prev();
-
- void setNext(Node*);
- Node* next();
-
- private:
- JSValue m_value;
- HandleSet* m_handleSet;
- Node* m_prev;
- Node* m_next;
- };
-
+ typedef HandleNode Node;
static HandleSlot toHandle(Node*);
static Node* toNode(HandleSlot);
@@ -90,8 +94,8 @@ private:
bool isLiveNode(Node*);
#endif
- JSGlobalData* m_globalData;
- BlockStack<Node> m_blockStack;
+ VM* m_vm;
+ DoublyLinkedList<HandleBlock> m_blockList;
SentinelLinkedList<Node> m_strongList;
SentinelLinkedList<Node> m_immediateList;
@@ -104,96 +108,94 @@ inline HandleSet* HandleSet::heapFor(HandleSlot handle)
return toNode(handle)->handleSet();
}
-inline JSGlobalData* HandleSet::globalData()
+inline VM* HandleSet::vm()
{
- return m_globalData;
+ return m_vm;
}
-inline HandleSlot HandleSet::toHandle(Node* node)
+inline HandleSlot HandleSet::toHandle(HandleSet::Node* node)
{
return reinterpret_cast<HandleSlot>(node);
}
inline HandleSet::Node* HandleSet::toNode(HandleSlot handle)
{
- return reinterpret_cast<Node*>(handle);
+ return reinterpret_cast<HandleSet::Node*>(handle);
}
inline HandleSlot HandleSet::allocate()
{
// Forbid assignment to handles during the finalization phase, since it would violate many GC invariants.
// File a bug with stack trace if you hit this.
- if (m_nextToFinalize)
- CRASH();
+ RELEASE_ASSERT(!m_nextToFinalize);
+
if (m_freeList.isEmpty())
grow();
- Node* node = m_freeList.pop();
- new (NotNull, node) Node(this);
+ HandleSet::Node* node = m_freeList.pop();
+ new (NotNull, node) HandleSet::Node();
m_immediateList.push(node);
return toHandle(node);
}
inline void HandleSet::deallocate(HandleSlot handle)
{
- Node* node = toNode(handle);
+ HandleSet::Node* node = toNode(handle);
if (node == m_nextToFinalize) {
ASSERT(m_nextToFinalize->next());
m_nextToFinalize = m_nextToFinalize->next();
}
- SentinelLinkedList<Node>::remove(node);
+ SentinelLinkedList<HandleSet::Node>::remove(node);
m_freeList.push(node);
}
-inline HandleSet::Node::Node(HandleSet* handleSet)
- : m_handleSet(handleSet)
- , m_prev(0)
+inline HandleNode::HandleNode()
+ : m_prev(0)
, m_next(0)
{
}
-inline HandleSet::Node::Node(WTF::SentinelTag)
- : m_handleSet(0)
- , m_prev(0)
+inline HandleNode::HandleNode(WTF::SentinelTag)
+ : m_prev(0)
, m_next(0)
{
}
-inline HandleSlot HandleSet::Node::slot()
+inline HandleSlot HandleNode::slot()
{
return &m_value;
}
-inline HandleSet* HandleSet::Node::handleSet()
+inline HandleSet* HandleNode::handleSet()
{
- return m_handleSet;
+ return HandleBlock::blockFor(this)->handleSet();
}
-inline void HandleSet::Node::setPrev(Node* prev)
+inline void HandleNode::setPrev(HandleNode* prev)
{
m_prev = prev;
}
-inline HandleSet::Node* HandleSet::Node::prev()
+inline HandleNode* HandleNode::prev()
{
return m_prev;
}
-inline void HandleSet::Node::setNext(Node* next)
+inline void HandleNode::setNext(HandleNode* next)
{
m_next = next;
}
-inline HandleSet::Node* HandleSet::Node::next()
+inline HandleNode* HandleNode::next()
{
return m_next;
}
template<typename Functor> void HandleSet::forEachStrongHandle(Functor& functor, const HashCountedSet<JSCell*>& skipSet)
{
- Node* end = m_strongList.end();
- for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
+ HandleSet::Node* end = m_strongList.end();
+ for (HandleSet::Node* node = m_strongList.begin(); node != end; node = node->next()) {
JSValue value = *node->slot();
if (!value || !value.isCell())
continue;
diff --git a/Source/JavaScriptCore/heap/HandleStack.cpp b/Source/JavaScriptCore/heap/HandleStack.cpp
index a5653c748..41b2ada5f 100644
--- a/Source/JavaScriptCore/heap/HandleStack.cpp
+++ b/Source/JavaScriptCore/heap/HandleStack.cpp
@@ -28,7 +28,7 @@
#include "HeapRootVisitor.h"
#include "JSObject.h"
-#include "JSValueInlines.h"
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/HandleStack.h b/Source/JavaScriptCore/heap/HandleStack.h
index 858ebf23f..a7ce97650 100644
--- a/Source/JavaScriptCore/heap/HandleStack.h
+++ b/Source/JavaScriptCore/heap/HandleStack.h
@@ -30,8 +30,6 @@
#include <wtf/BlockStack.h>
#include "Handle.h"
-#include <wtf/UnusedParam.h>
-
namespace JSC {
class LocalScope;
diff --git a/Source/JavaScriptCore/heap/HandleTypes.h b/Source/JavaScriptCore/heap/HandleTypes.h
index bdfbcfda3..42a267e57 100644
--- a/Source/JavaScriptCore/heap/HandleTypes.h
+++ b/Source/JavaScriptCore/heap/HandleTypes.h
@@ -26,7 +26,7 @@
#ifndef HandleTypes_h
#define HandleTypes_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index 9ff318b08..35a9bf71f 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -31,10 +31,11 @@
#include "HeapStatistics.h"
#include "IncrementalSweeper.h"
#include "Interpreter.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSONObject.h"
+#include "Operations.h"
#include "Tracing.h"
#include "UnlinkedCodeBlock.h"
#include "WeakSetInlines.h"
@@ -163,17 +164,17 @@ static inline size_t proportionalHeapSize(size_t heapSize, size_t ramSize)
return 1.25 * heapSize;
}
-static inline bool isValidSharedInstanceThreadState(JSGlobalData* globalData)
+static inline bool isValidSharedInstanceThreadState(VM* vm)
{
- return globalData->apiLock().currentThreadIsHoldingLock();
+ return vm->apiLock().currentThreadIsHoldingLock();
}
-static inline bool isValidThreadState(JSGlobalData* globalData)
+static inline bool isValidThreadState(VM* vm)
{
- if (globalData->identifierTable != wtfThreadData().currentIdentifierTable())
+ if (vm->identifierTable != wtfThreadData().currentIdentifierTable())
return false;
- if (globalData->isSharedInstance() && !isValidSharedInstanceThreadState(globalData))
+ if (vm->isSharedInstance() && !isValidSharedInstanceThreadState(vm))
return false;
return true;
@@ -240,7 +241,7 @@ inline PassOwnPtr<TypeCountSet> RecordType::returnValue()
} // anonymous namespace
-Heap::Heap(JSGlobalData* globalData, HeapType heapType)
+Heap::Heap(VM* vm, HeapType heapType)
: m_heapType(heapType)
, m_ramSize(ramSize())
, m_minBytesPerCycle(minHeapSize(m_heapType, m_ramSize))
@@ -249,15 +250,16 @@ Heap::Heap(JSGlobalData* globalData, HeapType heapType)
, m_bytesAllocated(0)
, m_bytesAbandoned(0)
, m_operationInProgress(NoOperation)
+ , m_blockAllocator()
, m_objectSpace(this)
, m_storageSpace(this)
, m_machineThreads(this)
- , m_sharedData(globalData)
+ , m_sharedData(vm)
, m_slotVisitor(m_sharedData)
, m_copyVisitor(m_sharedData)
- , m_handleSet(globalData)
+ , m_handleSet(vm)
, m_isSafeToCollect(false)
- , m_globalData(globalData)
+ , m_vm(vm)
, m_lastGCLength(0)
, m_lastCodeDiscardTime(WTF::currentTime())
, m_activityCallback(DefaultGCActivityCallback::create(this))
@@ -275,12 +277,12 @@ bool Heap::isPagedOut(double deadline)
return m_objectSpace.isPagedOut(deadline) || m_storageSpace.isPagedOut(deadline);
}
-// The JSGlobalData is being destroyed and the collector will never run again.
+// The VM is being destroyed and the collector will never run again.
// Run all pending finalizers now because we won't get another chance.
void Heap::lastChanceToFinalize()
{
- ASSERT(!m_globalData->dynamicGlobalObject);
- ASSERT(m_operationInProgress == NoOperation);
+ RELEASE_ASSERT(!m_vm->dynamicGlobalObject);
+ RELEASE_ASSERT(m_operationInProgress == NoOperation);
m_objectSpace.lastChanceToFinalize();
@@ -330,7 +332,7 @@ void Heap::didAbandon(size_t bytes)
void Heap::protect(JSValue k)
{
ASSERT(k);
- ASSERT(m_globalData->apiLock().currentThreadIsHoldingLock());
+ ASSERT(m_vm->apiLock().currentThreadIsHoldingLock());
if (!k.isCell())
return;
@@ -341,7 +343,7 @@ void Heap::protect(JSValue k)
bool Heap::unprotect(JSValue k)
{
ASSERT(k);
- ASSERT(m_globalData->apiLock().currentThreadIsHoldingLock());
+ ASSERT(m_vm->apiLock().currentThreadIsHoldingLock());
if (!k.isCell())
return false;
@@ -361,12 +363,12 @@ void Heap::markProtectedObjects(HeapRootVisitor& heapRootVisitor)
heapRootVisitor.visit(&it->key);
}
-void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
+void Heap::pushTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempVector)
{
m_tempSortingVectors.append(tempVector);
}
-void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
+void Heap::popTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempVector)
{
ASSERT_UNUSED(tempVector, tempVector == m_tempSortingVectors.last());
m_tempSortingVectors.removeLast();
@@ -374,11 +376,11 @@ void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
void Heap::markTempSortVectors(HeapRootVisitor& heapRootVisitor)
{
- typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
+ typedef Vector<Vector<ValueStringPair, 0, UnsafeVectorOverflow>* > VectorOfValueStringVectors;
VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
- Vector<ValueStringPair>* tempSortingVector = *it;
+ Vector<ValueStringPair, 0, UnsafeVectorOverflow>* tempSortingVector = *it;
Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) {
@@ -400,12 +402,17 @@ void Heap::finalizeUnconditionalFinalizers()
inline JSStack& Heap::stack()
{
- return m_globalData->interpreter->stack();
+ return m_vm->interpreter->stack();
+}
+
+void Heap::canonicalizeCellLivenessData()
+{
+ m_objectSpace.canonicalizeCellLivenessData();
}
void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots)
{
- ASSERT(isValidThreadState(m_globalData));
+ ASSERT(isValidThreadState(m_vm));
ConservativeRoots stackRoots(&m_objectSpace.blocks(), &m_storageSpace);
stack().gatherConservativeRoots(stackRoots);
size_t stackRootCount = stackRoots.size();
@@ -416,13 +423,12 @@ void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots)
}
}
-void Heap::markRoots(bool fullGC)
+void Heap::markRoots()
{
SamplingRegion samplingRegion("Garbage Collection: Tracing");
- COND_GCPHASE(fullGC, MarkFullRoots, MarkYoungRoots);
- UNUSED_PARAM(fullGC);
- ASSERT(isValidThreadState(m_globalData));
+ GCPHASE(MarkRoots);
+ ASSERT(isValidThreadState(m_vm));
#if ENABLE(OBJECT_MARK_LOGGING)
double gcStartTime = WTF::currentTime();
@@ -451,17 +457,10 @@ void Heap::markRoots(bool fullGC)
ConservativeRoots scratchBufferRoots(&m_objectSpace.blocks(), &m_storageSpace);
{
GCPHASE(GatherScratchBufferRoots);
- m_globalData->gatherConservativeRoots(scratchBufferRoots);
+ m_vm->gatherConservativeRoots(scratchBufferRoots);
}
#endif
-#if ENABLE(GGC)
- MarkedBlock::DirtyCellVector dirtyCells;
- if (!fullGC) {
- GCPHASE(GatheringDirtyCells);
- m_objectSpace.gatherDirtyCells(dirtyCells);
- } else
-#endif
{
GCPHASE(clearMarks);
m_objectSpace.clearMarks();
@@ -474,24 +473,15 @@ void Heap::markRoots(bool fullGC)
{
ParallelModeEnabler enabler(visitor);
-#if ENABLE(GGC)
- {
- size_t dirtyCellCount = dirtyCells.size();
- GCPHASE(VisitDirtyCells);
- GCCOUNTER(DirtyCellCount, dirtyCellCount);
- for (size_t i = 0; i < dirtyCellCount; i++) {
- heapRootVisitor.visitChildren(dirtyCells[i]);
- visitor.donateAndDrain();
- }
- }
-#endif
- if (m_globalData->codeBlocksBeingCompiled.size()) {
+ if (m_vm->codeBlocksBeingCompiled.size()) {
GCPHASE(VisitActiveCodeBlock);
- for (size_t i = 0; i < m_globalData->codeBlocksBeingCompiled.size(); i++)
- m_globalData->codeBlocksBeingCompiled[i]->visitAggregate(visitor);
+ for (size_t i = 0; i < m_vm->codeBlocksBeingCompiled.size(); i++)
+ m_vm->codeBlocksBeingCompiled[i]->visitAggregate(visitor);
}
+ m_vm->smallStrings.visitStrongReferences(visitor);
+
{
GCPHASE(VisitMachineRoots);
MARK_LOG_ROOT(visitor, "C++ Stack");
@@ -533,10 +523,10 @@ void Heap::markRoots(bool fullGC)
visitor.donateAndDrain();
}
}
- if (m_globalData->exception) {
+ if (m_vm->exception) {
GCPHASE(MarkingException);
MARK_LOG_ROOT(visitor, "Exceptions");
- heapRootVisitor.visit(&m_globalData->exception);
+ heapRootVisitor.visit(&m_vm->exception);
visitor.donateAndDrain();
}
@@ -668,7 +658,7 @@ void Heap::deleteAllCompiledCode()
{
// If JavaScript is running, it's not safe to delete code, since we'll end
// up deleting code that is live on the stack.
- if (m_globalData->dynamicGlobalObject)
+ if (m_vm->dynamicGlobalObject)
return;
for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) {
@@ -714,12 +704,11 @@ void Heap::collect(SweepToggle sweepToggle)
SamplingRegion samplingRegion("Garbage Collection");
GCPHASE(Collect);
- ASSERT(globalData()->apiLock().currentThreadIsHoldingLock());
- ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
+ ASSERT(vm()->apiLock().currentThreadIsHoldingLock());
+ RELEASE_ASSERT(vm()->identifierTable == wtfThreadData().currentIdentifierTable());
ASSERT(m_isSafeToCollect);
JAVASCRIPTCORE_GC_BEGIN();
- if (m_operationInProgress != NoOperation)
- CRASH();
+ RELEASE_ASSERT(m_operationInProgress == NoOperation);
m_operationInProgress = Collection;
m_activityCallback->willCollect();
@@ -730,19 +719,12 @@ void Heap::collect(SweepToggle sweepToggle)
m_lastCodeDiscardTime = WTF::currentTime();
}
-#if ENABLE(GGC)
- bool fullGC = sweepToggle == DoSweep;
- if (!fullGC)
- fullGC = (capacity() > 4 * m_sizeAfterLastCollect);
-#else
- bool fullGC = true;
-#endif
{
GCPHASE(Canonicalize);
m_objectSpace.canonicalizeCellLivenessData();
}
- markRoots(fullGC);
+ markRoots();
{
GCPHASE(ReapingWeakHandles);
@@ -766,7 +748,7 @@ void Heap::collect(SweepToggle sweepToggle)
{
GCPHASE(finalizeSmallStrings);
- m_globalData->smallStrings.finalizeSmallStrings();
+ m_vm->smallStrings.finalizeSmallStrings();
}
{
@@ -774,6 +756,11 @@ void Heap::collect(SweepToggle sweepToggle)
deleteUnmarkedCompiledCode();
}
+ {
+ GCPHASE(DeleteSourceProviderCaches);
+ m_vm->clearSourceProviderCaches();
+ }
+
if (sweepToggle == DoSweep) {
SamplingRegion samplingRegion("Garbage Collection: Sweeping");
GCPHASE(Sweeping);
@@ -793,23 +780,22 @@ void Heap::collect(SweepToggle sweepToggle)
if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize())
HeapStatistics::exitWithFailure();
- if (fullGC) {
- m_sizeAfterLastCollect = currentHeapSize;
+ m_sizeAfterLastCollect = currentHeapSize;
+
+ // To avoid pathological GC churn in very small and very large heaps, we set
+ // the new allocation limit based on the current size of the heap, with a
+ // fixed minimum.
+ size_t maxHeapSize = max(minHeapSize(m_heapType, m_ramSize), proportionalHeapSize(currentHeapSize, m_ramSize));
+ m_bytesAllocatedLimit = maxHeapSize - currentHeapSize;
- // To avoid pathological GC churn in very small and very large heaps, we set
- // the new allocation limit based on the current size of the heap, with a
- // fixed minimum.
- size_t maxHeapSize = max(minHeapSize(m_heapType, m_ramSize), proportionalHeapSize(currentHeapSize, m_ramSize));
- m_bytesAllocatedLimit = maxHeapSize - currentHeapSize;
- }
m_bytesAllocated = 0;
double lastGCEndTime = WTF::currentTime();
m_lastGCLength = lastGCEndTime - lastGCStartTime;
if (Options::recordGCPauseTimes())
HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime);
- if (m_operationInProgress != Collection)
- CRASH();
+ RELEASE_ASSERT(m_operationInProgress == Collection);
+
m_operationInProgress = NoOperation;
JAVASCRIPTCORE_GC_END();
@@ -828,19 +814,19 @@ void Heap::markDeadObjects()
m_objectSpace.forEachDeadCell<MarkObject>();
}
-void Heap::setActivityCallback(GCActivityCallback* activityCallback)
+void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
{
m_activityCallback = activityCallback;
}
GCActivityCallback* Heap::activityCallback()
{
- return m_activityCallback;
+ return m_activityCallback.get();
}
IncrementalSweeper* Heap::sweeper()
{
- return m_sweeper;
+ return m_sweeper.get();
}
void Heap::setGarbageCollectionTimerEnabled(bool enable)
@@ -856,7 +842,7 @@ void Heap::didAllocate(size_t bytes)
bool Heap::isValidAllocation(size_t)
{
- if (!isValidThreadState(m_globalData))
+ if (!isValidThreadState(m_vm))
return false;
if (m_operationInProgress != NoOperation)
@@ -883,15 +869,6 @@ void Heap::addCompiledCode(ExecutableBase* executable)
m_compiledCode.append(executable);
}
-void Heap::didStartVMShutdown()
-{
- m_activityCallback->didStartVMShutdown();
- m_activityCallback = 0;
- m_sweeper->didStartVMShutdown();
- m_sweeper = 0;
- lastChanceToFinalize();
-}
-
class Zombify : public MarkedBlock::VoidFunctor {
public:
void operator()(JSCell* cell)
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index 2df365643..8266f5fd5 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -55,7 +55,7 @@ namespace JSC {
class IncrementalSweeper;
class JITStubRoutine;
class JSCell;
- class JSGlobalData;
+ class VM;
class JSStack;
class JSValue;
class LiveObjectIterator;
@@ -96,16 +96,16 @@ namespace JSC {
static void writeBarrier(const JSCell*, JSCell*);
static uint8_t* addressOfCardFor(JSCell*);
- Heap(JSGlobalData*, HeapType);
+ Heap(VM*, HeapType);
~Heap();
JS_EXPORT_PRIVATE void lastChanceToFinalize();
- JSGlobalData* globalData() const { return m_globalData; }
+ VM* vm() const { return m_vm; }
MarkedSpace& objectSpace() { return m_objectSpace; }
MachineThreads& machineThreads() { return m_machineThreads; }
JS_EXPORT_PRIVATE GCActivityCallback* activityCallback();
- JS_EXPORT_PRIVATE void setActivityCallback(GCActivityCallback*);
+ JS_EXPORT_PRIVATE void setActivityCallback(PassOwnPtr<GCActivityCallback>);
JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);
JS_EXPORT_PRIVATE IncrementalSweeper* sweeper();
@@ -113,7 +113,6 @@ namespace JSC {
// true if an allocation or collection is in progress
inline bool isBusy();
- MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); }
MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); }
MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); }
MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); }
@@ -151,8 +150,8 @@ namespace JSC {
JS_EXPORT_PRIVATE PassOwnPtr<TypeCountSet> objectTypeCounts();
void showStatistics();
- void pushTempSortVector(Vector<ValueStringPair>*);
- void popTempSortVector(Vector<ValueStringPair>*);
+ void pushTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>*);
+ void popTempSortVector(Vector<ValueStringPair, 0, UnsafeVectorOverflow>*);
HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = adoptPtr(new HashSet<MarkedArgumentBuffer*>); return *m_markListSet; }
@@ -162,6 +161,7 @@ namespace JSC {
HandleSet* handleSet() { return &m_handleSet; }
HandleStack* handleStack() { return &m_handleStack; }
+ void canonicalizeCellLivenessData();
void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
double lastGCLength() { return m_lastGCLength; }
@@ -173,7 +173,6 @@ namespace JSC {
void didAbandon(size_t);
bool isPagedOut(double deadline);
- void didStartVMShutdown();
const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }
@@ -181,6 +180,7 @@ namespace JSC {
friend class CodeBlock;
friend class CopiedBlock;
friend class GCAwareJITStubRoutine;
+ friend class HandleSet;
friend class JITStubRoutine;
friend class LLIntOffsetsExtractor;
friend class MarkedSpace;
@@ -189,6 +189,7 @@ namespace JSC {
friend class CopiedSpace;
friend class CopyVisitor;
friend class SlotVisitor;
+ friend class SuperRegion;
friend class IncrementalSweeper;
friend class HeapStatistics;
friend class WeakSet;
@@ -209,7 +210,7 @@ namespace JSC {
JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
JS_EXPORT_PRIVATE void reportExtraMemoryCostSlowCase(size_t);
- void markRoots(bool fullGC);
+ void markRoots();
void markProtectedObjects(HeapRootVisitor&);
void markTempSortVectors(HeapRootVisitor&);
void copyBackingStores();
@@ -241,7 +242,7 @@ namespace JSC {
#endif
ProtectCountSet m_protectedValues;
- Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
+ Vector<Vector<ValueStringPair, 0, UnsafeVectorOverflow>* > m_tempSortingVectors;
OwnPtr<HashSet<MarkedArgumentBuffer*> > m_markListSet;
MachineThreads m_machineThreads;
@@ -258,14 +259,14 @@ namespace JSC {
bool m_isSafeToCollect;
- JSGlobalData* m_globalData;
+ VM* m_vm;
double m_lastGCLength;
double m_lastCodeDiscardTime;
DoublyLinkedList<ExecutableBase> m_compiledCode;
- GCActivityCallback* m_activityCallback;
- IncrementalSweeper* m_sweeper;
+ OwnPtr<GCActivityCallback> m_activityCallback;
+ OwnPtr<IncrementalSweeper> m_sweeper;
Vector<MarkedBlock*> m_blockSnapshot;
};
@@ -286,11 +287,7 @@ namespace JSC {
{
if (Options::gcMaxHeapSize())
return m_bytesAllocated > Options::gcMaxHeapSize() && m_isSafeToCollect && m_operationInProgress == NoOperation;
-#if ENABLE(GGC)
- return m_objectSpace.nurseryWaterMark() >= m_minBytesPerCycle && m_isSafeToCollect && m_operationInProgress == NoOperation;
-#else
return m_bytesAllocated > m_bytesAllocatedLimit && m_isSafeToCollect && m_operationInProgress == NoOperation;
-#endif
}
bool Heap::isBusy()
@@ -332,37 +329,13 @@ namespace JSC {
inline bool Heap::isWriteBarrierEnabled()
{
-#if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
+#if ENABLE(WRITE_BARRIER_PROFILING)
return true;
#else
return false;
#endif
}
-#if ENABLE(GGC)
- inline uint8_t* Heap::addressOfCardFor(JSCell* cell)
- {
- return MarkedBlock::blockFor(cell)->addressOfCardFor(cell);
- }
-
- inline void Heap::writeBarrier(const JSCell* owner, JSCell*)
- {
- WriteBarrierCounters::countWriteBarrier();
- MarkedBlock* block = MarkedBlock::blockFor(owner);
- if (block->isMarked(owner))
- block->setDirtyObject(owner);
- }
-
- inline void Heap::writeBarrier(const JSCell* owner, JSValue value)
- {
- if (!value)
- return;
- if (!value.isCell())
- return;
- writeBarrier(owner, value.asCell());
- }
-#else
-
inline void Heap::writeBarrier(const JSCell*, JSCell*)
{
WriteBarrierCounters::countWriteBarrier();
@@ -372,7 +345,6 @@ namespace JSC {
{
WriteBarrierCounters::countWriteBarrier();
}
-#endif
inline void Heap::reportExtraMemoryCost(size_t cost)
{
diff --git a/Source/JavaScriptCore/heap/HeapBlock.h b/Source/JavaScriptCore/heap/HeapBlock.h
index 677eaacd4..6f2a74c08 100644
--- a/Source/JavaScriptCore/heap/HeapBlock.h
+++ b/Source/JavaScriptCore/heap/HeapBlock.h
@@ -45,7 +45,7 @@ template<typename T>
class HeapBlock : public DoublyLinkedListNode<T> {
friend CLASS_IF_GCC DoublyLinkedListNode<T>;
public:
- static HeapBlock* destroy(HeapBlock* block)
+ static HeapBlock* destroy(HeapBlock* block) WARN_UNUSED_RETURN
{
static_cast<T*>(block)->~T();
return block;
diff --git a/Source/JavaScriptCore/heap/HeapStatistics.cpp b/Source/JavaScriptCore/heap/HeapStatistics.cpp
index 2b98fe711..55e3e9d9d 100644
--- a/Source/JavaScriptCore/heap/HeapStatistics.cpp
+++ b/Source/JavaScriptCore/heap/HeapStatistics.cpp
@@ -28,6 +28,7 @@
#include "Heap.h"
#include "JSObject.h"
+#include "Operations.h"
#include "Options.h"
#include <stdlib.h>
#if OS(UNIX)
diff --git a/Source/JavaScriptCore/heap/HeapStatistics.h b/Source/JavaScriptCore/heap/HeapStatistics.h
index ce7a40a79..13a29efbe 100644
--- a/Source/JavaScriptCore/heap/HeapStatistics.h
+++ b/Source/JavaScriptCore/heap/HeapStatistics.h
@@ -26,6 +26,7 @@
#ifndef HeapStatistics_h
#define HeapStatistics_h
+#include "JSExportMacros.h"
#include <wtf/Deque.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/HeapTimer.cpp b/Source/JavaScriptCore/heap/HeapTimer.cpp
index d69ee9607..a30a28b45 100644
--- a/Source/JavaScriptCore/heap/HeapTimer.cpp
+++ b/Source/JavaScriptCore/heap/HeapTimer.cpp
@@ -38,6 +38,8 @@
#include <QMutexLocker>
#include <QThread>
#include <QTimerEvent>
+#elif PLATFORM(EFL)
+#include <Ecore.h>
#endif
namespace JSC {
@@ -46,70 +48,67 @@ namespace JSC {
const CFTimeInterval HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
-HeapTimer::HeapTimer(JSGlobalData* globalData, CFRunLoopRef runLoop)
- : m_globalData(globalData)
- , m_runLoop(runLoop)
+static const void* retainAPILock(const void* info)
{
- memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
- m_context.info = this;
- m_timer.adoptCF(CFRunLoopTimerCreate(0, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
- CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+ static_cast<JSLock*>(const_cast<void*>(info))->ref();
+ return info;
}
-HeapTimer::~HeapTimer()
+static void releaseAPILock(const void* info)
{
- CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
- CFRunLoopTimerInvalidate(m_timer.get());
+ static_cast<JSLock*>(const_cast<void*>(info))->deref();
}
-void HeapTimer::synchronize()
+HeapTimer::HeapTimer(VM* vm, CFRunLoopRef runLoop)
+ : m_vm(vm)
+ , m_runLoop(runLoop)
{
- if (CFRunLoopGetCurrent() == m_runLoop.get())
- return;
- CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
- m_runLoop = CFRunLoopGetCurrent();
+ memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
+ m_context.info = &vm->apiLock();
+ m_context.retain = retainAPILock;
+ m_context.release = releaseAPILock;
+ m_timer = adoptCF(CFRunLoopTimerCreate(0, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
}
-void HeapTimer::invalidate()
+HeapTimer::~HeapTimer()
{
- m_globalData = 0;
- CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() - s_decade);
+ CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+ CFRunLoopTimerInvalidate(m_timer.get());
}
-void HeapTimer::didStartVMShutdown()
+void HeapTimer::timerDidFire(CFRunLoopTimerRef timer, void* context)
{
- if (CFRunLoopGetCurrent() == m_runLoop.get()) {
- invalidate();
- delete this;
- return;
- }
- ASSERT(!m_globalData->apiLock().currentThreadIsHoldingLock());
- MutexLocker locker(m_shutdownMutex);
- invalidate();
-}
+ JSLock* apiLock = static_cast<JSLock*>(context);
+ apiLock->lock();
-void HeapTimer::timerDidFire(CFRunLoopTimerRef, void* info)
-{
- HeapTimer* agent = static_cast<HeapTimer*>(info);
- agent->m_shutdownMutex.lock();
- if (!agent->m_globalData) {
- agent->m_shutdownMutex.unlock();
- delete agent;
+ VM* vm = apiLock->vm();
+ // The VM has been destroyed, so we should just give up.
+ if (!vm) {
+ apiLock->unlock();
return;
}
+
+ HeapTimer* heapTimer = 0;
+ if (vm->heap.activityCallback()->m_timer.get() == timer)
+ heapTimer = vm->heap.activityCallback();
+ else if (vm->heap.sweeper()->m_timer.get() == timer)
+ heapTimer = vm->heap.sweeper();
+ else
+ RELEASE_ASSERT_NOT_REACHED();
+
{
- // We don't ref here to prevent us from resurrecting the ref count of a "dead" JSGlobalData.
- APIEntryShim shim(agent->m_globalData, APIEntryShimWithoutLock::DontRefGlobalData);
- agent->doWork();
+ APIEntryShim shim(vm);
+ heapTimer->doWork();
}
- agent->m_shutdownMutex.unlock();
+
+ apiLock->unlock();
}
#elif PLATFORM(BLACKBERRY)
-HeapTimer::HeapTimer(JSGlobalData* globalData)
- : m_globalData(globalData)
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
, m_timer(this, &HeapTimer::timerDidFire)
{
// FIXME: Implement HeapTimer for other threads.
@@ -126,23 +125,14 @@ void HeapTimer::timerDidFire()
doWork();
}
-void HeapTimer::synchronize()
-{
-}
-
void HeapTimer::invalidate()
{
}
-void HeapTimer::didStartVMShutdown()
-{
- delete this;
-}
-
#elif PLATFORM(QT)
-HeapTimer::HeapTimer(JSGlobalData* globalData)
- : m_globalData(globalData)
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
, m_newThread(0)
, m_mutex(QMutex::NonRecursive)
{
@@ -153,6 +143,8 @@ HeapTimer::HeapTimer(JSGlobalData* globalData)
HeapTimer::~HeapTimer()
{
+ QMutexLocker lock(&m_mutex);
+ m_timer.stop();
}
void HeapTimer::timerEvent(QTimerEvent*)
@@ -163,7 +155,7 @@ void HeapTimer::timerEvent(QTimerEvent*)
return;
}
- APIEntryShim shim(m_globalData, APIEntryShimWithoutLock::DontRefGlobalData);
+ APIEntryShim shim(m_vm);
doWork();
}
@@ -175,49 +167,51 @@ void HeapTimer::customEvent(QEvent*)
m_newThread = 0;
}
-void HeapTimer::synchronize()
+#elif PLATFORM(EFL)
+
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
+ , m_timer(0)
{
- if (thread() != QThread::currentThread()) {
- // We can only move from the objects own thread to another, so we fire an
- // event into the owning thread to trigger the move.
- // This must be processed before any timerEvents so giving it high priority.
- QMutexLocker lock(&m_mutex);
- m_newThread = QThread::currentThread();
- QCoreApplication::postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
- }
}
-void HeapTimer::invalidate()
+HeapTimer::~HeapTimer()
{
- QMutexLocker lock(&m_mutex);
- m_timer.stop();
+ stop();
}
-void HeapTimer::didStartVMShutdown()
+Ecore_Timer* HeapTimer::add(double delay, void* agent)
{
- invalidate();
- if (thread() == QThread::currentThread())
- delete this;
- else
- deleteLater();
+ return ecore_timer_add(delay, reinterpret_cast<Ecore_Task_Cb>(timerEvent), agent);
}
-
-#else
-HeapTimer::HeapTimer(JSGlobalData* globalData)
- : m_globalData(globalData)
+
+void HeapTimer::stop()
{
+ if (!m_timer)
+ return;
+
+ ecore_timer_del(m_timer);
+ m_timer = 0;
}
-HeapTimer::~HeapTimer()
+bool HeapTimer::timerEvent(void* info)
{
+ HeapTimer* agent = static_cast<HeapTimer*>(info);
+
+ APIEntryShim shim(agent->m_vm);
+ agent->doWork();
+ agent->m_timer = 0;
+
+ return ECORE_CALLBACK_CANCEL;
}
-void HeapTimer::didStartVMShutdown()
+#else
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
{
- delete this;
}
-void HeapTimer::synchronize()
+HeapTimer::~HeapTimer()
{
}
diff --git a/Source/JavaScriptCore/heap/HeapTimer.h b/Source/JavaScriptCore/heap/HeapTimer.h
index 66d28f228..f7576edd9 100644
--- a/Source/JavaScriptCore/heap/HeapTimer.h
+++ b/Source/JavaScriptCore/heap/HeapTimer.h
@@ -38,11 +38,13 @@
#include <QMutex>
#include <QObject>
#include <QThread>
+#elif PLATFORM(EFL)
+typedef struct _Ecore_Timer Ecore_Timer;
#endif
namespace JSC {
-class JSGlobalData;
+class VM;
#if PLATFORM(QT) && !USE(CF)
class HeapTimer : public QObject {
@@ -51,20 +53,17 @@ class HeapTimer {
#endif
public:
#if USE(CF)
- HeapTimer(JSGlobalData*, CFRunLoopRef);
+ HeapTimer(VM*, CFRunLoopRef);
static void timerDidFire(CFRunLoopTimerRef, void*);
#else
- HeapTimer(JSGlobalData*);
+ HeapTimer(VM*);
#endif
virtual ~HeapTimer();
-
- void didStartVMShutdown();
- virtual void synchronize();
virtual void doWork() = 0;
protected:
- JSGlobalData* m_globalData;
+ VM* m_vm;
#if USE(CF)
static const CFTimeInterval s_decade;
@@ -84,6 +83,11 @@ protected:
QBasicTimer m_timer;
QThread* m_newThread;
QMutex m_mutex;
+#elif PLATFORM(EFL)
+ static bool timerEvent(void*);
+ Ecore_Timer* add(double delay, void* agent);
+ void stop();
+ Ecore_Timer* m_timer;
#endif
private:
diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
index 41bc7f5e4..038432a5d 100644
--- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
+++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
@@ -46,15 +46,15 @@ static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal;
#if USE(CF)
IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
- : HeapTimer(heap->globalData(), runLoop)
+ : HeapTimer(heap->vm(), runLoop)
, m_currentBlockToSweepIndex(0)
, m_blocksToSweep(heap->m_blockSnapshot)
{
}
-IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
+PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
{
- return new IncrementalSweeper(heap, CFRunLoopGetCurrent());
+ return adoptPtr(new IncrementalSweeper(heap, CFRunLoopGetCurrent()));
}
void IncrementalSweeper::scheduleTimer()
@@ -70,15 +70,15 @@ void IncrementalSweeper::cancelTimer()
#elif PLATFORM(BLACKBERRY) || PLATFORM(QT)
IncrementalSweeper::IncrementalSweeper(Heap* heap)
- : HeapTimer(heap->globalData())
+ : HeapTimer(heap->vm())
, m_currentBlockToSweepIndex(0)
, m_blocksToSweep(heap->m_blockSnapshot)
{
}
-IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
+PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
{
- return new IncrementalSweeper(heap);
+ return adoptPtr(new IncrementalSweeper(heap));
}
void IncrementalSweeper::scheduleTimer()
@@ -128,7 +128,7 @@ void IncrementalSweeper::sweepNextBlock()
continue;
block->sweep();
- m_globalData->heap.objectSpace().freeOrShrinkBlock(block);
+ m_vm->heap.objectSpace().freeOrShrinkBlock(block);
return;
}
}
@@ -144,14 +144,14 @@ void IncrementalSweeper::willFinishSweeping()
{
m_currentBlockToSweepIndex = 0;
m_blocksToSweep.clear();
- if (m_globalData)
+ if (m_vm)
cancelTimer();
}
#else
-IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData)
- : HeapTimer(globalData)
+IncrementalSweeper::IncrementalSweeper(VM* vm)
+ : HeapTimer(vm)
{
}
@@ -159,9 +159,9 @@ void IncrementalSweeper::doWork()
{
}
-IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
+PassOwnPtr<IncrementalSweeper> IncrementalSweeper::create(Heap* heap)
{
- return new IncrementalSweeper(heap->globalData());
+ return adoptPtr(new IncrementalSweeper(heap->vm()));
}
void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>&)
diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h
index 7b0ae99ab..1c6a3786d 100644
--- a/Source/JavaScriptCore/heap/IncrementalSweeper.h
+++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h
@@ -39,7 +39,7 @@ class Heap;
class IncrementalSweeper : public HeapTimer {
public:
- static IncrementalSweeper* create(Heap*);
+ static PassOwnPtr<IncrementalSweeper> create(Heap*);
void startSweeping(Vector<MarkedBlock*>&);
virtual void doWork();
void sweepNextBlock();
@@ -61,7 +61,7 @@ private:
Vector<MarkedBlock*>& m_blocksToSweep;
#else
- IncrementalSweeper(JSGlobalData*);
+ IncrementalSweeper(VM*);
#endif
};
diff --git a/Source/JavaScriptCore/heap/Local.h b/Source/JavaScriptCore/heap/Local.h
index 5d1f06439..d23435989 100644
--- a/Source/JavaScriptCore/heap/Local.h
+++ b/Source/JavaScriptCore/heap/Local.h
@@ -27,7 +27,7 @@
#define Local_h
#include "Handle.h"
-#include "JSGlobalData.h"
+#include "VM.h"
/*
A strongly referenced handle whose lifetime is temporary, limited to a given
@@ -44,8 +44,8 @@ template <typename T> class Local : public Handle<T> {
public:
typedef typename Handle<T>::ExternalType ExternalType;
- Local(JSGlobalData&, ExternalType = ExternalType());
- Local(JSGlobalData&, Handle<T>);
+ Local(VM&, ExternalType = ExternalType());
+ Local(VM&, Handle<T>);
Local(const Local<T>&); // Adopting constructor. Used to return a Local to a calling function.
Local& operator=(ExternalType);
@@ -56,14 +56,14 @@ private:
void set(ExternalType);
};
-template <typename T> inline Local<T>::Local(JSGlobalData& globalData, ExternalType value)
- : Handle<T>(globalData.heap.handleStack()->push())
+template <typename T> inline Local<T>::Local(VM& vm, ExternalType value)
+ : Handle<T>(vm.heap.handleStack()->push())
{
set(value);
}
-template <typename T> inline Local<T>::Local(JSGlobalData& globalData, Handle<T> other)
- : Handle<T>(globalData.heap.handleStack()->push())
+template <typename T> inline Local<T>::Local(VM& vm, Handle<T> other)
+ : Handle<T>(vm.heap.handleStack()->push())
{
set(other.get());
}
@@ -101,8 +101,8 @@ template <typename T> inline void Local<T>::set(ExternalType externalType)
template <typename T, unsigned inlineCapacity = 0> class LocalStack {
typedef typename Handle<T>::ExternalType ExternalType;
public:
- LocalStack(JSGlobalData& globalData)
- : m_globalData(globalData)
+ LocalStack(VM& vm)
+ : m_vm(vm)
, m_count(0)
{
}
@@ -122,7 +122,7 @@ public:
void push(ExternalType value)
{
if (m_count == m_stack.size())
- m_stack.append(Local<T>(m_globalData, value));
+ m_stack.append(Local<T>(m_vm, value));
else
m_stack[m_count] = value;
m_count++;
@@ -132,7 +132,7 @@ public:
unsigned size() const { return m_count; }
private:
- JSGlobalData& m_globalData;
+ VM& m_vm;
Vector<Local<T>, inlineCapacity> m_stack;
unsigned m_count;
};
diff --git a/Source/JavaScriptCore/heap/LocalScope.h b/Source/JavaScriptCore/heap/LocalScope.h
index cd27b32ef..ab896863c 100644
--- a/Source/JavaScriptCore/heap/LocalScope.h
+++ b/Source/JavaScriptCore/heap/LocalScope.h
@@ -37,11 +37,11 @@ namespace JSC {
LocalScope is similar in concept to NSAutoreleasePool.
*/
-class JSGlobalData;
+class VM;
class LocalScope {
public:
- explicit LocalScope(JSGlobalData&);
+ explicit LocalScope(VM&);
~LocalScope();
template <typename T> Local<T> release(Local<T>); // Destroys all other locals in the scope.
@@ -51,8 +51,8 @@ private:
HandleStack::Frame m_lastFrame;
};
-inline LocalScope::LocalScope(JSGlobalData& globalData)
- : m_handleStack(globalData.heap.handleStack())
+inline LocalScope::LocalScope(VM& vm)
+ : m_handleStack(vm.heap.handleStack())
{
m_handleStack->enterScope(m_lastFrame);
}
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 613edd08c..78fdfa496 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -25,7 +25,7 @@
#include "ConservativeRoots.h"
#include "Heap.h"
#include "JSArray.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include <setjmp.h>
#include <stdlib.h>
#include <wtf/StdLibExtras.h>
@@ -188,7 +188,7 @@ void MachineThreads::makeUsableFromMultipleThreads()
void MachineThreads::addCurrentThread()
{
- ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
+ ASSERT(!m_heap->vm()->exclusiveThread || m_heap->vm()->exclusiveThread == currentThread());
if (!m_threadSpecific || threadSpecificGet(m_threadSpecific))
return;
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
index 466c9fffe..cbdbfd532 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
@@ -4,7 +4,7 @@
#include "GCActivityCallback.h"
#include "Heap.h"
#include "IncrementalSweeper.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include <wtf/CurrentTime.h>
namespace JSC {
@@ -70,7 +70,7 @@ inline void* MarkedAllocator::tryAllocate(size_t bytes)
void* MarkedAllocator::allocateSlowCase(size_t bytes)
{
- ASSERT(m_heap->globalData()->apiLock().currentThreadIsHoldingLock());
+ ASSERT(m_heap->vm()->apiLock().currentThreadIsHoldingLock());
#if COLLECT_ON_EVERY_ALLOCATION
m_heap->collectAllGarbage();
ASSERT(m_heap->m_operationInProgress == NoOperation);
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h
index 867481fe3..686691433 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.h
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.h
@@ -15,10 +15,11 @@ class SpeculativeJIT;
}
class MarkedAllocator {
- friend class JIT;
- friend class DFG::SpeculativeJIT;
+ friend class LLIntOffsetsExtractor;
public:
+ static ptrdiff_t offsetOfFreeListHead();
+
MarkedAllocator();
void reset();
void canonicalizeCellLivenessData();
@@ -36,8 +37,6 @@ public:
bool isPagedOut(double deadline);
private:
- friend class LLIntOffsetsExtractor;
-
JS_EXPORT_PRIVATE void* allocateSlowCase(size_t);
void* tryAllocate(size_t);
void* tryAllocateHelper(size_t);
@@ -53,6 +52,11 @@ private:
MarkedSpace* m_markedSpace;
};
+inline ptrdiff_t MarkedAllocator::offsetOfFreeListHead()
+{
+ return OBJECT_OFFSETOF(MarkedAllocator, m_freeList) + OBJECT_OFFSETOF(MarkedBlock::FreeList, head);
+}
+
inline MarkedAllocator::MarkedAllocator()
: m_currentBlock(0)
, m_blocksToSweep(0)
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp
index 9a036f87c..0df2e1fb8 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.cpp
+++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp
@@ -29,12 +29,13 @@
#include "IncrementalSweeper.h"
#include "JSCell.h"
#include "JSDestructibleObject.h"
-
+#include "Operations.h"
namespace JSC {
MarkedBlock* MarkedBlock::create(DeadBlock* block, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
{
+ ASSERT(reinterpret_cast<size_t>(block) == (reinterpret_cast<size_t>(block) & blockMask));
Region* region = block->region();
return new (NotNull, block) MarkedBlock(region, allocator, cellSize, destructorType);
}
@@ -46,7 +47,7 @@ MarkedBlock::MarkedBlock(Region* region, MarkedAllocator* allocator, size_t cell
, m_destructorType(destructorType)
, m_allocator(allocator)
, m_state(New) // All cells start out unmarked.
- , m_weakSet(allocator->heap()->globalData())
+ , m_weakSet(allocator->heap()->vm())
{
ASSERT(allocator);
HEAP_LOG_BLOCK_STATE_TRANSITION(this);
@@ -62,7 +63,7 @@ inline void MarkedBlock::callDestructor(JSCell* cell)
m_heap->m_destroyedTypeCounts.countVPtr(vptr);
#endif
- cell->methodTable()->destroy(cell);
+ cell->methodTableForDestruction()->destroy(cell);
cell->zap();
}
@@ -131,7 +132,7 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
ASSERT(sweepMode == SweepToFreeList);
return FreeList();
case Allocated:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return FreeList();
case Marked:
return sweepMode == SweepToFreeList
@@ -139,7 +140,7 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
: specializedSweep<Marked, SweepOnly, dtorType>();
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return FreeList();
}
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index 9080aaef4..fcc3016d9 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -23,7 +23,6 @@
#define MarkedBlock_h
#include "BlockAllocator.h"
-#include "CardSet.h"
#include "HeapBlock.h"
#include "WeakSet.h"
@@ -71,19 +70,12 @@ namespace JSC {
class MarkedBlock : public HeapBlock<MarkedBlock> {
public:
- // Ensure natural alignment for native types whilst recognizing that the smallest
- // object the heap will commonly allocate is four words.
- static const size_t atomSize = 4 * sizeof(void*);
- static const size_t atomShift = 5;
+ static const size_t atomSize = 8; // bytes
static const size_t blockSize = 64 * KB;
static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two.
- static const size_t atomsPerBlock = blockSize / atomSize; // ~0.4% overhead
+ static const size_t atomsPerBlock = blockSize / atomSize;
static const size_t atomMask = atomsPerBlock - 1;
- static const int cardShift = 8; // This is log2 of bytes per card.
- static const size_t bytesPerCard = 1 << cardShift;
- static const int cardCount = blockSize / bytesPerCard;
- static const int cardMask = cardCount - 1;
struct FreeCell {
FreeCell* next;
@@ -125,7 +117,7 @@ namespace JSC {
MarkedAllocator* allocator() const;
Heap* heap() const;
- JSGlobalData* globalData() const;
+ VM* vm() const;
WeakSet& weakSet();
enum SweepMode { SweepOnly, SweepToFreeList };
@@ -165,34 +157,6 @@ namespace JSC {
bool needsSweeping();
-#if ENABLE(GGC)
- void setDirtyObject(const void* atom)
- {
- ASSERT(MarkedBlock::blockFor(atom) == this);
- m_cards.markCardForAtom(atom);
- }
-
- uint8_t* addressOfCardFor(const void* atom)
- {
- ASSERT(MarkedBlock::blockFor(atom) == this);
- return &m_cards.cardForAtom(atom);
- }
-
- static inline size_t offsetOfCards()
- {
- return OBJECT_OFFSETOF(MarkedBlock, m_cards);
- }
-
- static inline size_t offsetOfMarks()
- {
- return OBJECT_OFFSETOF(MarkedBlock, m_marks);
- }
-
- typedef Vector<JSCell*, 32> DirtyCellVector;
- inline void gatherDirtyCells(DirtyCellVector&);
- template <int size> inline void gatherDirtyCellsWithSize(DirtyCellVector&);
-#endif
-
template <typename Functor> void forEachCell(Functor&);
template <typename Functor> void forEachLiveCell(Functor&);
template <typename Functor> void forEachDeadCell(Functor&);
@@ -211,10 +175,6 @@ namespace JSC {
void callDestructor(JSCell*);
template<BlockState, SweepMode, DestructorType> FreeList specializedSweep();
-#if ENABLE(GGC)
- CardSet<bytesPerCard, blockSize> m_cards;
-#endif
-
size_t m_atomsPerCell;
size_t m_endAtom; // This is a fuzzy end. Always test for < m_endAtom.
#if ENABLE(PARALLEL_GC)
@@ -280,9 +240,9 @@ namespace JSC {
return m_weakSet.heap();
}
- inline JSGlobalData* MarkedBlock::globalData() const
+ inline VM* MarkedBlock::vm() const
{
- return m_weakSet.globalData();
+ return m_weakSet.vm();
}
inline WeakSet& MarkedBlock::weakSet()
@@ -408,11 +368,11 @@ namespace JSC {
case New:
case FreeListed:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
@@ -466,87 +426,6 @@ namespace JSC {
return m_state == Marked;
}
-#if ENABLE(GGC)
-template <int _cellSize> void MarkedBlock::gatherDirtyCellsWithSize(DirtyCellVector& dirtyCells)
-{
- if (m_cards.testAndClear(0)) {
- char* ptr = reinterpret_cast<char*>(&atoms()[firstAtom()]);
- const char* end = reinterpret_cast<char*>(this) + bytesPerCard;
- while (ptr < end) {
- JSCell* cell = reinterpret_cast<JSCell*>(ptr);
- if (isMarked(cell))
- dirtyCells.append(cell);
- ptr += _cellSize;
- }
- }
-
- const size_t cellOffset = firstAtom() * atomSize % _cellSize;
- for (size_t i = 1; i < m_cards.cardCount; i++) {
- if (!m_cards.testAndClear(i))
- continue;
- char* ptr = reinterpret_cast<char*>(this) + i * bytesPerCard + cellOffset;
- char* end = reinterpret_cast<char*>(this) + (i + 1) * bytesPerCard;
-
- while (ptr < end) {
- JSCell* cell = reinterpret_cast<JSCell*>(ptr);
- if (isMarked(cell))
- dirtyCells.append(cell);
- ptr += _cellSize;
- }
- }
-}
-
-void MarkedBlock::gatherDirtyCells(DirtyCellVector& dirtyCells)
-{
- COMPILE_ASSERT((int)m_cards.cardCount == (int)cardCount, MarkedBlockCardCountsMatch);
-
- ASSERT(m_state != New && m_state != FreeListed);
-
- // This is an optimisation to avoid having to walk the set of marked
- // blocks twice during GC.
- m_state = Marked;
-
- if (isEmpty())
- return;
-
- size_t cellSize = this->cellSize();
- if (cellSize == 32) {
- gatherDirtyCellsWithSize<32>(dirtyCells);
- return;
- }
- if (cellSize == 64) {
- gatherDirtyCellsWithSize<64>(dirtyCells);
- return;
- }
-
- const size_t firstCellOffset = firstAtom() * atomSize % cellSize;
-
- if (m_cards.testAndClear(0)) {
- char* ptr = reinterpret_cast<char*>(this) + firstAtom() * atomSize;
- char* end = reinterpret_cast<char*>(this) + bytesPerCard;
- while (ptr < end) {
- JSCell* cell = reinterpret_cast<JSCell*>(ptr);
- if (isMarked(cell))
- dirtyCells.append(cell);
- ptr += cellSize;
- }
- }
- for (size_t i = 1; i < m_cards.cardCount; i++) {
- if (!m_cards.testAndClear(i))
- continue;
- char* ptr = reinterpret_cast<char*>(this) + firstCellOffset + cellSize * ((i * bytesPerCard + cellSize - 1 - firstCellOffset) / cellSize);
- char* end = reinterpret_cast<char*>(this) + std::min((i + 1) * bytesPerCard, m_endAtom * atomSize);
-
- while (ptr < end) {
- JSCell* cell = reinterpret_cast<JSCell*>(ptr);
- if (isMarked(cell))
- dirtyCells.append(cell);
- ptr += cellSize;
- }
- }
-}
-#endif
-
} // namespace JSC
namespace WTF {
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp
index 50634dd23..2bef60843 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp
@@ -223,35 +223,4 @@ void MarkedSpace::shrink()
forEachBlock(freeOrShrink);
}
-#if ENABLE(GGC)
-class GatherDirtyCells {
- WTF_MAKE_NONCOPYABLE(GatherDirtyCells);
-public:
- typedef void* ReturnType;
-
- explicit GatherDirtyCells(MarkedBlock::DirtyCellVector*);
- void operator()(MarkedBlock*);
- ReturnType returnValue() { return 0; }
-
-private:
- MarkedBlock::DirtyCellVector* m_dirtyCells;
-};
-
-inline GatherDirtyCells::GatherDirtyCells(MarkedBlock::DirtyCellVector* dirtyCells)
- : m_dirtyCells(dirtyCells)
-{
-}
-
-inline void GatherDirtyCells::operator()(MarkedBlock* block)
-{
- block->gatherDirtyCells(*m_dirtyCells);
-}
-
-void MarkedSpace::gatherDirtyCells(MarkedBlock::DirtyCellVector& dirtyCells)
-{
- GatherDirtyCells gatherDirtyCells(&dirtyCells);
- forEachBlock(gatherDirtyCells);
-}
-#endif
-
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h
index 214536ad7..278f1cc98 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.h
+++ b/Source/JavaScriptCore/heap/MarkedSpace.h
@@ -114,9 +114,9 @@ public:
private:
friend class LLIntOffsetsExtractor;
- // [ 32... 512 ]
+ // [ 32... 128 ]
static const size_t preciseStep = MarkedBlock::atomSize;
- static const size_t preciseCutoff = 512;
+ static const size_t preciseCutoff = 128;
static const size_t preciseCount = preciseCutoff / preciseStep;
// [ 1024... blockSize ]
@@ -170,11 +170,6 @@ template<typename Functor> inline typename Functor::ReturnType MarkedSpace::forE
return forEachDeadCell(functor);
}
-inline MarkedAllocator& MarkedSpace::firstAllocator()
-{
- return m_normalSpace.preciseAllocators[0];
-}
-
inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes)
{
ASSERT(bytes);
diff --git a/Source/JavaScriptCore/heap/PassWeak.h b/Source/JavaScriptCore/heap/PassWeak.h
index acd6e52c7..506a63970 100644
--- a/Source/JavaScriptCore/heap/PassWeak.h
+++ b/Source/JavaScriptCore/heap/PassWeak.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,29 +34,14 @@
namespace JSC {
-template<typename T> class Weak;
template<typename T> class PassWeak;
template<typename T> PassWeak<T> adoptWeak(WeakImpl*);
-template<typename Base, typename T> class WeakImplAccessor {
+template<typename T> class PassWeak {
public:
- typedef T* GetType;
-
- T* operator->() const;
- T& operator*() const;
- GetType get() const;
-
- bool was(GetType) const;
-};
-
-template<typename T> class PassWeak : public WeakImplAccessor<PassWeak<T>, T> {
-public:
- friend class WeakImplAccessor<PassWeak<T>, T>;
- typedef typename WeakImplAccessor<PassWeak<T>, T>::GetType GetType;
-
PassWeak();
PassWeak(std::nullptr_t);
- PassWeak(GetType, WeakHandleOwner* = 0, void* context = 0);
+ PassWeak(T*, WeakHandleOwner* = 0, void* context = 0);
// It somewhat breaks the type system to allow transfer of ownership out of
// a const PassWeak. However, it makes it much easier to work with PassWeak
@@ -66,10 +51,14 @@ public:
~PassWeak();
+ T* operator->() const;
+ T& operator*() const;
+ T* get() const;
+
bool operator!() const;
// This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef JSValue (PassWeak::*UnspecifiedBoolType);
+ typedef void* (PassWeak::*UnspecifiedBoolType);
operator UnspecifiedBoolType*() const;
WeakImpl* leakImpl() const WARN_UNUSED_RETURN;
@@ -81,30 +70,6 @@ private:
WeakImpl* m_impl;
};
-template<typename Base, typename T> inline T* WeakImplAccessor<Base, T>::operator->() const
-{
- ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live);
- return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell());
-}
-
-template<typename Base, typename T> inline T& WeakImplAccessor<Base, T>::operator*() const
-{
- ASSERT(static_cast<const Base*>(this)->m_impl && static_cast<const Base*>(this)->m_impl->state() == WeakImpl::Live);
- return *jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell());
-}
-
-template<typename Base, typename T> inline typename WeakImplAccessor<Base, T>::GetType WeakImplAccessor<Base, T>::get() const
-{
- if (!static_cast<const Base*>(this)->m_impl || static_cast<const Base*>(this)->m_impl->state() != WeakImpl::Live)
- return GetType();
- return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell());
-}
-
-template<typename Base, typename T> inline bool WeakImplAccessor<Base, T>::was(typename WeakImplAccessor<Base, T>::GetType other) const
-{
- return jsCast<T*>(static_cast<const Base*>(this)->m_impl->jsValue().asCell()) == other;
-}
-
template<typename T> inline PassWeak<T>::PassWeak()
: m_impl(0)
{
@@ -115,8 +80,8 @@ template<typename T> inline PassWeak<T>::PassWeak(std::nullptr_t)
{
}
-template<typename T> inline PassWeak<T>::PassWeak(typename PassWeak<T>::GetType getType, WeakHandleOwner* weakOwner, void* context)
- : m_impl(getType ? WeakSet::allocate(getType, weakOwner, context) : 0)
+template<typename T> inline PassWeak<T>::PassWeak(T* cell, WeakHandleOwner* weakOwner, void* context)
+ : m_impl(cell ? WeakSet::allocate(cell, weakOwner, context) : 0)
{
}
@@ -137,6 +102,25 @@ template<typename T> inline PassWeak<T>::~PassWeak()
WeakSet::deallocate(m_impl);
}
+template<typename T> inline T* PassWeak<T>::operator->() const
+{
+ ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
+ return jsCast<T*>(m_impl->jsValue().asCell());
+}
+
+template<typename T> inline T& PassWeak<T>::operator*() const
+{
+ ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
+ return *jsCast<T*>(m_impl->jsValue().asCell());
+}
+
+template<typename T> inline T* PassWeak<T>::get() const
+{
+ if (!m_impl || m_impl->state() != WeakImpl::Live)
+ return 0;
+ return jsCast<T*>(m_impl->jsValue().asCell());
+}
+
template<typename T> inline bool PassWeak<T>::operator!() const
{
return !m_impl || m_impl->state() != WeakImpl::Live || !m_impl->jsValue();
diff --git a/Source/JavaScriptCore/heap/Region.h b/Source/JavaScriptCore/heap/Region.h
new file mode 100644
index 000000000..366f25643
--- /dev/null
+++ b/Source/JavaScriptCore/heap/Region.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSC_Region_h
+#define JSC_Region_h
+
+#include "HeapBlock.h"
+#include "SuperRegion.h"
+#include <wtf/DoublyLinkedList.h>
+#include <wtf/MetaAllocatorHandle.h>
+#include <wtf/PageAllocationAligned.h>
+
+#define HEAP_MEMORY_ID reinterpret_cast<void*>(static_cast<intptr_t>(-3))
+
+#define ENABLE_SUPER_REGION 0
+
+#ifndef ENABLE_SUPER_REGION
+#if USE(JSVALUE64)
+#define ENABLE_SUPER_REGION 1
+#else
+#define ENABLE_SUPER_REGION 0
+#endif
+#endif
+
+namespace JSC {
+
+class DeadBlock : public HeapBlock<DeadBlock> {
+public:
+ DeadBlock(Region*);
+};
+
+inline DeadBlock::DeadBlock(Region* region)
+ : HeapBlock<DeadBlock>(region)
+{
+}
+
+class Region : public DoublyLinkedListNode<Region> {
+ friend CLASS_IF_GCC DoublyLinkedListNode<Region>;
+ friend class BlockAllocator;
+public:
+ ~Region();
+ static Region* create(SuperRegion*, size_t blockSize);
+ static Region* createCustomSize(SuperRegion*, size_t blockSize, size_t blockAlignment);
+ Region* reset(size_t blockSize);
+ void destroy();
+
+ size_t blockSize() const { return m_blockSize; }
+ bool isFull() const { return m_blocksInUse == m_totalBlocks; }
+ bool isEmpty() const { return !m_blocksInUse; }
+ bool isCustomSize() const { return m_isCustomSize; }
+
+ DeadBlock* allocate();
+ void deallocate(void*);
+
+ static const size_t s_regionSize = 64 * KB;
+ static const size_t s_regionMask = ~(s_regionSize - 1);
+
+protected:
+ Region(size_t blockSize, size_t totalBlocks, bool isExcess);
+ void initializeBlockList();
+
+ bool m_isExcess;
+
+private:
+ void* base();
+ size_t size();
+
+ size_t m_totalBlocks;
+ size_t m_blocksInUse;
+ size_t m_blockSize;
+ bool m_isCustomSize;
+ Region* m_prev;
+ Region* m_next;
+ DoublyLinkedList<DeadBlock> m_deadBlocks;
+};
+
+
+class NormalRegion : public Region {
+ friend class Region;
+private:
+ NormalRegion(PassRefPtr<WTF::MetaAllocatorHandle>, size_t blockSize, size_t totalBlocks);
+
+ static NormalRegion* tryCreate(SuperRegion*, size_t blockSize);
+ static NormalRegion* tryCreateCustomSize(SuperRegion*, size_t blockSize, size_t blockAlignment);
+
+ void* base() { return m_allocation->start(); }
+ size_t size() { return m_allocation->sizeInBytes(); }
+
+ NormalRegion* reset(size_t blockSize);
+
+ RefPtr<WTF::MetaAllocatorHandle> m_allocation;
+};
+
+class ExcessRegion : public Region {
+ friend class Region;
+private:
+ ExcessRegion(PageAllocationAligned&, size_t blockSize, size_t totalBlocks);
+
+ ~ExcessRegion();
+
+ static ExcessRegion* create(size_t blockSize);
+ static ExcessRegion* createCustomSize(size_t blockSize, size_t blockAlignment);
+
+ void* base() { return m_allocation.base(); }
+ size_t size() { return m_allocation.size(); }
+
+ ExcessRegion* reset(size_t blockSize);
+
+ PageAllocationAligned m_allocation;
+};
+
+inline NormalRegion::NormalRegion(PassRefPtr<WTF::MetaAllocatorHandle> allocation, size_t blockSize, size_t totalBlocks)
+ : Region(blockSize, totalBlocks, false)
+ , m_allocation(allocation)
+{
+ initializeBlockList();
+}
+
+inline NormalRegion* NormalRegion::tryCreate(SuperRegion* superRegion, size_t blockSize)
+{
+ RefPtr<WTF::MetaAllocatorHandle> allocation = superRegion->allocate(s_regionSize, HEAP_MEMORY_ID);
+ if (!allocation)
+ return 0;
+ return new NormalRegion(allocation, blockSize, s_regionSize / blockSize);
+}
+
+inline NormalRegion* NormalRegion::tryCreateCustomSize(SuperRegion* superRegion, size_t blockSize, size_t blockAlignment)
+{
+ ASSERT_UNUSED(blockAlignment, blockAlignment <= s_regionSize);
+ RefPtr<WTF::MetaAllocatorHandle> allocation = superRegion->allocate(blockSize, HEAP_MEMORY_ID);
+ if (!allocation)
+ return 0;
+ return new NormalRegion(allocation, blockSize, 1);
+}
+
+inline NormalRegion* NormalRegion::reset(size_t blockSize)
+{
+ ASSERT(!m_isExcess);
+ RefPtr<WTF::MetaAllocatorHandle> allocation = m_allocation.release();
+ return new (NotNull, this) NormalRegion(allocation.release(), blockSize, s_regionSize / blockSize);
+}
+
+inline ExcessRegion::ExcessRegion(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks)
+ : Region(blockSize, totalBlocks, true)
+ , m_allocation(allocation)
+{
+ initializeBlockList();
+}
+
+inline ExcessRegion::~ExcessRegion()
+{
+ m_allocation.deallocate();
+}
+
+inline ExcessRegion* ExcessRegion::create(size_t blockSize)
+{
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages);
+ ASSERT(static_cast<bool>(allocation));
+ return new ExcessRegion(allocation, blockSize, s_regionSize / blockSize);
+}
+
+inline ExcessRegion* ExcessRegion::createCustomSize(size_t blockSize, size_t blockAlignment)
+{
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages);
+ ASSERT(static_cast<bool>(allocation));
+ return new ExcessRegion(allocation, blockSize, 1);
+}
+
+inline ExcessRegion* ExcessRegion::reset(size_t blockSize)
+{
+ ASSERT(m_isExcess);
+ PageAllocationAligned allocation = m_allocation;
+ return new (NotNull, this) ExcessRegion(allocation, blockSize, s_regionSize / blockSize);
+}
+
+inline Region::Region(size_t blockSize, size_t totalBlocks, bool isExcess)
+ : DoublyLinkedListNode<Region>()
+ , m_isExcess(isExcess)
+ , m_totalBlocks(totalBlocks)
+ , m_blocksInUse(0)
+ , m_blockSize(blockSize)
+ , m_isCustomSize(false)
+ , m_prev(0)
+ , m_next(0)
+{
+}
+
+inline void Region::initializeBlockList()
+{
+ char* start = static_cast<char*>(base());
+ char* current = start;
+ for (size_t i = 0; i < m_totalBlocks; i++) {
+ ASSERT(current < start + size());
+ m_deadBlocks.append(new (NotNull, current) DeadBlock(this));
+ current += m_blockSize;
+ }
+}
+
+inline Region* Region::create(SuperRegion* superRegion, size_t blockSize)
+{
+#if ENABLE(SUPER_REGION)
+ ASSERT(blockSize <= s_regionSize);
+ ASSERT(!(s_regionSize % blockSize));
+ Region* region = NormalRegion::tryCreate(superRegion, blockSize);
+ if (LIKELY(!!region))
+ return region;
+#else
+ UNUSED_PARAM(superRegion);
+#endif
+ return ExcessRegion::create(blockSize);
+}
+
+inline Region* Region::createCustomSize(SuperRegion* superRegion, size_t blockSize, size_t blockAlignment)
+{
+#if ENABLE(SUPER_REGION)
+ Region* region = NormalRegion::tryCreateCustomSize(superRegion, blockSize, blockAlignment);
+ if (UNLIKELY(!region))
+ region = ExcessRegion::createCustomSize(blockSize, blockAlignment);
+#else
+ UNUSED_PARAM(superRegion);
+ Region* region = ExcessRegion::createCustomSize(blockSize, blockAlignment);
+#endif
+ region->m_isCustomSize = true;
+ return region;
+}
+
+inline Region::~Region()
+{
+ ASSERT(isEmpty());
+}
+
+inline void Region::destroy()
+{
+#if ENABLE(SUPER_REGION)
+ if (UNLIKELY(m_isExcess))
+ delete static_cast<ExcessRegion*>(this);
+ else
+ delete static_cast<NormalRegion*>(this);
+#else
+ delete static_cast<ExcessRegion*>(this);
+#endif
+}
+
+inline Region* Region::reset(size_t blockSize)
+{
+#if ENABLE(SUPER_REGION)
+ ASSERT(isEmpty());
+ if (UNLIKELY(m_isExcess))
+ return static_cast<ExcessRegion*>(this)->reset(blockSize);
+ return static_cast<NormalRegion*>(this)->reset(blockSize);
+#else
+ return static_cast<ExcessRegion*>(this)->reset(blockSize);
+#endif
+}
+
+inline DeadBlock* Region::allocate()
+{
+ ASSERT(!isFull());
+ m_blocksInUse++;
+ return m_deadBlocks.removeHead();
+}
+
+inline void Region::deallocate(void* base)
+{
+ ASSERT(base);
+ ASSERT(m_blocksInUse);
+ ASSERT(base >= this->base() && base < static_cast<char*>(this->base()) + size());
+ DeadBlock* block = new (NotNull, base) DeadBlock(this);
+ m_deadBlocks.push(block);
+ m_blocksInUse--;
+}
+
+inline void* Region::base()
+{
+#if ENABLE(SUPER_REGION)
+ if (UNLIKELY(m_isExcess))
+ return static_cast<ExcessRegion*>(this)->ExcessRegion::base();
+ return static_cast<NormalRegion*>(this)->NormalRegion::base();
+#else
+ return static_cast<ExcessRegion*>(this)->ExcessRegion::base();
+#endif
+}
+
+inline size_t Region::size()
+{
+#if ENABLE(SUPER_REGION)
+ if (UNLIKELY(m_isExcess))
+ return static_cast<ExcessRegion*>(this)->ExcessRegion::size();
+ return static_cast<NormalRegion*>(this)->NormalRegion::size();
+#else
+ return static_cast<ExcessRegion*>(this)->ExcessRegion::size();
+#endif
+}
+
+} // namespace JSC
+
+#endif // JSC_Region_h
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp
index 3ff4b48fa..6c2ded09d 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.cpp
+++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp
@@ -8,19 +8,20 @@
#include "GCThread.h"
#include "JSArray.h"
#include "JSDestructibleObject.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSObject.h"
#include "JSString.h"
+#include "Operations.h"
#include <wtf/StackStats.h>
namespace JSC {
SlotVisitor::SlotVisitor(GCThreadSharedData& shared)
- : m_stack(shared.m_globalData->heap.blockAllocator())
+ : m_stack(shared.m_vm->heap.blockAllocator())
, m_visitCount(0)
, m_isInParallelMode(false)
, m_shared(shared)
- , m_shouldHashConst(false)
+ , m_shouldHashCons(false)
#if !ASSERT_DISABLED
, m_isCheckingForDefaultMarkViolation(false)
, m_isDraining(false)
@@ -35,11 +36,11 @@ SlotVisitor::~SlotVisitor()
void SlotVisitor::setup()
{
- m_shared.m_shouldHashConst = m_shared.m_globalData->haveEnoughNewStringsToHashConst();
- m_shouldHashConst = m_shared.m_shouldHashConst;
+ m_shared.m_shouldHashCons = m_shared.m_vm->haveEnoughNewStringsToHashCons();
+ m_shouldHashCons = m_shared.m_shouldHashCons;
#if ENABLE(PARALLEL_GC)
for (unsigned i = 0; i < m_shared.m_gcThreads.size(); ++i)
- m_shared.m_gcThreads[i]->slotVisitor()->m_shouldHashConst = m_shared.m_shouldHashConst;
+ m_shared.m_gcThreads[i]->slotVisitor()->m_shouldHashCons = m_shared.m_shouldHashCons;
#endif
}
@@ -52,9 +53,9 @@ void SlotVisitor::reset()
#else
m_opaqueRoots.clear();
#endif
- if (m_shouldHashConst) {
+ if (m_shouldHashCons) {
m_uniqueStrings.clear();
- m_shouldHashConst = false;
+ m_shouldHashCons = false;
}
}
@@ -240,15 +241,15 @@ void SlotVisitor::mergeOpaqueRoots()
m_opaqueRoots.clear();
}
-ALWAYS_INLINE bool JSString::tryHashConstLock()
+ALWAYS_INLINE bool JSString::tryHashConsLock()
{
#if ENABLE(PARALLEL_GC)
unsigned currentFlags = m_flags;
- if (currentFlags & HashConstLock)
+ if (currentFlags & HashConsLock)
return false;
- unsigned newFlags = currentFlags | HashConstLock;
+ unsigned newFlags = currentFlags | HashConsLock;
if (!WTF::weakCompareAndSwap(&m_flags, currentFlags, newFlags))
return false;
@@ -256,26 +257,26 @@ ALWAYS_INLINE bool JSString::tryHashConstLock()
WTF::memoryBarrierAfterLock();
return true;
#else
- if (isHashConstSingleton())
+ if (isHashConsSingleton())
return false;
- m_flags |= HashConstLock;
+ m_flags |= HashConsLock;
return true;
#endif
}
-ALWAYS_INLINE void JSString::releaseHashConstLock()
+ALWAYS_INLINE void JSString::releaseHashConsLock()
{
#if ENABLE(PARALLEL_GC)
WTF::memoryBarrierBeforeUnlock();
#endif
- m_flags &= ~HashConstLock;
+ m_flags &= ~HashConsLock;
}
-ALWAYS_INLINE bool JSString::shouldTryHashConst()
+ALWAYS_INLINE bool JSString::shouldTryHashCons()
{
- return ((length() > 1) && !isRope() && !isHashConstSingleton());
+ return ((length() > 1) && !isRope() && !isHashConsSingleton());
}
ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot)
@@ -297,21 +298,21 @@ ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot)
validate(cell);
- if (m_shouldHashConst && cell->isString()) {
+ if (m_shouldHashCons && cell->isString()) {
JSString* string = jsCast<JSString*>(cell);
- if (string->shouldTryHashConst() && string->tryHashConstLock()) {
+ if (string->shouldTryHashCons() && string->tryHashConsLock()) {
UniqueStringMap::AddResult addResult = m_uniqueStrings.add(string->string().impl(), value);
if (addResult.isNewEntry)
- string->setHashConstSingleton();
+ string->setHashConsSingleton();
else {
JSValue existingJSValue = addResult.iterator->value;
if (value != existingJSValue)
- jsCast<JSString*>(existingJSValue.asCell())->clearHashConstSingleton();
+ jsCast<JSString*>(existingJSValue.asCell())->clearHashConsSingleton();
*slot = existingJSValue;
- string->releaseHashConstLock();
+ string->releaseHashConsLock();
return;
}
- string->releaseHashConstLock();
+ string->releaseHashConsLock();
}
}
@@ -335,10 +336,7 @@ void SlotVisitor::finalizeUnconditionalFinalizers()
#if ENABLE(GC_VALIDATION)
void SlotVisitor::validate(JSCell* cell)
{
- if (!cell) {
- dataLogF("cell is NULL\n");
- CRASH();
- }
+ RELEASE_ASSERT(cell);
if (!cell->structure()) {
dataLogF("cell at %p has a null structure\n" , cell);
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h
index 7d16dc2ed..e1808faf0 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.h
+++ b/Source/JavaScriptCore/heap/SlotVisitor.h
@@ -62,6 +62,7 @@ public:
void addOpaqueRoot(void*);
bool containsOpaqueRoot(void*);
+ TriState containsOpaqueRootTriState(void*);
int opaqueRootCount();
GCThreadSharedData& sharedData() { return m_shared; }
@@ -124,7 +125,7 @@ private:
GCThreadSharedData& m_shared;
- bool m_shouldHashConst; // Local per-thread copy of shared flag for performance reasons
+ bool m_shouldHashCons; // Local per-thread copy of shared flag for performance reasons
typedef HashMap<StringImpl*, JSValue> UniqueStringMap;
UniqueStringMap m_uniqueStrings;
diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlines.h b/Source/JavaScriptCore/heap/SlotVisitorInlines.h
index 3a7f2290c..4273a28d6 100644
--- a/Source/JavaScriptCore/heap/SlotVisitorInlines.h
+++ b/Source/JavaScriptCore/heap/SlotVisitorInlines.h
@@ -31,6 +31,7 @@
#include "Options.h"
#include "SlotVisitor.h"
#include "Weak.h"
+#include "WeakInlines.h"
namespace JSC {
@@ -121,6 +122,16 @@ inline bool SlotVisitor::containsOpaqueRoot(void* root)
#endif
}
+inline TriState SlotVisitor::containsOpaqueRootTriState(void* root)
+{
+ if (m_opaqueRoots.contains(root))
+ return TrueTriState;
+ MutexLocker locker(m_shared.m_opaqueRootsLock);
+ if (m_shared.m_opaqueRoots.contains(root))
+ return TrueTriState;
+ return MixedTriState;
+}
+
inline int SlotVisitor::opaqueRootCount()
{
ASSERT(!m_isInParallelMode);
diff --git a/Source/JavaScriptCore/heap/Strong.h b/Source/JavaScriptCore/heap/Strong.h
index 7fafaeab5..e00e92061 100644
--- a/Source/JavaScriptCore/heap/Strong.h
+++ b/Source/JavaScriptCore/heap/Strong.h
@@ -32,12 +32,13 @@
namespace JSC {
-class JSGlobalData;
+class VM;
// A strongly referenced handle that prevents the object it points to from being garbage collected.
template <typename T> class Strong : public Handle<T> {
using Handle<T>::slot;
using Handle<T>::setSlot;
+ template <typename U> friend class Strong;
public:
typedef typename Handle<T>::ExternalType ExternalType;
@@ -47,9 +48,9 @@ public:
{
}
- Strong(JSGlobalData&, ExternalType = ExternalType());
+ Strong(VM&, ExternalType = ExternalType());
- Strong(JSGlobalData&, Handle<T>);
+ Strong(VM&, Handle<T>);
Strong(const Strong& other)
: Handle<T>()
@@ -94,7 +95,7 @@ public:
ExternalType get() const { return HandleTypes<T>::getFromSlot(this->slot()); }
- void set(JSGlobalData&, ExternalType);
+ void set(VM&, ExternalType);
template <typename U> Strong& operator=(const Strong<U>& other)
{
@@ -103,7 +104,7 @@ public:
return *this;
}
- set(*HandleSet::heapFor(other.slot())->globalData(), other.get());
+ set(*HandleSet::heapFor(other.slot())->vm(), other.get());
return *this;
}
@@ -114,7 +115,7 @@ public:
return *this;
}
- set(*HandleSet::heapFor(other.slot())->globalData(), other.get());
+ set(*HandleSet::heapFor(other.slot())->vm(), other.get());
return *this;
}
diff --git a/Source/JavaScriptCore/heap/StrongInlines.h b/Source/JavaScriptCore/heap/StrongInlines.h
index 2308bf6f6..e1fbe90d2 100644
--- a/Source/JavaScriptCore/heap/StrongInlines.h
+++ b/Source/JavaScriptCore/heap/StrongInlines.h
@@ -26,29 +26,29 @@
#ifndef StrongInlines_h
#define StrongInlines_h
-#include "JSGlobalData.h"
+#include "VM.h"
namespace JSC {
template <typename T>
-inline Strong<T>::Strong(JSGlobalData& globalData, ExternalType value)
- : Handle<T>(globalData.heap.handleSet()->allocate())
+inline Strong<T>::Strong(VM& vm, ExternalType value)
+ : Handle<T>(vm.heap.handleSet()->allocate())
{
set(value);
}
template <typename T>
-inline Strong<T>::Strong(JSGlobalData& globalData, Handle<T> handle)
- : Handle<T>(globalData.heap.handleSet()->allocate())
+inline Strong<T>::Strong(VM& vm, Handle<T> handle)
+ : Handle<T>(vm.heap.handleSet()->allocate())
{
set(handle.get());
}
template <typename T>
-inline void Strong<T>::set(JSGlobalData& globalData, ExternalType value)
+inline void Strong<T>::set(VM& vm, ExternalType value)
{
if (!slot())
- setSlot(globalData.heap.handleSet()->allocate());
+ setSlot(vm.heap.handleSet()->allocate());
set(value);
}
diff --git a/Source/JavaScriptCore/heap/SuperRegion.cpp b/Source/JavaScriptCore/heap/SuperRegion.cpp
new file mode 100644
index 000000000..d58f600b5
--- /dev/null
+++ b/Source/JavaScriptCore/heap/SuperRegion.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SuperRegion.h"
+
+#include "Region.h"
+
+namespace JSC {
+
+const uint64_t SuperRegion::s_fixedHeapMemoryPoolSize = 4 * 1024 * static_cast<uint64_t>(MB);
+
+SuperRegion::SuperRegion()
+ : MetaAllocator(Region::s_regionSize, Region::s_regionSize)
+ , m_reservationBase(0)
+{
+#if ENABLE(SUPER_REGION)
+ // Over-allocate so that we can make sure that we're aligned to the size of Regions.
+ m_reservation = PageReservation::reserve(s_fixedHeapMemoryPoolSize + Region::s_regionSize, OSAllocator::JSGCHeapPages);
+ m_reservationBase = getAlignedBase(m_reservation);
+ addFreshFreeSpace(m_reservationBase, s_fixedHeapMemoryPoolSize);
+#else
+ UNUSED_PARAM(m_reservation);
+ UNUSED_PARAM(m_reservationBase);
+#endif
+}
+
+SuperRegion::~SuperRegion()
+{
+#if ENABLE(SUPER_REGION)
+ m_reservation.deallocate();
+#endif
+}
+
+void* SuperRegion::getAlignedBase(PageReservation& reservation)
+{
+ for (char* current = static_cast<char*>(reservation.base()); current < static_cast<char*>(reservation.base()) + Region::s_regionSize; current += pageSize()) {
+ if (!(reinterpret_cast<size_t>(current) & ~Region::s_regionMask))
+ return current;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void* SuperRegion::allocateNewSpace(size_t&)
+{
+ return 0;
+}
+
+void SuperRegion::notifyNeedPage(void* page)
+{
+ m_reservation.commit(page, Region::s_regionSize);
+}
+
+void SuperRegion::notifyPageIsFree(void* page)
+{
+ m_reservation.decommit(page, Region::s_regionSize);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/SuperRegion.h b/Source/JavaScriptCore/heap/SuperRegion.h
new file mode 100644
index 000000000..b659510f8
--- /dev/null
+++ b/Source/JavaScriptCore/heap/SuperRegion.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SuperRegion_h
+#define SuperRegion_h
+
+#include <wtf/MetaAllocator.h>
+#include <wtf/PageBlock.h>
+#include <wtf/PageReservation.h>
+
+namespace JSC {
+
+class VM;
+
+class SuperRegion : public WTF::MetaAllocator {
+public:
+ SuperRegion();
+ virtual ~SuperRegion();
+
+protected:
+ virtual void* allocateNewSpace(size_t&);
+ virtual void notifyNeedPage(void*);
+ virtual void notifyPageIsFree(void*);
+
+private:
+ static const uint64_t s_fixedHeapMemoryPoolSize;
+
+ static void* getAlignedBase(PageReservation&);
+
+ PageReservation m_reservation;
+ void* m_reservationBase;
+};
+
+} // namespace JSC
+
+#endif // SuperRegion_h
diff --git a/Source/JavaScriptCore/heap/VTableSpectrum.cpp b/Source/JavaScriptCore/heap/VTableSpectrum.cpp
index acb494034..a6f8e54bd 100644
--- a/Source/JavaScriptCore/heap/VTableSpectrum.cpp
+++ b/Source/JavaScriptCore/heap/VTableSpectrum.cpp
@@ -30,7 +30,6 @@
#include "Structure.h"
#include <algorithm>
#include <stdio.h>
-#include <wtf/Platform.h>
#include <wtf/Vector.h>
#if PLATFORM(MAC)
diff --git a/Source/JavaScriptCore/heap/Weak.cpp b/Source/JavaScriptCore/heap/Weak.cpp
new file mode 100644
index 000000000..3857b60d2
--- /dev/null
+++ b/Source/JavaScriptCore/heap/Weak.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Weak.h"
+
+#include "WeakSetInlines.h"
+
+namespace JSC {
+
+void weakClearSlowCase(WeakImpl*& impl)
+{
+ ASSERT(impl);
+
+ WeakSet::deallocate(impl);
+ impl = 0;
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/Weak.h b/Source/JavaScriptCore/heap/Weak.h
index efb2a9a56..5c901df22 100644
--- a/Source/JavaScriptCore/heap/Weak.h
+++ b/Source/JavaScriptCore/heap/Weak.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,22 +26,32 @@
#ifndef Weak_h
#define Weak_h
-#include "PassWeak.h"
-#include "WeakSetInlines.h"
-#include <wtf/Assertions.h>
-#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/NullPtr.h>
namespace JSC {
-template<typename T> class Weak : public WeakImplAccessor<Weak<T>, T> {
+template<typename T> class PassWeak;
+class WeakImpl;
+class WeakHandleOwner;
+
+// This is a free function rather than a Weak<T> member function so we can put it in Weak.cpp.
+JS_EXPORT_PRIVATE void weakClearSlowCase(WeakImpl*&);
+
+template<typename T> class Weak {
WTF_MAKE_NONCOPYABLE(Weak);
public:
- friend class WeakImplAccessor<Weak<T>, T>;
- typedef typename WeakImplAccessor<Weak<T>, T>::GetType GetType;
+ Weak()
+ : m_impl(0)
+ {
+ }
- Weak();
- Weak(std::nullptr_t);
- Weak(GetType, WeakHandleOwner* = 0, void* context = 0);
+ explicit Weak(std::nullptr_t)
+ : m_impl(0)
+ {
+ }
+
+ explicit Weak(T*, WeakHandleOwner* = 0, void* context = 0);
enum HashTableDeletedValueTag { HashTableDeletedValue };
bool isHashTableDeletedValue() const;
@@ -49,19 +59,32 @@ public:
template<typename U> Weak(const PassWeak<U>&);
- ~Weak();
+ ~Weak()
+ {
+ clear();
+ }
void swap(Weak&);
Weak& operator=(const PassWeak<T>&);
bool operator!() const;
+ T* operator->() const;
+ T& operator*() const;
+ T* get() const;
+
+ bool was(T*) const;
// This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef JSValue (HandleBase::*UnspecifiedBoolType);
+ typedef void* (Weak::*UnspecifiedBoolType);
operator UnspecifiedBoolType*() const;
PassWeak<T> release();
- void clear();
+ void clear()
+ {
+ if (!m_impl)
+ return;
+ weakClearSlowCase(m_impl);
+ }
private:
static WeakImpl* hashTableDeletedValue();
@@ -69,145 +92,6 @@ private:
WeakImpl* m_impl;
};
-template<typename T> inline Weak<T>::Weak()
- : m_impl(0)
-{
-}
-
-template<typename T> inline Weak<T>::Weak(std::nullptr_t)
- : m_impl(0)
-{
-}
-
-template<typename T> inline Weak<T>::Weak(typename Weak<T>::GetType getType, WeakHandleOwner* weakOwner, void* context)
- : m_impl(getType ? WeakSet::allocate(getType, weakOwner, context) : 0)
-{
-}
-
-template<typename T> inline bool Weak<T>::isHashTableDeletedValue() const
-{
- return m_impl == hashTableDeletedValue();
-}
-
-template<typename T> inline Weak<T>::Weak(typename Weak<T>::HashTableDeletedValueTag)
- : m_impl(hashTableDeletedValue())
-{
-}
-
-template<typename T> template<typename U> inline Weak<T>::Weak(const PassWeak<U>& other)
- : m_impl(other.leakImpl())
-{
-}
-
-template<typename T> inline Weak<T>::~Weak()
-{
- clear();
-}
-
-template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
-{
- a.swap(b);
-}
-
-template<typename T> inline void Weak<T>::swap(Weak& other)
-{
- std::swap(m_impl, other.m_impl);
-}
-
-template<typename T> inline Weak<T>& Weak<T>::operator=(const PassWeak<T>& o)
-{
- clear();
- m_impl = o.leakImpl();
- return *this;
-}
-
-template<typename T> inline bool Weak<T>::operator!() const
-{
- return !m_impl || !m_impl->jsValue() || m_impl->state() != WeakImpl::Live;
-}
-
-template<typename T> inline Weak<T>::operator UnspecifiedBoolType*() const
-{
- return reinterpret_cast<UnspecifiedBoolType*>(!!*this);
-}
-
-template<typename T> inline PassWeak<T> Weak<T>::release()
-{
- PassWeak<T> tmp = adoptWeak<T>(m_impl);
- m_impl = 0;
- return tmp;
-}
-
-template<typename T> inline void Weak<T>::clear()
-{
- if (!m_impl)
- return;
- WeakSet::deallocate(m_impl);
- m_impl = 0;
-}
-
-template<typename T> inline WeakImpl* Weak<T>::hashTableDeletedValue()
-{
- return reinterpret_cast<WeakImpl*>(-1);
-}
-
-template <typename T> inline bool operator==(const Weak<T>& lhs, const Weak<T>& rhs)
-{
- return lhs.get() == rhs.get();
-}
-
-// This function helps avoid modifying a weak table while holding an iterator into it. (Object allocation
-// can run a finalizer that modifies the table. We avoid that by requiring a pre-constructed object as our value.)
-template<typename Map, typename Key, typename Value> inline void weakAdd(Map& map, const Key& key, Value value)
-{
- ASSERT(!map.get(key));
- map.set(key, value); // The table may still have a zombie for value.
-}
-
-template<typename Map, typename Key, typename Value> inline void weakRemove(Map& map, const Key& key, Value value)
-{
- typename Map::iterator it = map.find(key);
- ASSERT_UNUSED(value, value);
- ASSERT(it != map.end());
- ASSERT(it->value.was(value));
- ASSERT(!it->value);
- map.remove(it);
-}
-
-template<typename T> inline void weakClear(Weak<T>& weak, typename Weak<T>::GetType value)
-{
- ASSERT_UNUSED(value, value);
- ASSERT(weak.was(value));
- ASSERT(!weak);
- weak.clear();
-}
-
} // namespace JSC
-namespace WTF {
-
-template<typename T> struct VectorTraits<JSC::Weak<T> > : SimpleClassVectorTraits {
- static const bool canCompareWithMemcmp = false;
-};
-
-template<typename T> struct HashTraits<JSC::Weak<T> > : SimpleClassHashTraits<JSC::Weak<T> > {
- typedef JSC::Weak<T> StorageType;
-
- typedef std::nullptr_t EmptyValueType;
- static EmptyValueType emptyValue() { return nullptr; }
-
- typedef JSC::PassWeak<T> PassInType;
- static void store(PassInType value, StorageType& storage) { storage = value; }
-
- typedef JSC::PassWeak<T> PassOutType;
- static PassOutType passOut(StorageType& value) { return value.release(); }
- static PassOutType passOut(EmptyValueType) { return PassOutType(); }
-
- typedef typename StorageType::GetType PeekType;
- static PeekType peek(const StorageType& value) { return value.get(); }
- static PeekType peek(EmptyValueType) { return PeekType(); }
-};
-
-}
-
#endif // Weak_h
diff --git a/Source/JavaScriptCore/heap/WeakBlock.cpp b/Source/JavaScriptCore/heap/WeakBlock.cpp
index 5f01f34b3..957090569 100644
--- a/Source/JavaScriptCore/heap/WeakBlock.cpp
+++ b/Source/JavaScriptCore/heap/WeakBlock.cpp
@@ -29,7 +29,7 @@
#include "Heap.h"
#include "HeapRootVisitor.h"
#include "JSObject.h"
-
+#include "Operations.h"
#include "Structure.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/WeakBlock.h b/Source/JavaScriptCore/heap/WeakBlock.h
index fd28101fd..b6b631e27 100644
--- a/Source/JavaScriptCore/heap/WeakBlock.h
+++ b/Source/JavaScriptCore/heap/WeakBlock.h
@@ -97,7 +97,7 @@ inline bool WeakBlock::SweepResult::isNull() const
inline WeakImpl* WeakBlock::asWeakImpl(FreeCell* freeCell)
{
- return reinterpret_cast<WeakImpl*>(freeCell);
+ return reinterpret_cast_ptr<WeakImpl*>(freeCell);
}
inline WeakBlock::SweepResult WeakBlock::takeSweepResult()
@@ -110,12 +110,12 @@ inline WeakBlock::SweepResult WeakBlock::takeSweepResult()
inline WeakBlock::FreeCell* WeakBlock::asFreeCell(WeakImpl* weakImpl)
{
- return reinterpret_cast<FreeCell*>(weakImpl);
+ return reinterpret_cast_ptr<FreeCell*>(weakImpl);
}
inline WeakImpl* WeakBlock::weakImpls()
{
- return reinterpret_cast<WeakImpl*>(this) + ((sizeof(WeakBlock) + sizeof(WeakImpl) - 1) / sizeof(WeakImpl));
+ return reinterpret_cast_ptr<WeakImpl*>(this) + ((sizeof(WeakBlock) + sizeof(WeakImpl) - 1) / sizeof(WeakImpl));
}
inline size_t WeakBlock::weakImplCount()
diff --git a/Source/JavaScriptCore/heap/WeakImpl.h b/Source/JavaScriptCore/heap/WeakImpl.h
index 9924923f9..ca93fb286 100644
--- a/Source/JavaScriptCore/heap/WeakImpl.h
+++ b/Source/JavaScriptCore/heap/WeakImpl.h
@@ -26,7 +26,7 @@
#ifndef WeakImpl_h
#define WeakImpl_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
@@ -107,7 +107,7 @@ inline void* WeakImpl::context()
inline WeakImpl* WeakImpl::asWeakImpl(JSValue* slot)
{
- return reinterpret_cast<WeakImpl*>(reinterpret_cast<char*>(slot) + OBJECT_OFFSETOF(WeakImpl, m_jsValue));
+ return reinterpret_cast_ptr<WeakImpl*>(reinterpret_cast_ptr<char*>(slot) + OBJECT_OFFSETOF(WeakImpl, m_jsValue));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/WeakInlines.h b/Source/JavaScriptCore/heap/WeakInlines.h
new file mode 100644
index 000000000..221b6c11a
--- /dev/null
+++ b/Source/JavaScriptCore/heap/WeakInlines.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2009, 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (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 WeakInlines_h
+#define WeakInlines_h
+
+#include "PassWeak.h"
+#include "WeakSetInlines.h"
+#include <wtf/Assertions.h>
+#include <wtf/HashTraits.h>
+
+namespace JSC {
+
+template<typename T> inline Weak<T>::Weak(T* cell, WeakHandleOwner* weakOwner, void* context)
+ : m_impl(cell ? WeakSet::allocate(cell, weakOwner, context) : 0)
+{
+}
+
+template<typename T> inline bool Weak<T>::isHashTableDeletedValue() const
+{
+ return m_impl == hashTableDeletedValue();
+}
+
+template<typename T> inline Weak<T>::Weak(typename Weak<T>::HashTableDeletedValueTag)
+ : m_impl(hashTableDeletedValue())
+{
+}
+
+template<typename T> template<typename U> inline Weak<T>::Weak(const PassWeak<U>& other)
+ : m_impl(other.leakImpl())
+{
+}
+
+template<class T> inline void swap(Weak<T>& a, Weak<T>& b)
+{
+ a.swap(b);
+}
+
+template<typename T> inline void Weak<T>::swap(Weak& other)
+{
+ std::swap(m_impl, other.m_impl);
+}
+
+template<typename T> inline Weak<T>& Weak<T>::operator=(const PassWeak<T>& o)
+{
+ clear();
+ m_impl = o.leakImpl();
+ return *this;
+}
+
+template<typename T> inline T* Weak<T>::operator->() const
+{
+ ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
+ return jsCast<T*>(m_impl->jsValue().asCell());
+}
+
+template<typename T> inline T& Weak<T>::operator*() const
+{
+ ASSERT(m_impl && m_impl->state() == WeakImpl::Live);
+ return *jsCast<T*>(m_impl->jsValue().asCell());
+}
+
+template<typename T> inline T* Weak<T>::get() const
+{
+ if (!m_impl || m_impl->state() != WeakImpl::Live)
+ return 0;
+ return jsCast<T*>(m_impl->jsValue().asCell());
+}
+
+template<typename T> inline bool Weak<T>::was(T* other) const
+{
+ return jsCast<T*>(m_impl->jsValue().asCell()) == other;
+}
+
+template<typename T> inline bool Weak<T>::operator!() const
+{
+ return !m_impl || !m_impl->jsValue() || m_impl->state() != WeakImpl::Live;
+}
+
+template<typename T> inline Weak<T>::operator UnspecifiedBoolType*() const
+{
+ return reinterpret_cast<UnspecifiedBoolType*>(!!*this);
+}
+
+template<typename T> inline PassWeak<T> Weak<T>::release()
+{
+ PassWeak<T> tmp = adoptWeak<T>(m_impl);
+ m_impl = 0;
+ return tmp;
+}
+
+template<typename T> inline WeakImpl* Weak<T>::hashTableDeletedValue()
+{
+ return reinterpret_cast<WeakImpl*>(-1);
+}
+
+template <typename T> inline bool operator==(const Weak<T>& lhs, const Weak<T>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
+// This function helps avoid modifying a weak table while holding an iterator into it. (Object allocation
+// can run a finalizer that modifies the table. We avoid that by requiring a pre-constructed object as our value.)
+template<typename Map, typename Key, typename Value> inline void weakAdd(Map& map, const Key& key, Value value)
+{
+ ASSERT(!map.get(key));
+ map.set(key, value); // The table may still have a zombie for value.
+}
+
+template<typename Map, typename Key, typename Value> inline void weakRemove(Map& map, const Key& key, Value value)
+{
+ typename Map::iterator it = map.find(key);
+ ASSERT_UNUSED(value, value);
+ ASSERT(it != map.end());
+ ASSERT(it->value.was(value));
+ ASSERT(!it->value);
+ map.remove(it);
+}
+
+template<typename T> inline void weakClear(Weak<T>& weak, T* cell)
+{
+ ASSERT_UNUSED(cell, cell);
+ ASSERT(weak.was(cell));
+ ASSERT(!weak);
+ weak.clear();
+}
+
+} // namespace JSC
+
+namespace WTF {
+
+template<typename T> struct VectorTraits<JSC::Weak<T> > : SimpleClassVectorTraits {
+ static const bool canCompareWithMemcmp = false;
+};
+
+template<typename T> struct HashTraits<JSC::Weak<T> > : SimpleClassHashTraits<JSC::Weak<T> > {
+ typedef JSC::Weak<T> StorageType;
+
+ typedef std::nullptr_t EmptyValueType;
+ static EmptyValueType emptyValue() { return nullptr; }
+
+ typedef JSC::PassWeak<T> PassInType;
+ static void store(PassInType value, StorageType& storage) { storage = value; }
+
+ typedef JSC::PassWeak<T> PassOutType;
+ static PassOutType passOut(StorageType& value) { return value.release(); }
+ static PassOutType passOut(EmptyValueType) { return PassOutType(); }
+
+ typedef T* PeekType;
+ static PeekType peek(const StorageType& value) { return value.get(); }
+ static PeekType peek(EmptyValueType) { return PeekType(); }
+};
+
+} // namespace WTF
+
+#endif // WeakInlines_h
diff --git a/Source/JavaScriptCore/heap/WeakSet.cpp b/Source/JavaScriptCore/heap/WeakSet.cpp
index 7cedaee85..e62e66eae 100644
--- a/Source/JavaScriptCore/heap/WeakSet.cpp
+++ b/Source/JavaScriptCore/heap/WeakSet.cpp
@@ -27,7 +27,7 @@
#include "WeakSet.h"
#include "Heap.h"
-#include "JSGlobalData.h"
+#include "VM.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/WeakSet.h b/Source/JavaScriptCore/heap/WeakSet.h
index 06514eb69..580cbe7a9 100644
--- a/Source/JavaScriptCore/heap/WeakSet.h
+++ b/Source/JavaScriptCore/heap/WeakSet.h
@@ -38,12 +38,12 @@ public:
static WeakImpl* allocate(JSValue, WeakHandleOwner* = 0, void* context = 0);
static void deallocate(WeakImpl*);
- WeakSet(JSGlobalData*);
+ WeakSet(VM*);
~WeakSet();
void lastChanceToFinalize();
Heap* heap() const;
- JSGlobalData* globalData() const;
+ VM* vm() const;
bool isEmpty() const;
@@ -62,19 +62,19 @@ private:
WeakBlock::FreeCell* m_allocator;
WeakBlock* m_nextAllocator;
DoublyLinkedList<WeakBlock> m_blocks;
- JSGlobalData* m_globalData;
+ VM* m_vm;
};
-inline WeakSet::WeakSet(JSGlobalData* globalData)
+inline WeakSet::WeakSet(VM* vm)
: m_allocator(0)
, m_nextAllocator(0)
- , m_globalData(globalData)
+ , m_vm(vm)
{
}
-inline JSGlobalData* WeakSet::globalData() const
+inline VM* WeakSet::vm() const
{
- return m_globalData;
+ return m_vm;
}
inline bool WeakSet::isEmpty() const
diff --git a/Source/JavaScriptCore/heap/WeakSetInlines.h b/Source/JavaScriptCore/heap/WeakSetInlines.h
index 76337fda7..f23922493 100644
--- a/Source/JavaScriptCore/heap/WeakSetInlines.h
+++ b/Source/JavaScriptCore/heap/WeakSetInlines.h
@@ -26,7 +26,7 @@
#ifndef WeakSetInlines_h
#define WeakSetInlines_h
-#include "WeakSet.h"
+#include "MarkedBlock.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/interpreter/AbstractPC.cpp b/Source/JavaScriptCore/interpreter/AbstractPC.cpp
index 12bc3a768..8600b7228 100644
--- a/Source/JavaScriptCore/interpreter/AbstractPC.cpp
+++ b/Source/JavaScriptCore/interpreter/AbstractPC.cpp
@@ -27,19 +27,19 @@
#include "AbstractPC.h"
#include "CallFrame.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSObject.h"
namespace JSC {
-AbstractPC::AbstractPC(JSGlobalData& globalData, ExecState* exec)
+AbstractPC::AbstractPC(VM& vm, ExecState* exec)
{
- UNUSED_PARAM(globalData);
+ UNUSED_PARAM(vm);
UNUSED_PARAM(exec);
#if ENABLE(JIT)
- if (globalData.canUseJIT()) {
+ if (vm.canUseJIT()) {
m_pointer = exec->returnPC().value();
m_mode = JIT;
return;
diff --git a/Source/JavaScriptCore/interpreter/AbstractPC.h b/Source/JavaScriptCore/interpreter/AbstractPC.h
index 09a6db8ea..c30027d9e 100644
--- a/Source/JavaScriptCore/interpreter/AbstractPC.h
+++ b/Source/JavaScriptCore/interpreter/AbstractPC.h
@@ -31,7 +31,7 @@
namespace JSC {
-class JSGlobalData;
+class VM;
class ExecState;
struct Instruction;
@@ -43,7 +43,7 @@ public:
{
}
- AbstractPC(JSGlobalData&, ExecState*);
+ AbstractPC(VM&, ExecState*);
#if ENABLE(JIT)
AbstractPC(ReturnAddressPtr ptr)
diff --git a/Source/JavaScriptCore/interpreter/CachedCall.h b/Source/JavaScriptCore/interpreter/CachedCall.h
index b2513ba6e..ddf9a40ad 100644
--- a/Source/JavaScriptCore/interpreter/CachedCall.h
+++ b/Source/JavaScriptCore/interpreter/CachedCall.h
@@ -38,7 +38,7 @@ namespace JSC {
CachedCall(CallFrame* callFrame, JSFunction* function, int argumentCount)
: m_valid(false)
, m_interpreter(callFrame->interpreter())
- , m_globalObjectScope(callFrame->globalData(), function->scope()->globalObject())
+ , m_globalObjectScope(callFrame->vm(), function->scope()->globalObject())
{
ASSERT(!function->isHostFunction());
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argumentCount + 1, function->scope());
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.cpp b/Source/JavaScriptCore/interpreter/CallFrame.cpp
index ac286c36c..bb61020ce 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.cpp
+++ b/Source/JavaScriptCore/interpreter/CallFrame.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#include "CodeBlock.h"
#include "Interpreter.h"
+#include "Operations.h"
namespace JSC {
@@ -120,9 +121,22 @@ CallFrame* CallFrame::trueCallFrame(AbstractPC pc)
ReturnAddressPtr currentReturnPC = pc.jitReturnAddress();
bool hasCodeOrigin = machineCodeBlock->codeOriginForReturn(currentReturnPC, codeOrigin);
- ASSERT_UNUSED(hasCodeOrigin, hasCodeOrigin);
+ ASSERT(hasCodeOrigin);
+ if (!hasCodeOrigin) {
+ // In release builds, if we find ourselves in a situation where the return PC doesn't
+ // correspond to a valid CodeOrigin, we return zero instead of continuing. Some of
+ // the callers of trueCallFrame() will be able to recover and do conservative things,
+ // while others will crash.
+ return 0;
+ }
} else {
unsigned index = codeOriginIndexForDFG();
+ ASSERT(machineCodeBlock->canGetCodeOrigin(index));
+ if (!machineCodeBlock->canGetCodeOrigin(index)) {
+ // See above. In release builds, we try to protect ourselves from crashing even
+ // though stack walking will be goofed up.
+ return 0;
+ }
codeOrigin = machineCodeBlock->codeOrigin(index);
}
@@ -138,8 +152,8 @@ CallFrame* CallFrame::trueCallFrame(AbstractPC pc)
// Fill in the inlinedCaller
inlinedCaller->setCodeBlock(machineCodeBlock);
-
- inlinedCaller->setScope(calleeAsFunction->scope());
+ if (calleeAsFunction)
+ inlinedCaller->setScope(calleeAsFunction->scope());
if (nextInlineCallFrame)
inlinedCaller->setCallerFrame(this + nextInlineCallFrame->stackOffset);
else
@@ -147,7 +161,8 @@ CallFrame* CallFrame::trueCallFrame(AbstractPC pc)
inlinedCaller->setInlineCallFrame(inlineCallFrame);
inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->arguments.size());
- inlinedCaller->setCallee(calleeAsFunction);
+ if (calleeAsFunction)
+ inlinedCaller->setCallee(calleeAsFunction);
inlineCallFrame = nextInlineCallFrame;
}
@@ -157,6 +172,9 @@ CallFrame* CallFrame::trueCallFrame(AbstractPC pc)
CallFrame* CallFrame::trueCallerFrame()
{
+ if (!codeBlock())
+ return callerFrame()->removeHostCallFrameFlag();
+
// this -> The callee; this is either an inlined callee in which case it already has
// a pointer to the true caller. Otherwise it contains current PC in the machine
// caller.
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index 2b0ea3aac..c09132c57 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -24,9 +24,10 @@
#define CallFrame_h
#include "AbstractPC.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSStack.h"
#include "MacroAssemblerCodeRef.h"
+#include "Register.h"
namespace JSC {
@@ -59,43 +60,46 @@ namespace JSC {
// the actual DOM window, which can't be "this" for security reasons.
JSObject* globalThisValue() const;
- JSGlobalData& globalData() const;
+ VM& vm() const;
// Convenience functions for access to global data.
// It takes a few memory references to get from a call frame to the global data
// pointer, so these are inefficient, and should be used sparingly in new code.
// But they're used in many places in legacy code, so they're not going away any time soon.
- void clearException() { globalData().exception = JSValue(); }
- JSValue exception() const { return globalData().exception; }
- bool hadException() const { return globalData().exception; }
+ void clearException() { vm().exception = JSValue(); }
+ void clearSupplementaryExceptionInfo()
+ {
+ vm().clearExceptionStack();
+ }
+
+ JSValue exception() const { return vm().exception; }
+ bool hadException() const { return vm().exception; }
- const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
- const MarkedArgumentBuffer& emptyList() const { return *globalData().emptyList; }
- Interpreter* interpreter() { return globalData().interpreter; }
- Heap* heap() { return &globalData().heap; }
+ const CommonIdentifiers& propertyNames() const { return *vm().propertyNames; }
+ const MarkedArgumentBuffer& emptyList() const { return *vm().emptyList; }
+ Interpreter* interpreter() { return vm().interpreter; }
+ Heap* heap() { return &vm().heap; }
#ifndef NDEBUG
void dumpCaller();
#endif
- static const HashTable* arrayConstructorTable(CallFrame* callFrame) { return callFrame->globalData().arrayConstructorTable; }
- static const HashTable* arrayPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().arrayPrototypeTable; }
- static const HashTable* booleanPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().booleanPrototypeTable; }
- static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; }
- static const HashTable* dateConstructorTable(CallFrame* callFrame) { return callFrame->globalData().dateConstructorTable; }
- static const HashTable* errorPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().errorPrototypeTable; }
- static const HashTable* globalObjectTable(CallFrame* callFrame) { return callFrame->globalData().globalObjectTable; }
- static const HashTable* jsonTable(CallFrame* callFrame) { return callFrame->globalData().jsonTable; }
- static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
- static const HashTable* numberConstructorTable(CallFrame* callFrame) { return callFrame->globalData().numberConstructorTable; }
- static const HashTable* numberPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().numberPrototypeTable; }
- static const HashTable* objectConstructorTable(CallFrame* callFrame) { return callFrame->globalData().objectConstructorTable; }
- static const HashTable* objectPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().objectPrototypeTable; }
- static const HashTable* privateNamePrototypeTable(CallFrame* callFrame) { return callFrame->globalData().privateNamePrototypeTable; }
- static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
- static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
- static const HashTable* regExpPrototypeTable(CallFrame* callFrame) { return callFrame->globalData().regExpPrototypeTable; }
- static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
- static const HashTable* stringConstructorTable(CallFrame* callFrame) { return callFrame->globalData().stringConstructorTable; }
+ static const HashTable* arrayConstructorTable(CallFrame* callFrame) { return callFrame->vm().arrayConstructorTable; }
+ static const HashTable* arrayPrototypeTable(CallFrame* callFrame) { return callFrame->vm().arrayPrototypeTable; }
+ static const HashTable* booleanPrototypeTable(CallFrame* callFrame) { return callFrame->vm().booleanPrototypeTable; }
+ static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->vm().dateTable; }
+ static const HashTable* dateConstructorTable(CallFrame* callFrame) { return callFrame->vm().dateConstructorTable; }
+ static const HashTable* errorPrototypeTable(CallFrame* callFrame) { return callFrame->vm().errorPrototypeTable; }
+ static const HashTable* globalObjectTable(CallFrame* callFrame) { return callFrame->vm().globalObjectTable; }
+ static const HashTable* jsonTable(CallFrame* callFrame) { return callFrame->vm().jsonTable; }
+ static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->vm().mathTable; }
+ static const HashTable* numberConstructorTable(CallFrame* callFrame) { return callFrame->vm().numberConstructorTable; }
+ static const HashTable* numberPrototypeTable(CallFrame* callFrame) { return callFrame->vm().numberPrototypeTable; }
+ static const HashTable* objectConstructorTable(CallFrame* callFrame) { return callFrame->vm().objectConstructorTable; }
+ static const HashTable* privateNamePrototypeTable(CallFrame* callFrame) { return callFrame->vm().privateNamePrototypeTable; }
+ static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->vm().regExpTable; }
+ static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->vm().regExpConstructorTable; }
+ static const HashTable* regExpPrototypeTable(CallFrame* callFrame) { return callFrame->vm().regExpPrototypeTable; }
+ static const HashTable* stringConstructorTable(CallFrame* callFrame) { return callFrame->vm().stringConstructorTable; }
static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
Register* registers() { return this; }
@@ -108,7 +112,7 @@ namespace JSC {
bool hasReturnPC() const { return !!this[JSStack::ReturnPC].vPC(); }
void clearReturnPC() { registers()[JSStack::ReturnPC] = static_cast<Instruction*>(0); }
#endif
- AbstractPC abstractReturnPC(JSGlobalData& globalData) { return AbstractPC(globalData, this); }
+ AbstractPC abstractReturnPC(VM& vm) { return AbstractPC(vm, this); }
#if USE(JSVALUE32_64)
unsigned bytecodeOffsetForNonDFGCode() const;
void setBytecodeOffsetForNonDFGCode(unsigned offset);
@@ -144,7 +148,7 @@ namespace JSC {
// #if's, we make a dummy implementation available anyway.
InlineCallFrame* inlineCallFrame() const
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
#endif
diff --git a/Source/JavaScriptCore/interpreter/CallFrameClosure.h b/Source/JavaScriptCore/interpreter/CallFrameClosure.h
index 010c9655b..7ae1e6fdf 100644
--- a/Source/JavaScriptCore/interpreter/CallFrameClosure.h
+++ b/Source/JavaScriptCore/interpreter/CallFrameClosure.h
@@ -33,7 +33,7 @@ struct CallFrameClosure {
CallFrame* newCallFrame;
JSFunction* function;
FunctionExecutable* functionExecutable;
- JSGlobalData* globalData;
+ VM* vm;
JSScope* scope;
int parameterCountIncludingThis;
int argumentCountIncludingThis;
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 7d9e6f92e..844f5f252 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -52,21 +52,23 @@
#include "JSString.h"
#include "JSWithScope.h"
#include "LLIntCLoop.h"
+#include "LegacyProfiler.h"
#include "LiteralParser.h"
#include "NameInstance.h"
#include "ObjectPrototype.h"
#include "Operations.h"
#include "Parser.h"
-#include "Profiler.h"
#include "RegExpObject.h"
#include "RegExpPrototype.h"
#include "Register.h"
#include "SamplingTool.h"
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
+#include "VMStackBounds.h"
#include <limits.h>
#include <stdio.h>
#include <wtf/StackStats.h>
+#include <wtf/StringPrintStream.h>
#include <wtf/Threading.h>
#include <wtf/WTFThreadData.h>
#include <wtf/text/StringBuilder.h>
@@ -97,108 +99,7 @@ Interpreter::ErrorHandlingMode::~ErrorHandlingMode()
m_interpreter.stack().disableErrorStackReserve();
}
-
-// The Interpreter::StackPolicy class is used to compute a stack capacity
-// requirement to ensure that we have enough room on the native stack for:
-// 1. the max cumulative stack used by the interpreter and all code
-// paths sub of it up till leaf functions.
-// 2. the max cumulative stack used by the interpreter before it reaches
-// the next checkpoint (execute...() function) in the interpreter.
-//
-// The interpreter can be run on different threads and hence, different
-// native stacks (with different sizes) before exiting out of the first
-// frame. Hence, the required capacity needs to be re-computed on every
-// entry into the interpreter.
-//
-// Currently the requiredStack is computed based on a policy. See comments
-// in StackPolicy::StackPolicy() for details.
-
-Interpreter::StackPolicy::StackPolicy(Interpreter& interpreter, const StackBounds& stack)
- : m_interpreter(interpreter)
-{
- const size_t size = stack.size();
-
- const size_t DEFAULT_REQUIRED_STACK = 1024 * 1024;
- const size_t DEFAULT_MINIMUM_USEABLE_STACK = 128 * 1024;
- const size_t DEFAULT_ERROR_MODE_REQUIRED_STACK = 32 * 1024;
-
- // Here's the policy in a nutshell:
- //
- // 1. If we have a large stack, let JS use as much stack as possible
- // but require that we have at least DEFAULT_REQUIRED_STACK capacity
- // remaining on the stack:
- //
- // stack grows this way -->
- // ---------------------------------------------------------
- // | ... | <-- DEFAULT_REQUIRED_STACK --> | ...
- // ---------------------------------------------------------
- // ^ ^
- // start current sp
- //
- // 2. In event that we're re-entering the interpreter to handle
- // exceptions (in error mode), we'll be a little more generous and
- // require less stack capacity for the interpreter to be re-entered.
- //
- // This is needed because we may have just detected an eminent stack
- // overflow based on the normally computed required stack capacity.
- // However, the normal required capacity far exceeds what is needed
- // for exception handling work. Hence, in error mode, we only require
- // DEFAULT_ERROR_MODE_REQUIRED_STACK capacity.
- //
- // stack grows this way -->
- // -----------------------------------------------------------------
- // | ... | <-- DEFAULT_ERROR_MODE_REQUIRED_STACK --> | ...
- // -----------------------------------------------------------------
- // ^ ^
- // start current sp
- //
- // This smaller required capacity also means that we won't re-trigger
- // a stack overflow for processing the exception caused by the original
- // StackOverflowError.
- //
- // 3. If the stack is not large enough, give JS at least a minimum
- // amount of useable stack:
- //
- // stack grows this way -->
- // --------------------------------------------------------------------
- // | <-- DEFAULT_MINIMUM_USEABLE_STACK --> | <-- requiredCapacity --> |
- // --------------------------------------------------------------------
- // ^ ^
- // start current sp
- //
- // The minimum useable capacity is DEFAULT_MINIMUM_USEABLE_STACK.
- // In this case, the requiredCapacity is whatever is left of the
- // total stack capacity after we have give JS its minimum stack
- // i.e. requiredCapacity can even be 0 if there's not enough stack.
-
-
- // Policy 1: Normal mode: required = DEFAULT_REQUIRED_STACK.
- // Policy 2: Error mode: required = DEFAULT_ERROR_MODE_REQUIRED_STACK.
- size_t requiredCapacity = !m_interpreter.m_errorHandlingModeReentry ?
- DEFAULT_REQUIRED_STACK : DEFAULT_ERROR_MODE_REQUIRED_STACK;
-
- size_t useableStack = (requiredCapacity <= size) ?
- size - requiredCapacity : DEFAULT_MINIMUM_USEABLE_STACK;
-
- // Policy 3: Ensure the useable stack is not too small:
- if (useableStack < DEFAULT_MINIMUM_USEABLE_STACK)
- useableStack = DEFAULT_MINIMUM_USEABLE_STACK;
-
- // Sanity check: Make sure we do not use more space than the stack's
- // total capacity:
- if (useableStack > size)
- useableStack = size;
-
- // Re-compute the requiredCapacity based on the adjusted useable stack
- // size:
- requiredCapacity = size - useableStack;
- ASSERT(requiredCapacity < size);
-
- m_requiredCapacity = requiredCapacity;
-}
-
-
-static CallFrame* getCallerInfo(JSGlobalData*, CallFrame*, int& lineNumber, unsigned& bytecodeOffset);
+static CallFrame* getCallerInfo(VM*, CallFrame*, unsigned& bytecodeOffset, CodeBlock*& callerOut);
// Returns the depth of the scope chain within a given call frame.
static int depth(CodeBlock* codeBlock, JSScope* sc)
@@ -217,7 +118,7 @@ JSValue eval(CallFrame* callFrame)
if (!program.isString())
return program;
- TopCallFrameSetter topCallFrame(callFrame->globalData(), callFrame);
+ TopCallFrameSetter topCallFrame(callFrame->vm(), callFrame);
String programSource = asString(program)->value(callFrame);
if (callFrame->hadException())
return JSValue();
@@ -243,10 +144,10 @@ JSValue eval(CallFrame* callFrame)
}
// If the literal parser bailed, it should not have thrown exceptions.
- ASSERT(!callFrame->globalData().exception);
+ ASSERT(!callFrame->vm().exception);
JSValue exceptionValue;
- eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain, exceptionValue);
+ eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->unlinkedCodeBlock()->codeCacheForEval().get(), callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain, exceptionValue);
ASSERT(!eval == exceptionValue);
if (UNLIKELY(!eval))
@@ -255,7 +156,7 @@ JSValue eval(CallFrame* callFrame)
JSValue thisValue = callerFrame->thisValue();
ASSERT(isValidThisObject(thisValue, callFrame));
- Interpreter* interpreter = callFrame->globalData().interpreter;
+ Interpreter* interpreter = callFrame->vm().interpreter;
return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
}
@@ -265,7 +166,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue,
unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->grow(newCallFrame->registers())) {
- callFrame->globalData().exception = createStackOverflowError(callFrame);
+ callFrame->vm().exception = createStackOverflowError(callFrame);
return 0;
}
@@ -279,7 +180,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue,
if (arguments.isUndefinedOrNull()) {
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + JSStack::CallFrameHeaderSize);
if (!stack->grow(newCallFrame->registers())) {
- callFrame->globalData().exception = createStackOverflowError(callFrame);
+ callFrame->vm().exception = createStackOverflowError(callFrame);
return 0;
}
newCallFrame->setArgumentCountIncludingThis(1);
@@ -288,7 +189,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue,
}
if (!arguments.isObject()) {
- callFrame->globalData().exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
+ callFrame->vm().exception = createInvalidParameterError(callFrame, "Function.prototype.apply", arguments);
return 0;
}
@@ -297,7 +198,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue,
unsigned argCount = argsObject->length(callFrame);
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
- callFrame->globalData().exception = createStackOverflowError(callFrame);
+ callFrame->vm().exception = createStackOverflowError(callFrame);
return 0;
}
newCallFrame->setArgumentCountIncludingThis(argCount + 1);
@@ -311,7 +212,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue,
unsigned argCount = array->length();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
- callFrame->globalData().exception = createStackOverflowError(callFrame);
+ callFrame->vm().exception = createStackOverflowError(callFrame);
return 0;
}
newCallFrame->setArgumentCountIncludingThis(argCount + 1);
@@ -324,22 +225,22 @@ CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue,
unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
- callFrame->globalData().exception = createStackOverflowError(callFrame);
+ callFrame->vm().exception = createStackOverflowError(callFrame);
return 0;
}
newCallFrame->setArgumentCountIncludingThis(argCount + 1);
newCallFrame->setThisValue(thisValue);
for (size_t i = 0; i < argCount; ++i) {
newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i));
- if (UNLIKELY(callFrame->globalData().exception))
+ if (UNLIKELY(callFrame->vm().exception))
return 0;
}
return newCallFrame;
}
-Interpreter::Interpreter(JSGlobalData& globalData)
+Interpreter::Interpreter(VM& vm)
: m_sampleEntryDepth(0)
- , m_stack(globalData)
+ , m_stack(vm)
, m_errorHandlingModeReentry(0)
#if !ASSERT_DISABLED
, m_initialized(false)
@@ -401,7 +302,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
JSValue v = it->jsValue();
int registerNumber = it - callFrame->registers();
String name = codeBlock->nameForRegister(registerNumber);
- dataLogF("[r% 3d %14s] | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, v.description(), (long long)JSValue::encode(v));
+ dataLogF("[r% 3d %14s] | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
it++;
}
@@ -415,13 +316,15 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
dataLogF("[ScopeChain] | %10p | %p \n", it, callFrame->scope());
++it;
#if ENABLE(JIT)
- AbstractPC pc = callFrame->abstractReturnPC(callFrame->globalData());
+ AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm());
if (pc.hasJITReturnAddress())
dataLogF("[ReturnJITPC] | %10p | %p \n", it, pc.jitReturnAddress().value());
#endif
unsigned bytecodeOffset = 0;
int line = 0;
- getCallerInfo(&callFrame->globalData(), callFrame, line, bytecodeOffset);
+ CodeBlock* callerCodeBlock = 0;
+ getCallerInfo(&callFrame->vm(), callFrame, bytecodeOffset, callerCodeBlock);
+ line = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset);
dataLogF("[ReturnVPC] | %10p | %d (line %d)\n", it, bytecodeOffset, line);
++it;
dataLogF("[CodeBlock] | %10p | %p \n", it, callFrame->codeBlock());
@@ -436,7 +339,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
JSValue v = it->jsValue();
int registerNumber = it - callFrame->registers();
String name = codeBlock->nameForRegister(registerNumber);
- dataLogF("[r% 3d %14s] | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, v.description(), (long long)JSValue::encode(v));
+ dataLogF("[r% 3d %14s] | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
++it;
++registerCount;
} while (it != end);
@@ -447,7 +350,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
if (it != end) {
do {
JSValue v = (*it).jsValue();
- dataLogF("[r% 3d] | %10p | %-16s 0x%lld \n", registerCount, it, v.description(), (long long)JSValue::encode(v));
+ dataLogF("[r% 3d] | %10p | %-16s 0x%lld \n", registerCount, it, toCString(v).data(), (long long)JSValue::encode(v));
++it;
++registerCount;
} while (it != end);
@@ -489,7 +392,7 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsActivation()) {
activation = callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue();
if (activation)
- jsCast<JSActivation*>(activation)->tearOff(*scope->globalData());
+ jsCast<JSActivation*>(activation)->tearOff(*scope->vm());
}
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->usesArguments()) {
@@ -502,20 +405,10 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
}
CallFrame* callerFrame = callFrame->callerFrame();
- callFrame->globalData().topCallFrame = callerFrame;
+ callFrame->vm().topCallFrame = callerFrame;
if (callerFrame->hasHostCallFrameFlag())
return false;
-
- codeBlock = callerFrame->codeBlock();
-
- // Because of how the JIT records call site->bytecode offset
- // information the JIT reports the bytecodeOffset for the returnPC
- // to be at the beginning of the opcode that has caused the call.
-#if ENABLE(JIT) || ENABLE(LLINT)
- bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
-#endif
-
- callFrame = callerFrame;
+ callFrame = getCallerInfo(&callFrame->vm(), callFrame, bytecodeOffset, codeBlock);
return true;
}
@@ -529,9 +422,11 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
+ unsigned line = 0;
+ unsigned column = 0;
CodeBlock* codeBlock = callFrame->codeBlock();
- codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset);
+ codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset, line, column);
int expressionStart = divotPoint - startOffset;
int expressionStop = divotPoint + endOffset;
@@ -540,8 +435,8 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
return;
- JSGlobalData* globalData = &callFrame->globalData();
- JSValue jsMessage = exception->getDirect(*globalData, globalData->propertyNames->message);
+ VM* vm = &callFrame->vm();
+ JSValue jsMessage = exception->getDirect(*vm, vm->propertyNames->message);
if (!jsMessage || !jsMessage.isString())
return;
@@ -568,64 +463,54 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
}
- exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
+ exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
}
-static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFrame)
+static unsigned getBytecodeOffsetForCallFrame(CallFrame* callFrame)
{
- UNUSED_PARAM(globalData);
callFrame = callFrame->removeHostCallFrameFlag();
CodeBlock* codeBlock = callFrame->codeBlock();
if (!codeBlock)
- return -1;
-#if ENABLE(JIT) || ENABLE(LLINT)
+ return 0;
#if ENABLE(DFG_JIT)
if (codeBlock->getJITType() == JITCode::DFGJIT)
- return codeBlock->lineNumberForBytecodeOffset(codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex);
-#endif
- return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());
+ return codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex;
#endif
+ return callFrame->bytecodeOffsetForNonDFGCode();
}
-static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber, unsigned& bytecodeOffset)
+static CallFrame* getCallerInfo(VM* vm, CallFrame* callFrame, unsigned& bytecodeOffset, CodeBlock*& caller)
{
- UNUSED_PARAM(globalData);
+ ASSERT_UNUSED(vm, vm);
bytecodeOffset = 0;
- lineNumber = -1;
ASSERT(!callFrame->hasHostCallFrameFlag());
- CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag();
- bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame();
- ASSERT(!callerFrame->hasHostCallFrameFlag());
+ CallFrame* trueCallerFrame = callFrame->trueCallerFrame();
+ bool wasCalledByHost = callFrame->callerFrame()->hasHostCallFrameFlag();
+ ASSERT(!trueCallerFrame->hasHostCallFrameFlag());
- if (callerFrame == CallFrame::noCaller() || !callerFrame || !callerFrame->codeBlock())
- return callerFrame;
+ if (trueCallerFrame == CallFrame::noCaller() || !trueCallerFrame || !trueCallerFrame->codeBlock()) {
+ caller = 0;
+ return trueCallerFrame;
+ }
- CodeBlock* callerCodeBlock = callerFrame->codeBlock();
+ CodeBlock* callerCodeBlock = trueCallerFrame->codeBlock();
-#if ENABLE(JIT) || ENABLE(LLINT)
if (!callFrame->hasReturnPC())
- callframeIsHost = true;
-#endif
-#if ENABLE(DFG_JIT)
- if (callFrame->isInlineCallFrame())
- callframeIsHost = false;
-#endif
+ wasCalledByHost = true;
- 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(JIT) || ENABLE(LLINT)
+ if (wasCalledByHost) {
#if ENABLE(DFG_JIT)
if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
- unsigned codeOriginIndex = callerFrame->codeOriginIndexForDFG();
- bytecodeOffset = callerCodeBlock->codeOrigin(codeOriginIndex).bytecodeIndex;
+ unsigned codeOriginIndex = callFrame->callerFrame()->removeHostCallFrameFlag()->codeOriginIndexForDFG();
+ CodeOrigin origin = callerCodeBlock->codeOrigin(codeOriginIndex);
+ bytecodeOffset = origin.bytecodeIndex;
+ if (InlineCallFrame* inlineCallFrame = origin.inlineCallFrame)
+ callerCodeBlock = inlineCallFrame->baselineCodeBlock();
} else
#endif
- bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
-#endif
+ bytecodeOffset = trueCallerFrame->bytecodeOffsetForNonDFGCode();
} else {
-#if ENABLE(JIT) || ENABLE(LLINT)
- #if ENABLE(DFG_JIT)
+#if ENABLE(DFG_JIT)
if (callFrame->isInlineCallFrame()) {
InlineCallFrame* icf = callFrame->inlineCallFrame();
bytecodeOffset = icf->caller.bytecodeIndex;
@@ -638,8 +523,14 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
}
} else if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
CodeOrigin origin;
- if (!callerCodeBlock->codeOriginForReturn(callFrame->returnPC(), origin))
+ if (!callerCodeBlock->codeOriginForReturn(callFrame->returnPC(), origin)) {
+ // This should not be possible, but we're seeing cases where it does happen
+ // CallFrame already has robustness against bogus stack walks, so
+ // we'll extend that to here as well.
ASSERT_NOT_REACHED();
+ caller = 0;
+ return 0;
+ }
bytecodeOffset = origin.bytecodeIndex;
if (InlineCallFrame* icf = origin.inlineCallFrame) {
FunctionExecutable* executable = static_cast<FunctionExecutable*>(icf->executable.get());
@@ -649,13 +540,16 @@ static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame,
callerCodeBlock = newCodeBlock;
}
} else
- #endif
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
#endif
+ {
+ RELEASE_ASSERT(callerCodeBlock);
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(trueCallerFrame, callFrame->returnPC());
+ }
}
- lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset);
- return callerFrame;
+ RELEASE_ASSERT(callerCodeBlock);
+ caller = callerCodeBlock;
+ return trueCallerFrame;
}
static ALWAYS_INLINE const String getSourceURLFromCallFrame(CallFrame* callFrame)
@@ -676,52 +570,118 @@ static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame)
case GlobalCode:
return StackFrameGlobalCode;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return StackFrameGlobalCode;
}
-void Interpreter::getStackTrace(JSGlobalData* globalData, Vector<StackFrame>& results)
+void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column)
{
- CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag();
- if (!callFrame || callFrame == CallFrame::noCaller())
+ if (!codeBlock) {
+ line = 0;
+ column = 0;
return;
- int line = getLineNumberForCallFrame(globalData, callFrame);
+ }
+ int divot = 0;
+ int unusedStartOffset = 0;
+ int unusedEndOffset = 0;
+ unsigned divotLine = 0;
+ unsigned divotColumn = 0;
+ expressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
+
+ line = divotLine + lineOffset;
+ column = divotColumn + (divotLine ? 1 : firstLineColumnOffset);
+}
+
+void StackFrame::expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
+{
+ codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
+ divot += characterOffset;
+}
+
+String StackFrame::toString(CallFrame* callFrame)
+{
+ StringBuilder traceBuild;
+ String functionName = friendlyFunctionName(callFrame);
+ String sourceURL = friendlySourceURL();
+ traceBuild.append(functionName);
+ if (!sourceURL.isEmpty()) {
+ if (!functionName.isEmpty())
+ traceBuild.append('@');
+ traceBuild.append(sourceURL);
+ if (codeType != StackFrameNativeCode) {
+ unsigned line;
+ unsigned column;
+ computeLineAndColumn(line, column);
+
+ traceBuild.append(':');
+ traceBuild.appendNumber(line);
+ traceBuild.append(':');
+ traceBuild.appendNumber(column);
+ }
+ }
+ return traceBuild.toString().impl();
+}
+
+void Interpreter::getStackTrace(VM* vm, Vector<StackFrame>& results, size_t maxStackSize)
+{
+ CallFrame* callFrame = vm->topCallFrame->removeHostCallFrameFlag();
+ if (!callFrame || callFrame == CallFrame::noCaller())
+ return;
+ unsigned bytecodeOffset = getBytecodeOffsetForCallFrame(callFrame);
callFrame = callFrame->trueCallFrameFromVMCode();
+ if (!callFrame)
+ return;
+ CodeBlock* callerCodeBlock = callFrame->codeBlock();
- while (callFrame && callFrame != CallFrame::noCaller()) {
+ while (callFrame && callFrame != CallFrame::noCaller() && maxStackSize--) {
String sourceURL;
- if (callFrame->codeBlock()) {
+ if (callerCodeBlock) {
sourceURL = getSourceURLFromCallFrame(callFrame);
- StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*globalData, callFrame->codeBlock()->ownerExecutable()), line, sourceURL};
+ StackFrame s = {
+ Strong<JSObject>(*vm, callFrame->callee()),
+ getStackFrameCodeType(callFrame),
+ Strong<ExecutableBase>(*vm, callerCodeBlock->ownerExecutable()),
+ Strong<UnlinkedCodeBlock>(*vm, callerCodeBlock->unlinkedCodeBlock()),
+ callerCodeBlock->source(),
+ callerCodeBlock->ownerExecutable()->lineNo(),
+ callerCodeBlock->firstLineColumnOffset(),
+ callerCodeBlock->sourceOffset(),
+ bytecodeOffset,
+ sourceURL
+ };
+
results.append(s);
} else {
- StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, String()};
+ StackFrame s = { Strong<JSObject>(*vm, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
results.append(s);
}
- unsigned unusedBytecodeOffset = 0;
- callFrame = getCallerInfo(globalData, callFrame, line, unusedBytecodeOffset);
+ callFrame = getCallerInfo(vm, callFrame, bytecodeOffset, callerCodeBlock);
}
}
-void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSObject* error)
+void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSValue error)
{
- JSGlobalData* globalData = &callFrame->globalData();
- ASSERT(callFrame == globalData->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec());
- if (error->hasProperty(callFrame, globalData->propertyNames->stack))
- return;
+ VM* vm = &callFrame->vm();
+ ASSERT(callFrame == vm->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec());
- Vector<StackFrame> stackTrace;
- getStackTrace(&callFrame->globalData(), stackTrace);
+ if (error.isObject()) {
+ if (asObject(error)->hasProperty(callFrame, vm->propertyNames->stack))
+ return;
+ }
- if (stackTrace.isEmpty())
+ Vector<StackFrame> stackTrace;
+ getStackTrace(&callFrame->vm(), stackTrace);
+ vm->exceptionStack() = RefCountedArray<StackFrame>(stackTrace);
+ if (stackTrace.isEmpty() || !error.isObject())
return;
-
+
+ JSObject* errorObject = asObject(error);
JSGlobalObject* globalObject = 0;
- if (isTerminatedExecutionException(error) || isInterruptedExecutionException(error))
- globalObject = globalData->dynamicGlobalObject;
+ if (isTerminatedExecutionException(error))
+ globalObject = vm->dynamicGlobalObject;
else
- globalObject = error->globalObject();
+ globalObject = errorObject->globalObject();
// FIXME: JSStringJoiner could be more efficient than StringBuilder here.
StringBuilder builder;
@@ -730,14 +690,14 @@ void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSObject* error
if (i != stackTrace.size() - 1)
builder.append('\n');
}
-
- error->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, builder.toString()), ReadOnly | DontDelete);
+
+ errorObject->putDirect(*vm, vm->propertyNames->stack, jsString(vm, builder.toString()), ReadOnly | DontDelete);
}
NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
{
CodeBlock* codeBlock = callFrame->codeBlock();
- bool isInterrupt = false;
+ bool isTermination = false;
ASSERT(!exceptionValue.isEmpty());
ASSERT(!exceptionValue.isCell() || exceptionValue.asCell());
@@ -759,7 +719,13 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source());
}
- isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception);
+ isTermination = isTerminatedExecutionException(exception);
+ } else {
+ if (!callFrame->vm().exceptionStack().size()) {
+ Vector<StackFrame> stack;
+ Interpreter::getStackTrace(&callFrame->vm(), stack);
+ callFrame->vm().exceptionStack() = RefCountedArray<StackFrame>(stack);
+ }
}
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
@@ -770,15 +736,15 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
// Calculate an exception handler vPC, unwinding call frames as necessary.
HandlerInfo* handler = 0;
- while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
+ while (isTermination || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
- if (Profiler* profiler = callFrame->globalData().enabledProfiler())
+ if (LegacyProfiler* profiler = callFrame->vm().enabledProfiler())
profiler->exceptionUnwind(callFrame);
return 0;
}
}
- if (Profiler* profiler = callFrame->globalData().enabledProfiler())
+ if (LegacyProfiler* profiler = callFrame->vm().enabledProfiler())
profiler->exceptionUnwind(callFrame);
// Unwind the scope chain within the exception handler's call frame.
@@ -789,7 +755,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
int currentDepth = depth(codeBlock, scope);
int targetDepth = handler->scopeDepth;
scopeDelta = currentDepth - targetDepth;
- ASSERT(scopeDelta >= 0);
+ RELEASE_ASSERT(scopeDelta >= 0);
}
while (scopeDelta--)
scope = scope->next();
@@ -830,24 +796,23 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
SamplingScope samplingScope(this);
JSScope* scope = callFrame->scope();
- JSGlobalData& globalData = *scope->globalData();
+ VM& vm = *scope->vm();
ASSERT(isValidThisObject(thisObj, callFrame));
- ASSERT(!globalData.exception);
- ASSERT(!globalData.isCollectorBusy());
- if (globalData.isCollectorBusy())
- CRASH();
+ ASSERT(!vm.exception);
+ ASSERT(!vm.isCollectorBusy());
+ if (vm.isCollectorBusy())
+ return jsNull();
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
// First check if the "program" is actually just a JSON object. If so,
// we'll handle the JSON object here. Else, we'll handle real JS code
// below at failedJSONP.
- DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
Vector<JSONPData> JSONPData;
bool parseResult;
const String programSource = program->source().toString();
@@ -904,7 +869,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
continue;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return jsUndefined();
}
}
@@ -939,7 +904,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
break;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return jsUndefined();
}
result = JSONPValue;
@@ -951,7 +916,7 @@ failedJSONP:
// object.
// Compile source to bytecode if necessary:
- if (JSObject* error = program->initalizeGlobalProperties(globalData, callFrame, scope))
+ if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
return checkedReturn(throwError(callFrame, error));
if (JSObject* error = program->compile(callFrame, scope))
@@ -959,6 +924,9 @@ failedJSONP:
ProgramCodeBlock* codeBlock = &program->generatedBytecode();
+ if (UNLIKELY(vm.watchdog.didFire(callFrame)))
+ return throwTerminatedExecutionException(callFrame);
+
// Push the call frame for this invocation:
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
@@ -968,22 +936,23 @@ failedJSONP:
// Set the arguments for the callee:
newCallFrame->setThisValue(thisObj);
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, program->sourceURL(), program->lineNo());
// Execute the code:
JSValue result;
{
SamplingTool::CallRecord callRecord(m_sampler.get());
+ Watchdog::Scope watchdogScope(vm.watchdog);
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
#elif ENABLE(JIT)
- result = program->generatedJITCode().execute(&m_stack, newCallFrame, &globalData);
+ result = program->generatedJITCode().execute(&m_stack, newCallFrame, &vm);
#endif // ENABLE(JIT)
}
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
m_stack.popFrame(newCallFrame);
@@ -993,17 +962,16 @@ failedJSONP:
JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
{
- JSGlobalData& globalData = callFrame->globalData();
+ VM& vm = callFrame->vm();
ASSERT(isValidThisObject(thisValue, callFrame));
ASSERT(!callFrame->hadException());
- ASSERT(!globalData.isCollectorBusy());
- if (globalData.isCollectorBusy())
+ ASSERT(!vm.isCollectorBusy());
+ if (vm.isCollectorBusy())
return jsNull();
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
bool isJSCall = (callType == CallTypeJS);
@@ -1017,7 +985,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
ASSERT(callType == CallTypeHost);
scope = callFrame->scope();
}
- DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
if (isJSCall) {
// Compile the callee:
@@ -1030,6 +998,9 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
} else
newCodeBlock = 0;
+ if (UNLIKELY(vm.watchdog.didFire(callFrame)))
+ return throwTerminatedExecutionException(callFrame);
+
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
if (UNLIKELY(!newCallFrame))
return checkedReturn(throwStackOverflowError(callFrame));
@@ -1039,25 +1010,26 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
for (size_t i = 0; i < args.size(); ++i)
newCallFrame->setArgument(i, args.at(i));
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, function);
JSValue result;
{
SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
+ Watchdog::Scope watchdogScope(vm.watchdog);
// Execute the code:
if (isJSCall) {
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
#elif ENABLE(JIT)
- result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_stack, newCallFrame, &globalData);
+ result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_stack, newCallFrame, &vm);
#endif // ENABLE(JIT)
} else
result = JSValue::decode(callData.native.function(newCallFrame));
}
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, function);
m_stack.popFrame(newCallFrame);
@@ -1066,18 +1038,17 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
{
- JSGlobalData& globalData = callFrame->globalData();
+ VM& vm = callFrame->vm();
ASSERT(!callFrame->hadException());
- ASSERT(!globalData.isCollectorBusy());
+ ASSERT(!vm.isCollectorBusy());
// We throw in this case because we have to return something "valid" but we're
// already in an invalid state.
- if (globalData.isCollectorBusy())
+ if (vm.isCollectorBusy())
return checkedReturn(throwStackOverflowError(callFrame));
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
bool isJSConstruct = (constructType == ConstructTypeJS);
@@ -1092,7 +1063,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
scope = callFrame->scope();
}
- DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
if (isJSConstruct) {
// Compile the callee:
@@ -1105,6 +1076,9 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
} else
newCodeBlock = 0;
+ if (UNLIKELY(vm.watchdog.didFire(callFrame)))
+ return throwTerminatedExecutionException(callFrame);
+
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, constructor);
if (UNLIKELY(!newCallFrame))
return checkedReturn(throwStackOverflowError(callFrame));
@@ -1114,26 +1088,26 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
for (size_t i = 0; i < args.size(); ++i)
newCallFrame->setArgument(i, args.at(i));
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, constructor);
JSValue result;
{
SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
+ Watchdog::Scope watchdogScope(vm.watchdog);
// Execute the code.
if (isJSConstruct) {
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
#elif ENABLE(JIT)
- result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_stack, newCallFrame, &globalData);
+ result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_stack, newCallFrame, &vm);
#endif // ENABLE(JIT)
- } else {
+ } else
result = JSValue::decode(constructData.native.function(newCallFrame));
- }
}
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, constructor);
m_stack.popFrame(newCallFrame);
@@ -1146,16 +1120,15 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
{
- JSGlobalData& globalData = *scope->globalData();
- ASSERT(!globalData.exception);
+ VM& vm = *scope->vm();
+ ASSERT(!vm.exception);
- if (globalData.isCollectorBusy())
+ if (vm.isCollectorBusy())
return CallFrameClosure();
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity())) {
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse()) {
throwStackOverflowError(callFrame);
return CallFrameClosure();
}
@@ -1182,17 +1155,17 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
}
// Return the successful closure:
- CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &globalData, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
+ CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
return result;
}
JSValue Interpreter::execute(CallFrameClosure& closure)
{
- JSGlobalData& globalData = *closure.globalData;
+ VM& vm = *closure.vm;
SamplingScope samplingScope(this);
- ASSERT(!globalData.isCollectorBusy());
- if (globalData.isCollectorBusy())
+ ASSERT(!vm.isCollectorBusy());
+ if (vm.isCollectorBusy())
return jsNull();
StackStats::CheckPoint stackCheckPoint;
@@ -1200,9 +1173,12 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
closure.resetCallFrame();
m_stack.validateFence(closure.newCallFrame, "STEP 1");
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(closure.oldCallFrame, closure.function);
+ if (UNLIKELY(vm.watchdog.didFire(closure.oldCallFrame)))
+ return throwTerminatedExecutionException(closure.oldCallFrame);
+
// The code execution below may push more frames and point the topCallFrame
// to those newer frames, or it may pop to the top frame to the caller of
// the current repeat frame, or it may leave the top frame pointing to the
@@ -1211,21 +1187,22 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
// Hence, we need to preserve the topCallFrame here ourselves before
// repeating this call on a second callback function.
- TopCallFrameSetter topCallFrame(globalData, closure.newCallFrame);
+ TopCallFrameSetter topCallFrame(vm, closure.newCallFrame);
// Execute the code:
JSValue result;
{
SamplingTool::CallRecord callRecord(m_sampler.get());
-
+ Watchdog::Scope watchdogScope(vm.watchdog);
+
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
#elif ENABLE(JIT)
- result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_stack, closure.newCallFrame, &globalData);
+ result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_stack, closure.newCallFrame, &vm);
#endif // ENABLE(JIT)
}
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(closure.oldCallFrame, closure.function);
m_stack.validateFence(closure.newCallFrame, "AFTER");
@@ -1239,22 +1216,21 @@ void Interpreter::endRepeatCall(CallFrameClosure& closure)
JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
{
- JSGlobalData& globalData = *scope->globalData();
+ VM& vm = *scope->vm();
SamplingScope samplingScope(this);
- ASSERT(scope->globalData() == &callFrame->globalData());
+ ASSERT(scope->vm() == &callFrame->vm());
ASSERT(isValidThisObject(thisValue, callFrame));
- ASSERT(!globalData.exception);
- ASSERT(!globalData.isCollectorBusy());
- if (globalData.isCollectorBusy())
+ ASSERT(!vm.exception);
+ ASSERT(!vm.isCollectorBusy());
+ if (vm.isCollectorBusy())
return jsNull();
- DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(vm, scope->globalObject());
StackStats::CheckPoint stackCheckPoint;
- const StackBounds& nativeStack = wtfThreadData().stack();
- StackPolicy policy(*this, nativeStack);
- if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
+ const VMStackBounds vmStackBounds(vm, wtfThreadData().stack());
+ if (!vmStackBounds.isSafeToRecurse())
return checkedReturn(throwStackOverflowError(callFrame));
// Compile the callee:
@@ -1265,7 +1241,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
JSObject* variableObject;
for (JSScope* node = scope; ; node = node->next()) {
- ASSERT(node);
+ RELEASE_ASSERT(node);
if (node->isVariableObject() && !node->isNameScopeObject()) {
variableObject = node;
break;
@@ -1280,7 +1256,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
variableObject = scope;
}
// Scope for BatchedTransitionOptimizer
- BatchedTransitionOptimizer optimizer(globalData, variableObject);
+ BatchedTransitionOptimizer optimizer(vm, variableObject);
for (unsigned i = 0; i < numVariables; ++i) {
const Identifier& ident = codeBlock->variable(i);
@@ -1297,6 +1273,9 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
}
}
+ if (UNLIKELY(vm.watchdog.didFire(callFrame)))
+ return throwTerminatedExecutionException(callFrame);
+
// Push the frame:
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
@@ -1306,22 +1285,23 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
// Set the arguments for the callee:
newCallFrame->setThisValue(thisValue);
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo());
// Execute the code:
JSValue result;
{
SamplingTool::CallRecord callRecord(m_sampler.get());
-
+ Watchdog::Scope watchdogScope(vm.watchdog);
+
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
#elif ENABLE(JIT)
- result = eval->generatedJITCode().execute(&m_stack, newCallFrame, &globalData);
+ result = eval->generatedJITCode().execute(&m_stack, newCallFrame, &vm);
#endif // ENABLE(JIT)
}
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
m_stack.popFrame(newCallFrame);
@@ -1362,7 +1342,7 @@ JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunctio
if (!functionCallFrame)
return jsNull();
- Arguments* arguments = Arguments::create(functionCallFrame->globalData(), functionCallFrame);
+ Arguments* arguments = Arguments::create(functionCallFrame->vm(), functionCallFrame);
arguments->tearOff(functionCallFrame);
return JSValue(arguments);
}
@@ -1374,9 +1354,9 @@ JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction*
if (!functionCallFrame)
return jsNull();
- int lineNumber;
unsigned bytecodeOffset;
- CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, lineNumber, bytecodeOffset);
+ CodeBlock* unusedCallerCodeBlock = 0;
+ CallFrame* callerFrame = getCallerInfo(&callFrame->vm(), functionCallFrame, bytecodeOffset, unusedCallerCodeBlock);
if (!callerFrame)
return jsNull();
JSValue caller = callerFrame->callee();
@@ -1386,7 +1366,7 @@ JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction*
// Skip over function bindings.
ASSERT(caller.isObject());
while (asObject(caller)->inherits(&JSBoundFunction::s_info)) {
- callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, lineNumber, bytecodeOffset);
+ callerFrame = getCallerInfo(&callFrame->vm(), callerFrame, bytecodeOffset, unusedCallerCodeBlock);
if (!callerFrame)
return jsNull();
caller = callerFrame->callee();
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index c3bca1ad7..e5eca0e1c 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2012 Research In Motion Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,9 @@
#define Interpreter_h
#include "ArgList.h"
+#include "JSCJSValue.h"
#include "JSCell.h"
#include "JSFunction.h"
-#include "JSValue.h"
#include "JSObject.h"
#include "JSStack.h"
#include "LLIntData.h"
@@ -48,7 +48,7 @@ namespace JSC {
class EvalExecutable;
class ExecutableBase;
class FunctionExecutable;
- class JSGlobalData;
+ class VM;
class JSGlobalObject;
class LLIntOffsetsExtractor;
class ProgramExecutable;
@@ -79,25 +79,14 @@ namespace JSC {
Strong<JSObject> callee;
StackFrameCodeType codeType;
Strong<ExecutableBase> executable;
- int line;
+ Strong<UnlinkedCodeBlock> codeBlock;
+ RefPtr<SourceProvider> code;
+ int lineOffset;
+ unsigned firstLineColumnOffset;
+ unsigned characterOffset;
+ unsigned bytecodeOffset;
String sourceURL;
- String toString(CallFrame* callFrame) const
- {
- StringBuilder traceBuild;
- String functionName = friendlyFunctionName(callFrame);
- String sourceURL = friendlySourceURL();
- traceBuild.append(functionName);
- if (!sourceURL.isEmpty()) {
- if (!functionName.isEmpty())
- traceBuild.append('@');
- traceBuild.append(sourceURL);
- if (line > -1) {
- traceBuild.append(':');
- traceBuild.appendNumber(line);
- }
- }
- return traceBuild.toString().impl();
- }
+ JS_EXPORT_PRIVATE String toString(CallFrame*);
String friendlySourceURL() const
{
String traceLine;
@@ -137,16 +126,16 @@ namespace JSC {
}
return traceLine.isNull() ? emptyString() : traceLine;
}
- unsigned friendlyLineNumber() const
- {
- return line > -1 ? line : 0;
- }
+ JS_EXPORT_PRIVATE void computeLineAndColumn(unsigned& line, unsigned& column);
+
+ private:
+ void expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column);
};
class TopCallFrameSetter {
public:
- TopCallFrameSetter(JSGlobalData& global, CallFrame* callFrame)
- : globalData(global)
+ TopCallFrameSetter(VM& global, CallFrame* callFrame)
+ : vm(global)
, oldCallFrame(global.topCallFrame)
{
global.topCallFrame = callFrame;
@@ -154,16 +143,16 @@ namespace JSC {
~TopCallFrameSetter()
{
- globalData.topCallFrame = oldCallFrame;
+ vm.topCallFrame = oldCallFrame;
}
private:
- JSGlobalData& globalData;
+ VM& vm;
CallFrame* oldCallFrame;
};
class NativeCallFrameTracer {
public:
- ALWAYS_INLINE NativeCallFrameTracer(JSGlobalData* global, CallFrame* callFrame)
+ ALWAYS_INLINE NativeCallFrameTracer(VM* global, CallFrame* callFrame)
{
ASSERT(global);
ASSERT(callFrame);
@@ -186,7 +175,7 @@ namespace JSC {
Interpreter& m_interpreter;
};
- Interpreter(JSGlobalData &);
+ Interpreter(VM &);
~Interpreter();
void initialize(bool canUseJIT);
@@ -229,11 +218,13 @@ namespace JSC {
SamplingTool* sampler() { return m_sampler.get(); }
+ bool isInErrorHandlingMode() { return m_errorHandlingModeReentry; }
+
NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column);
static const String getTraceLine(CallFrame*, StackFrameCodeType, const String&, int);
- JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, Vector<StackFrame>& results);
- static void addStackTraceIfNecessary(CallFrame*, JSObject* error);
+ JS_EXPORT_PRIVATE static void getStackTrace(VM*, Vector<StackFrame>& results, size_t maxStackSize = std::numeric_limits<size_t>::max());
+ static void addStackTraceIfNecessary(CallFrame*, JSValue error);
void dumpSampleData(ExecState* exec);
void startSampling();
@@ -242,16 +233,6 @@ namespace JSC {
JS_EXPORT_PRIVATE void dumpCallFrame(CallFrame*);
private:
- class StackPolicy {
- public:
- StackPolicy(Interpreter&, const StackBounds&);
- inline size_t requiredCapacity() { return m_requiredCapacity; }
-
- private:
- Interpreter& m_interpreter;
- size_t m_requiredCapacity;
- };
-
enum ExecutionFlag { Normal, InitializeAndReturn };
CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*);
diff --git a/Source/JavaScriptCore/interpreter/JSStack.cpp b/Source/JavaScriptCore/interpreter/JSStack.cpp
index f5f9e3763..ec2962a92 100644
--- a/Source/JavaScriptCore/interpreter/JSStack.cpp
+++ b/Source/JavaScriptCore/interpreter/JSStack.cpp
@@ -43,9 +43,9 @@ static Mutex& stackStatisticsMutex()
return staticMutex;
}
-JSStack::JSStack(JSGlobalData& globalData, size_t capacity)
+JSStack::JSStack(VM& vm, size_t capacity)
: m_end(0)
- , m_topCallFrame(globalData.topCallFrame)
+ , m_topCallFrame(vm.topCallFrame)
{
ASSERT(capacity && isPageAligned(capacity));
@@ -135,7 +135,7 @@ void JSStack::enableErrorStackReserve()
void JSStack::disableErrorStackReserve()
{
char* useableEnd = reinterpret_cast<char*>(reservationEnd()) - commitSize;
- m_useableEnd = reinterpret_cast<Register*>(useableEnd);
+ m_useableEnd = reinterpret_cast_ptr<Register*>(useableEnd);
// By the time we get here, we are guaranteed to be destructing the last
// Interpreter::ErrorHandlingMode that enabled this reserve in the first
diff --git a/Source/JavaScriptCore/interpreter/JSStack.h b/Source/JavaScriptCore/interpreter/JSStack.h
index 3beb59ebf..fe4012d83 100644
--- a/Source/JavaScriptCore/interpreter/JSStack.h
+++ b/Source/JavaScriptCore/interpreter/JSStack.h
@@ -45,7 +45,7 @@ namespace JSC {
class DFGCodeBlocks;
class ExecState;
class JITStubRoutineSet;
- class JSGlobalData;
+ class VM;
class LLIntOffsetsExtractor;
class JSStack {
@@ -67,7 +67,7 @@ namespace JSC {
// Allow 8k of excess registers before we start trying to reap the stack
static const ptrdiff_t maxExcessCapacity = 8 * 1024;
- JSStack(JSGlobalData&, size_t capacity = defaultCapacity);
+ JSStack(VM&, size_t capacity = defaultCapacity);
~JSStack();
void gatherConservativeRoots(ConservativeRoots&);
@@ -113,7 +113,7 @@ namespace JSC {
{
char* base = static_cast<char*>(m_reservation.base());
char* reservationEnd = base + m_reservation.size();
- return reinterpret_cast<Register*>(reservationEnd);
+ return reinterpret_cast_ptr<Register*>(reservationEnd);
}
#if ENABLE(DEBUG_JSSTACK)
diff --git a/Source/JavaScriptCore/interpreter/JSStackInlines.h b/Source/JavaScriptCore/interpreter/JSStackInlines.h
index 25b7dcf5a..d316b5992 100644
--- a/Source/JavaScriptCore/interpreter/JSStackInlines.h
+++ b/Source/JavaScriptCore/interpreter/JSStackInlines.h
@@ -29,7 +29,6 @@
#include "CallFrame.h"
#include "CodeBlock.h"
#include "JSStack.h"
-#include <wtf/UnusedParam.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/interpreter/Register.h b/Source/JavaScriptCore/interpreter/Register.h
index f056a1c8f..bc2335689 100644
--- a/Source/JavaScriptCore/interpreter/Register.h
+++ b/Source/JavaScriptCore/interpreter/Register.h
@@ -29,7 +29,7 @@
#ifndef Register_h
#define Register_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include <wtf/Assertions.h>
#include <wtf/VectorTraits.h>
diff --git a/Source/JavaScriptCore/interpreter/VMInspector.h b/Source/JavaScriptCore/interpreter/VMInspector.h
index 81ca26c6f..6623068dc 100644
--- a/Source/JavaScriptCore/interpreter/VMInspector.h
+++ b/Source/JavaScriptCore/interpreter/VMInspector.h
@@ -29,7 +29,7 @@
#define ENABLE_VMINSPECTOR 0
#include "CallFrame.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include <stdarg.h>
#include <stdio.h>
#include <wtf/text/WTFString.h>
diff --git a/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp b/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp
index 73704aa03..1588f7fea 100644
--- a/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp
+++ b/Source/JavaScriptCore/jit/ClosureCallStubRoutine.cpp
@@ -30,18 +30,19 @@
#include "Executable.h"
#include "Heap.h"
-#include "JSGlobalData.h"
+#include "VM.h"
+#include "Operations.h"
#include "SlotVisitor.h"
#include "Structure.h"
namespace JSC {
ClosureCallStubRoutine::ClosureCallStubRoutine(
- const MacroAssemblerCodeRef& code, JSGlobalData& globalData, const JSCell* owner,
+ const MacroAssemblerCodeRef& code, VM& vm, const JSCell* owner,
Structure* structure, ExecutableBase* executable, const CodeOrigin& codeOrigin)
- : GCAwareJITStubRoutine(code, globalData, true)
- , m_structure(globalData, owner, structure)
- , m_executable(globalData, owner, executable)
+ : GCAwareJITStubRoutine(code, vm, true)
+ , m_structure(vm, owner, structure)
+ , m_executable(vm, owner, executable)
, m_codeOrigin(codeOrigin)
{
}
diff --git a/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h b/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h
index 3fd020691..d951075e2 100644
--- a/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h
+++ b/Source/JavaScriptCore/jit/ClosureCallStubRoutine.h
@@ -38,7 +38,7 @@ namespace JSC {
class ClosureCallStubRoutine : public GCAwareJITStubRoutine {
public:
ClosureCallStubRoutine(
- const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner,
+ const MacroAssemblerCodeRef&, VM&, const JSCell* owner,
Structure*, ExecutableBase*, const CodeOrigin&);
virtual ~ClosureCallStubRoutine();
diff --git a/Source/JavaScriptCore/jit/CompactJITCodeMap.h b/Source/JavaScriptCore/jit/CompactJITCodeMap.h
index 5b92a8961..45ab175ec 100644
--- a/Source/JavaScriptCore/jit/CompactJITCodeMap.h
+++ b/Source/JavaScriptCore/jit/CompactJITCodeMap.h
@@ -34,7 +34,6 @@
#include <wtf/FastMalloc.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
-#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
index e9bb66ce7..5ac6cc412 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -114,8 +114,7 @@ protected:
#endif
PageReservation reservation = PageReservation::reserve(numPages * pageSize(), OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
- if (!reservation)
- CRASH();
+ RELEASE_ASSERT(reservation);
reservations.append(reservation);
@@ -168,7 +167,7 @@ void ExecutableAllocator::initializeAllocator()
}
#endif
-ExecutableAllocator::ExecutableAllocator(JSGlobalData&)
+ExecutableAllocator::ExecutableAllocator(VM&)
#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
: m_allocator(adoptPtr(new DemandExecutableAllocator()))
#endif
@@ -213,11 +212,10 @@ double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
}
-PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
+PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
{
RefPtr<ExecutableMemoryHandle> result = allocator()->allocate(sizeInBytes, ownerUID);
- if (!result && effort == JITCompilationMustSucceed)
- CRASH();
+ RELEASE_ASSERT(result || effort != JITCompilationMustSucceed);
return result.release();
}
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h
index 85779e6a8..fe63ddf7a 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h
@@ -34,7 +34,6 @@
#include <wtf/PageAllocation.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
#if OS(IOS)
@@ -74,15 +73,14 @@ extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLeng
namespace JSC {
-class JSGlobalData;
-void releaseExecutableMemory(JSGlobalData&);
+class VM;
+void releaseExecutableMemory(VM&);
static const unsigned jitAllocationGranule = 32;
inline size_t roundUpAllocationSize(size_t request, size_t granularity)
{
- if ((std::numeric_limits<size_t>::max() - granularity) <= request)
- CRASH(); // Allocation is too large
+ RELEASE_ASSERT((std::numeric_limits<size_t>::max() - granularity) > request);
// Round up to next page boundary
size_t size = request + (granularity - 1);
@@ -119,7 +117,7 @@ class ExecutableAllocator {
enum ProtectionSetting { Writable, Executable };
public:
- ExecutableAllocator(JSGlobalData&);
+ ExecutableAllocator(VM&);
~ExecutableAllocator();
static void initializeAllocator();
@@ -136,7 +134,7 @@ public:
static void dumpProfile() { }
#endif
- PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
+ PassRefPtr<ExecutableMemoryHandle> allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
static void makeWritable(void* start, size_t size)
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index 7ee3e0497..7823cd2d2 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -36,10 +36,19 @@
#include <wtf/PageReservation.h>
#include <wtf/VMTags.h>
+#if OS(DARWIN)
+#include <sys/mman.h>
+#endif
+
#if OS(LINUX)
#include <stdio.h>
#endif
+#if !PLATFORM(IOS) && PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+// MADV_FREE_REUSABLE does not work for JIT memory on older OSes so use MADV_FREE in that case.
+#define WTF_USE_MADV_FREE_FOR_JIT_MEMORY 1
+#endif
+
using namespace WTF;
namespace JSC {
@@ -54,8 +63,7 @@ public:
{
m_reservation = PageReservation::reserveWithGuardPages(fixedExecutableMemoryPoolSize, OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
#if !ENABLE(LLINT)
- if (!m_reservation)
- CRASH();
+ RELEASE_ASSERT(m_reservation);
#endif
if (m_reservation) {
ASSERT(m_reservation.size() == fixedExecutableMemoryPoolSize);
@@ -64,6 +72,8 @@ public:
startOfFixedExecutableMemoryPool = reinterpret_cast<uintptr_t>(m_reservation.base());
}
}
+
+ virtual ~FixedVMPoolExecutableAllocator();
protected:
virtual void* allocateNewSpace(size_t&)
@@ -74,7 +84,7 @@ protected:
virtual void notifyNeedPage(void* page)
{
-#if OS(DARWIN)
+#if USE(MADV_FREE_FOR_JIT_MEMORY)
UNUSED_PARAM(page);
#else
m_reservation.commit(page, pageSize());
@@ -83,14 +93,14 @@ protected:
virtual void notifyPageIsFree(void* page)
{
-#if OS(DARWIN)
+#if USE(MADV_FREE_FOR_JIT_MEMORY)
for (;;) {
int result = madvise(page, pageSize(), MADV_FREE);
if (!result)
return;
ASSERT(result == -1);
if (errno != EAGAIN) {
- ASSERT_NOT_REACHED(); // In debug mode, this should be a hard failure.
+ RELEASE_ASSERT_NOT_REACHED(); // In debug mode, this should be a hard failure.
break; // In release mode, we should just ignore the error - not returning memory to the OS is better than crashing, especially since we _will_ be able to reuse the memory internally anyway.
}
}
@@ -112,7 +122,7 @@ void ExecutableAllocator::initializeAllocator()
CodeProfiling::notifyAllocator(allocator);
}
-ExecutableAllocator::ExecutableAllocator(JSGlobalData&)
+ExecutableAllocator::ExecutableAllocator(VM&)
{
ASSERT(allocator);
}
@@ -121,6 +131,11 @@ ExecutableAllocator::~ExecutableAllocator()
{
}
+FixedVMPoolExecutableAllocator::~FixedVMPoolExecutableAllocator()
+{
+ m_reservation.deallocate();
+}
+
bool ExecutableAllocator::isValid() const
{
return !!allocator->bytesReserved();
@@ -148,16 +163,15 @@ double ExecutableAllocator::memoryPressureMultiplier(size_t addedMemoryUsage)
return result;
}
-PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(JSGlobalData& globalData, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
+PassRefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(VM& vm, size_t sizeInBytes, void* ownerUID, JITCompilationEffort effort)
{
RefPtr<ExecutableMemoryHandle> result = allocator->allocate(sizeInBytes, ownerUID);
if (!result) {
if (effort == JITCompilationCanFail)
return result;
- releaseExecutableMemory(globalData);
+ releaseExecutableMemory(vm);
result = allocator->allocate(sizeInBytes, ownerUID);
- if (!result)
- CRASH();
+ RELEASE_ASSERT(result);
}
return result.release();
}
diff --git a/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp b/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp
index 521e49751..f681dd847 100644
--- a/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp
+++ b/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp
@@ -29,20 +29,21 @@
#if ENABLE(JIT)
#include "Heap.h"
-#include "JSGlobalData.h"
+#include "VM.h"
+#include "Operations.h"
#include "SlotVisitor.h"
#include "Structure.h"
namespace JSC {
GCAwareJITStubRoutine::GCAwareJITStubRoutine(
- const MacroAssemblerCodeRef& code, JSGlobalData& globalData, bool isClosureCall)
+ const MacroAssemblerCodeRef& code, VM& vm, bool isClosureCall)
: JITStubRoutine(code)
, m_mayBeExecuting(false)
, m_isJettisoned(false)
, m_isClosureCall(isClosureCall)
{
- globalData.heap.m_jitStubRoutines.add(this);
+ vm.heap.m_jitStubRoutines.add(this);
}
GCAwareJITStubRoutine::~GCAwareJITStubRoutine() { }
@@ -59,7 +60,7 @@ void GCAwareJITStubRoutine::observeZeroRefCount()
return;
}
- ASSERT(!m_refCount);
+ RELEASE_ASSERT(!m_refCount);
m_isJettisoned = true;
}
@@ -78,10 +79,10 @@ void GCAwareJITStubRoutine::markRequiredObjectsInternal(SlotVisitor&)
}
MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject(
- const MacroAssemblerCodeRef& code, JSGlobalData& globalData, const JSCell* owner,
+ const MacroAssemblerCodeRef& code, VM& vm, const JSCell* owner,
JSCell* object)
- : GCAwareJITStubRoutine(code, globalData)
- , m_object(globalData, owner, object)
+ : GCAwareJITStubRoutine(code, vm)
+ , m_object(vm, owner, object)
{
}
@@ -96,7 +97,7 @@ void MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal(Slot
PassRefPtr<JITStubRoutine> createJITStubRoutine(
const MacroAssemblerCodeRef& code,
- JSGlobalData& globalData,
+ VM& vm,
const JSCell*,
bool makesCalls)
{
@@ -104,12 +105,12 @@ PassRefPtr<JITStubRoutine> createJITStubRoutine(
return adoptRef(new JITStubRoutine(code));
return static_pointer_cast<JITStubRoutine>(
- adoptRef(new GCAwareJITStubRoutine(code, globalData)));
+ adoptRef(new GCAwareJITStubRoutine(code, vm)));
}
PassRefPtr<JITStubRoutine> createJITStubRoutine(
const MacroAssemblerCodeRef& code,
- JSGlobalData& globalData,
+ VM& vm,
const JSCell* owner,
bool makesCalls,
JSCell* object)
@@ -118,7 +119,7 @@ PassRefPtr<JITStubRoutine> createJITStubRoutine(
return adoptRef(new JITStubRoutine(code));
return static_pointer_cast<JITStubRoutine>(
- adoptRef(new MarkingGCAwareJITStubRoutineWithOneObject(code, globalData, owner, object)));
+ adoptRef(new MarkingGCAwareJITStubRoutineWithOneObject(code, vm, owner, object)));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h b/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h
index e5ce281e8..f0b282cf1 100644
--- a/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h
+++ b/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h
@@ -54,7 +54,7 @@ class JITStubRoutineSet;
// list which does not get reclaimed all at once).
class GCAwareJITStubRoutine : public JITStubRoutine {
public:
- GCAwareJITStubRoutine(const MacroAssemblerCodeRef&, JSGlobalData&, bool isClosureCall = false);
+ GCAwareJITStubRoutine(const MacroAssemblerCodeRef&, VM&, bool isClosureCall = false);
virtual ~GCAwareJITStubRoutine();
void markRequiredObjects(SlotVisitor& visitor)
@@ -84,7 +84,7 @@ private:
class MarkingGCAwareJITStubRoutineWithOneObject : public GCAwareJITStubRoutine {
public:
MarkingGCAwareJITStubRoutineWithOneObject(
- const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner, JSCell*);
+ const MacroAssemblerCodeRef&, VM&, const JSCell* owner, JSCell*);
virtual ~MarkingGCAwareJITStubRoutineWithOneObject();
protected:
@@ -102,7 +102,7 @@ private:
//
// PassRefPtr<JITStubRoutine> createJITStubRoutine(
// const MacroAssemblerCodeRef& code,
-// JSGlobalData& globalData,
+// VM& vm,
// const JSCell* owner,
// bool makesCalls,
// ...);
@@ -114,9 +114,9 @@ private:
// way.
PassRefPtr<JITStubRoutine> createJITStubRoutine(
- const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner, bool makesCalls);
+ const MacroAssemblerCodeRef&, VM&, const JSCell* owner, bool makesCalls);
PassRefPtr<JITStubRoutine> createJITStubRoutine(
- const MacroAssemblerCodeRef&, JSGlobalData&, const JSCell* owner, bool makesCalls,
+ const MacroAssemblerCodeRef&, VM&, const JSCell* owner, bool makesCalls,
JSCell*);
} // namespace JSC
diff --git a/Source/JavaScriptCore/jit/HostCallReturnValue.cpp b/Source/JavaScriptCore/jit/HostCallReturnValue.cpp
index 967c499b9..528fb2bc4 100644
--- a/Source/JavaScriptCore/jit/HostCallReturnValue.cpp
+++ b/Source/JavaScriptCore/jit/HostCallReturnValue.cpp
@@ -27,9 +27,9 @@
#include "HostCallReturnValue.h"
#include "CallFrame.h"
-#include <wtf/InlineASM.h>
+#include "JSCJSValueInlines.h"
#include "JSObject.h"
-#include "JSValueInlines.h"
+#include <wtf/InlineASM.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/jit/HostCallReturnValue.h b/Source/JavaScriptCore/jit/HostCallReturnValue.h
index 3f61179a3..f4c8bc703 100644
--- a/Source/JavaScriptCore/jit/HostCallReturnValue.h
+++ b/Source/JavaScriptCore/jit/HostCallReturnValue.h
@@ -26,7 +26,7 @@
#ifndef HostCallReturnValue_h
#define HostCallReturnValue_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "MacroAssemblerCodeRef.h"
#include <wtf/Platform.h>
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index cccf33bf6..8e003c782 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -43,6 +43,7 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse
#include "JSArray.h"
#include "JSFunction.h"
#include "LinkBuffer.h"
+#include "Operations.h"
#include "RepatchBuffer.h"
#include "ResultType.h"
#include "SamplingTool.h"
@@ -69,9 +70,9 @@ void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAd
repatchBuffer.relinkCallerToFunction(returnAddress, newCalleeFunction);
}
-JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
- : m_interpreter(globalData->interpreter)
- , m_globalData(globalData)
+JIT::JIT(VM* vm, CodeBlock* codeBlock)
+ : m_interpreter(vm->interpreter)
+ , m_vm(vm)
, m_codeBlock(codeBlock)
, m_labels(codeBlock ? codeBlock->numberOfInstructions() : 0)
, m_bytecodeOffset((unsigned)-1)
@@ -89,11 +90,7 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
, m_lastResultBytecodeRegister(std::numeric_limits<int>::max())
, m_jumpTargetsPosition(0)
#endif
-#if USE(OS_RANDOMNESS)
, m_randomGenerator(cryptographicallyRandomNumber())
-#else
- , m_randomGenerator(static_cast<unsigned>(randomNumber() * 0xFFFFFFF))
-#endif
#if ENABLE(VALUE_PROFILER)
, m_canBeOptimized(false)
, m_shouldEmitProfiling(false)
@@ -102,53 +99,20 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
}
#if ENABLE(DFG_JIT)
-void JIT::emitOptimizationCheck(OptimizationCheckKind kind)
+void JIT::emitEnterOptimizationCheck()
{
if (!canBeOptimized())
return;
-
- Jump skipOptimize = branchAdd32(Signed, TrustedImm32(kind == LoopOptimizationCheck ? Options::executionCounterIncrementForLoop() : Options::executionCounterIncrementForReturn()), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter()));
+
+ Jump skipOptimize = branchAdd32(Signed, TrustedImm32(Options::executionCounterIncrementForReturn()), AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter()));
JITStubCall stubCall(this, cti_optimize);
stubCall.addArgument(TrustedImm32(m_bytecodeOffset));
- if (kind == EnterOptimizationCheck)
- ASSERT(!m_bytecodeOffset);
+ ASSERT(!m_bytecodeOffset);
stubCall.call();
skipOptimize.link(this);
}
#endif
-#if CPU(X86)
-void JIT::emitTimeoutCheck()
-{
- Jump skipTimeout = branchSub32(NonZero, TrustedImm32(1), AbsoluteAddress(&m_globalData->m_timeoutCount));
- JITStubCall stubCall(this, cti_timeout_check);
- stubCall.addArgument(regT1, regT0); // save last result registers.
- stubCall.call(regT0);
- store32(regT0, &m_globalData->m_timeoutCount);
- stubCall.getArgument(0, regT1, regT0); // reload last result registers.
- skipTimeout.link(this);
-}
-#elif USE(JSVALUE32_64)
-void JIT::emitTimeoutCheck()
-{
- Jump skipTimeout = branchSub32(NonZero, TrustedImm32(1), timeoutCheckRegister);
- JITStubCall stubCall(this, cti_timeout_check);
- stubCall.addArgument(regT1, regT0); // save last result registers.
- stubCall.call(timeoutCheckRegister);
- stubCall.getArgument(0, regT1, regT0); // reload last result registers.
- skipTimeout.link(this);
-}
-#else
-void JIT::emitTimeoutCheck()
-{
- Jump skipTimeout = branchSub32(NonZero, TrustedImm32(1), timeoutCheckRegister);
- JITStubCall(this, cti_timeout_check).call(timeoutCheckRegister);
- skipTimeout.link(this);
-
- killLastResultRegister();
-}
-#endif
-
#define NEXT_OPCODE(name) \
m_bytecodeOffset += OPCODE_LENGTH(name); \
break;
@@ -232,8 +196,17 @@ void JIT::privateCompileMainPass()
#if ENABLE(JIT_VERBOSE)
dataLogF("Old JIT emitting code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, (long)debugOffset());
#endif
+
+ OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode);
- switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
+ if (m_compilation && opcodeID != op_call_put_result) {
+ add64(
+ TrustedImm32(1),
+ AbsoluteAddress(m_compilation->executionCounterFor(Profiler::OriginStack(Profiler::Origin(
+ m_compilation->bytecodes(), m_bytecodeOffset)))->address()));
+ }
+
+ switch (opcodeID) {
DEFINE_BINARY_OP(op_del_by_val)
DEFINE_BINARY_OP(op_in)
DEFINE_BINARY_OP(op_less)
@@ -283,7 +256,6 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_jeq_null)
DEFINE_OP(op_jfalse)
DEFINE_OP(op_jmp)
- DEFINE_OP(op_jmp_scopes)
DEFINE_OP(op_jneq_null)
DEFINE_OP(op_jneq_ptr)
DEFINE_OP(op_jless)
@@ -295,14 +267,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_jngreater)
DEFINE_OP(op_jngreatereq)
DEFINE_OP(op_jtrue)
- DEFINE_OP(op_loop)
DEFINE_OP(op_loop_hint)
- DEFINE_OP(op_loop_if_less)
- DEFINE_OP(op_loop_if_lesseq)
- DEFINE_OP(op_loop_if_greater)
- DEFINE_OP(op_loop_if_greatereq)
- DEFINE_OP(op_loop_if_true)
- DEFINE_OP(op_loop_if_false)
DEFINE_OP(op_lshift)
DEFINE_OP(op_mod)
DEFINE_OP(op_mov)
@@ -321,10 +286,8 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_not)
DEFINE_OP(op_nstricteq)
DEFINE_OP(op_pop_scope)
- DEFINE_OP(op_post_dec)
- DEFINE_OP(op_post_inc)
- DEFINE_OP(op_pre_dec)
- DEFINE_OP(op_pre_inc)
+ DEFINE_OP(op_dec)
+ DEFINE_OP(op_inc)
DEFINE_OP(op_profile_did_call)
DEFINE_OP(op_profile_will_call)
DEFINE_OP(op_push_name_scope)
@@ -359,7 +322,6 @@ void JIT::privateCompileMainPass()
case op_put_to_base_variable:
DEFINE_OP(op_put_to_base)
- DEFINE_OP(op_ensure_property_exists)
DEFINE_OP(op_resolve_with_base)
DEFINE_OP(op_resolve_with_this)
DEFINE_OP(op_ret)
@@ -377,9 +339,12 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_tear_off_arguments)
DEFINE_OP(op_throw)
DEFINE_OP(op_throw_static_error)
- DEFINE_OP(op_to_jsnumber)
+ DEFINE_OP(op_to_number)
DEFINE_OP(op_to_primitive)
+ DEFINE_OP(op_get_scoped_var)
+ DEFINE_OP(op_put_scoped_var)
+
case op_get_by_id_chain:
case op_get_by_id_generic:
case op_get_by_id_proto:
@@ -394,11 +359,11 @@ void JIT::privateCompileMainPass()
case op_put_by_id_generic:
case op_put_by_id_replace:
case op_put_by_id_transition:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
- ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
+ RELEASE_ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
#ifndef NDEBUG
// Reset this, in order to guard its use with ASSERTs.
@@ -423,7 +388,7 @@ void JIT::privateCompileSlowCases()
m_globalResolveInfoIndex = 0;
m_callLinkInfoIndex = 0;
-#if !ASSERT_DISABLED && ENABLE(VALUE_PROFILER)
+#if ENABLE(VALUE_PROFILER)
// Use this to assert that slow-path code associates new profiling sites with existing
// ValueProfiles rather than creating new ones. This ensures that for a given instruction
// (say, get_by_id) we get combined statistics for both the fast-path executions of that
@@ -439,9 +404,9 @@ void JIT::privateCompileSlowCases()
#endif
m_bytecodeOffset = iter->to;
-#ifndef NDEBUG
+
unsigned firstTo = m_bytecodeOffset;
-#endif
+
Instruction* currentInstruction = instructionsBegin + m_bytecodeOffset;
#if ENABLE(VALUE_PROFILER)
@@ -489,12 +454,7 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_jngreater)
DEFINE_SLOWCASE_OP(op_jngreatereq)
DEFINE_SLOWCASE_OP(op_jtrue)
- DEFINE_SLOWCASE_OP(op_loop_if_less)
- DEFINE_SLOWCASE_OP(op_loop_if_lesseq)
- DEFINE_SLOWCASE_OP(op_loop_if_greater)
- DEFINE_SLOWCASE_OP(op_loop_if_greatereq)
- DEFINE_SLOWCASE_OP(op_loop_if_true)
- DEFINE_SLOWCASE_OP(op_loop_if_false)
+ DEFINE_SLOWCASE_OP(op_loop_hint)
DEFINE_SLOWCASE_OP(op_lshift)
DEFINE_SLOWCASE_OP(op_mod)
DEFINE_SLOWCASE_OP(op_mul)
@@ -503,10 +463,8 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_new_object)
DEFINE_SLOWCASE_OP(op_not)
DEFINE_SLOWCASE_OP(op_nstricteq)
- DEFINE_SLOWCASE_OP(op_post_dec)
- DEFINE_SLOWCASE_OP(op_post_inc)
- DEFINE_SLOWCASE_OP(op_pre_dec)
- DEFINE_SLOWCASE_OP(op_pre_inc)
+ DEFINE_SLOWCASE_OP(op_dec)
+ DEFINE_SLOWCASE_OP(op_inc)
case op_put_by_id_out_of_line:
case op_put_by_id_transition_direct:
case op_put_by_id_transition_normal:
@@ -519,7 +477,7 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_urshift)
DEFINE_SLOWCASE_OP(op_stricteq)
DEFINE_SLOWCASE_OP(op_sub)
- DEFINE_SLOWCASE_OP(op_to_jsnumber)
+ DEFINE_SLOWCASE_OP(op_to_number)
DEFINE_SLOWCASE_OP(op_to_primitive)
case op_resolve_global_property:
@@ -541,11 +499,11 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_put_to_base)
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
- ASSERT_WITH_MESSAGE(iter == m_slowCases.end() || firstTo != iter->to,"Not enough jumps linked in slow case codegen.");
- ASSERT_WITH_MESSAGE(firstTo == (iter - 1)->to, "Too many jumps linked in slow case codegen.");
+ RELEASE_ASSERT_WITH_MESSAGE(iter == m_slowCases.end() || firstTo != iter->to, "Not enough jumps linked in slow case codegen.");
+ RELEASE_ASSERT_WITH_MESSAGE(firstTo == (iter - 1)->to, "Too many jumps linked in slow case codegen.");
#if ENABLE(VALUE_PROFILER)
if (shouldEmitProfiling())
@@ -555,10 +513,10 @@ void JIT::privateCompileSlowCases()
emitJumpSlowToHot(jump(), 0);
}
- ASSERT(m_propertyAccessInstructionIndex == m_propertyAccessCompilationInfo.size());
- ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
+ RELEASE_ASSERT(m_propertyAccessInstructionIndex == m_propertyAccessCompilationInfo.size());
+ RELEASE_ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
#if ENABLE(VALUE_PROFILER)
- ASSERT(numberOfValueProfiles == m_codeBlock->numberOfValueProfiles());
+ RELEASE_ASSERT(numberOfValueProfiles == m_codeBlock->numberOfValueProfiles());
#endif
#ifndef NDEBUG
@@ -617,22 +575,28 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo
m_canBeOptimized = false;
m_shouldEmitProfiling = false;
break;
- case DFG::ShouldProfile:
+ case DFG::MayInline:
m_canBeOptimized = false;
+ m_canBeOptimizedOrInlined = true;
m_shouldEmitProfiling = true;
break;
case DFG::CanCompile:
m_canBeOptimized = true;
+ m_canBeOptimizedOrInlined = true;
m_shouldEmitProfiling = true;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
#endif
- if (Options::showDisassembly())
+ if (Options::showDisassembly() || m_vm->m_perBytecodeProfiler)
m_disassembler = adoptPtr(new JITDisassembler(m_codeBlock));
+ if (m_vm->m_perBytecodeProfiler) {
+ m_compilation = m_vm->m_perBytecodeProfiler->newCompilation(m_codeBlock, Profiler::Baseline);
+ m_compilation->addProfiledBytecodes(*m_vm->m_perBytecodeProfiler, m_codeBlock);
+ }
if (m_disassembler)
m_disassembler->setStartOfCode(label());
@@ -682,16 +646,11 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo
#endif
addPtr(TrustedImm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
- stackCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), regT1);
+ stackCheck = branchPtr(Below, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), regT1);
}
Label functionBody = label();
-#if ENABLE(VALUE_PROFILER)
- if (canBeOptimized())
- add32(TrustedImm32(1), AbsoluteAddress(&m_codeBlock->m_executionEntryCount));
-#endif
-
privateCompileMainPass();
privateCompileLinkPass();
privateCompileSlowCases();
@@ -731,7 +690,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo
if (m_disassembler)
m_disassembler->setEndOfCode(label());
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock, effort);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock, effort);
if (patchBuffer.didFailToAllocate())
return JITCode();
@@ -806,7 +765,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo
}
#if ENABLE(DFG_JIT) || ENABLE(LLINT)
- if (canBeOptimized()
+ if (canBeOptimizedOrInlined()
#if ENABLE(LLINT)
|| true
#endif
@@ -823,12 +782,14 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo
if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck)
*functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
- if (m_disassembler)
+ if (Options::showDisassembly())
m_disassembler->dump(patchBuffer);
+ if (m_compilation)
+ m_disassembler->reportToProfiler(m_compilation.get(), patchBuffer);
CodeRef result = patchBuffer.finalizeCodeWithoutDisassembly();
- m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.add(
+ m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT.add(
static_cast<double>(result.size()) /
static_cast<double>(m_codeBlock->instructions().size()));
@@ -841,13 +802,13 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo
return JITCode(result, JITCode::BaselineJIT);
}
-void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, JSGlobalData* globalData, CodeSpecializationKind kind)
+void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, VM* vm, CodeSpecializationKind kind)
{
RepatchBuffer repatchBuffer(callerCodeBlock);
ASSERT(!callLinkInfo->isLinked());
- callLinkInfo->callee.set(*globalData, callLinkInfo->hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
- callLinkInfo->lastSeenCallee.set(*globalData, callerCodeBlock->ownerExecutable(), callee);
+ callLinkInfo->callee.set(*vm, callLinkInfo->hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
+ callLinkInfo->lastSeenCallee.set(*vm, callerCodeBlock->ownerExecutable(), callee);
repatchBuffer.relink(callLinkInfo->hotPathOther, code);
if (calleeCodeBlock)
@@ -855,12 +816,26 @@ void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* cal
// Patch the slow patch so we do not continue to try to link.
if (kind == CodeForCall) {
- repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
+ ASSERT(callLinkInfo->callType == CallLinkInfo::Call
+ || callLinkInfo->callType == CallLinkInfo::CallVarargs);
+ if (callLinkInfo->callType == CallLinkInfo::Call) {
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(linkClosureCallGenerator).code());
+ return;
+ }
+
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(virtualCallGenerator).code());
return;
}
ASSERT(kind == CodeForConstruct);
- repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct());
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, vm->getCTIStub(virtualConstructGenerator).code());
+}
+
+void JIT::linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo* callLinkInfo)
+{
+ RepatchBuffer repatchBuffer(callerCodeBlock);
+
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, callerCodeBlock->vm()->getCTIStub(virtualCallGenerator).code());
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index bbbc3b1c7..df8a19fd8 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -48,8 +48,10 @@
#include "Interpreter.h"
#include "JITDisassembler.h"
#include "JSInterfaceJIT.h"
+#include "LegacyProfiler.h"
#include "Opcode.h"
-#include "Profiler.h"
+#include "ResultType.h"
+#include "UnusedPointer.h"
#include <bytecode/SamplingTool.h>
namespace JSC {
@@ -61,6 +63,7 @@ namespace JSC {
class Interpreter;
class JSScope;
class JSStack;
+ class MarkedAllocator;
class Register;
class StructureChain;
@@ -292,91 +295,90 @@ namespace JSC {
using MacroAssembler::JumpList;
using MacroAssembler::Label;
- static const int patchGetByIdDefaultStructure = -1;
+ static const uintptr_t patchGetByIdDefaultStructure = unusedPointer;
static const int patchGetByIdDefaultOffset = 0;
// Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
// will compress the displacement, and we may not be able to fit a patched offset.
static const int patchPutByIdDefaultOffset = 256;
public:
- static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, JITCompilationEffort effort, CodePtr* functionEntryArityCheck = 0)
+ static JITCode compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort, CodePtr* functionEntryArityCheck = 0)
{
- return JIT(globalData, codeBlock).privateCompile(functionEntryArityCheck, effort);
+ return JIT(vm, codeBlock).privateCompile(functionEntryArityCheck, effort);
+ }
+
+ static void compileClosureCall(VM* vm, CallLinkInfo* callLinkInfo, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
+ {
+ JIT jit(vm, callerCodeBlock);
+ jit.m_bytecodeOffset = callLinkInfo->codeOrigin.bytecodeIndex;
+ jit.privateCompileClosureCall(callLinkInfo, calleeCodeBlock, expectedStructure, expectedExecutable, codePtr);
}
- static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
+ static void compileGetByIdProto(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, ident, slot, cachedOffset, returnAddress, callFrame);
}
- static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
+ static void compileGetByIdSelfList(VM* vm, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, ident, slot, cachedOffset);
}
- static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
+ static void compileGetByIdProtoList(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, ident, slot, cachedOffset, callFrame);
}
- static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
+ static void compileGetByIdChainList(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, ident, slot, cachedOffset, callFrame);
}
- static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
+ static void compileGetByIdChain(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, ident, slot, cachedOffset, returnAddress, callFrame);
}
- static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
+ static void compilePutByIdTransition(VM* vm, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = stubInfo->bytecodeIndex;
jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct);
}
- static void compileGetByVal(JSGlobalData* globalData, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
+ static void compileGetByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = byValInfo->bytecodeIndex;
jit.privateCompileGetByVal(byValInfo, returnAddress, arrayMode);
}
- static void compilePutByVal(JSGlobalData* globalData, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
+ static void compilePutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
jit.m_bytecodeOffset = byValInfo->bytecodeIndex;
jit.privateCompilePutByVal(byValInfo, returnAddress, arrayMode);
}
- static PassRefPtr<ExecutableMemoryHandle> compileCTIMachineTrampolines(JSGlobalData* globalData, TrampolineStructure *trampolines)
- {
- if (!globalData->canUseJIT())
- return 0;
- JIT jit(globalData, 0);
- return jit.privateCompileCTIMachineTrampolines(globalData, trampolines);
- }
-
- static CodeRef compileCTINativeCall(JSGlobalData* globalData, NativeFunction func)
+ static CodeRef compileCTINativeCall(VM* vm, NativeFunction func)
{
- if (!globalData->canUseJIT()) {
+ if (!vm->canUseJIT()) {
#if ENABLE(LLINT)
return CodeRef::createLLIntCodeRef(llint_native_call_trampoline);
#else
return CodeRef();
#endif
}
- JIT jit(globalData, 0);
- return jit.privateCompileCTINativeCall(globalData, func);
+ JIT jit(vm, 0);
+ return jit.privateCompileCTINativeCall(vm, func);
}
static void resetPatchGetById(RepatchBuffer&, StructureStubInfo*);
@@ -384,26 +386,31 @@ namespace JSC {
static void patchGetByIdSelf(CodeBlock*, StructureStubInfo*, Structure*, PropertyOffset cachedOffset, ReturnAddressPtr);
static void patchPutByIdReplace(CodeBlock*, StructureStubInfo*, Structure*, PropertyOffset cachedOffset, ReturnAddressPtr, bool direct);
- static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
+ static void compilePatchGetArrayLength(VM* vm, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
{
- JIT jit(globalData, codeBlock);
+ JIT jit(vm, codeBlock);
#if ENABLE(DFG_JIT)
// Force profiling to be enabled during stub generation.
jit.m_canBeOptimized = true;
+ jit.m_canBeOptimizedOrInlined = true;
+ jit.m_shouldEmitProfiling = true;
#endif // ENABLE(DFG_JIT)
return jit.privateCompilePatchGetArrayLength(returnAddress);
}
- static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, JSGlobalData*, CodeSpecializationKind);
+ static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, VM*, CodeSpecializationKind);
+ static void linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo*);
private:
- JIT(JSGlobalData*, CodeBlock* = 0);
+ JIT(VM*, CodeBlock* = 0);
void privateCompileMainPass();
void privateCompileLinkPass();
void privateCompileSlowCases();
JITCode privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort);
+ void privateCompileClosureCall(CallLinkInfo*, CodeBlock* calleeCodeBlock, Structure*, ExecutableBase*, MacroAssemblerCodePtr);
+
void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, ReturnAddressPtr, CallFrame*);
void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset);
void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, CallFrame*);
@@ -414,9 +421,8 @@ namespace JSC {
void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode);
- PassRefPtr<ExecutableMemoryHandle> privateCompileCTIMachineTrampolines(JSGlobalData*, TrampolineStructure*);
- Label privateCompileCTINativeCall(JSGlobalData*, bool isConstruct = false);
- CodeRef privateCompileCTINativeCall(JSGlobalData*, NativeFunction);
+ Label privateCompileCTINativeCall(VM*, bool isConstruct = false);
+ CodeRef privateCompileCTINativeCall(VM*, NativeFunction);
void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
static bool isDirectPutById(StructureStubInfo*);
@@ -440,7 +446,6 @@ namespace JSC {
void emitLoadDouble(int index, FPRegisterID value);
void emitLoadInt32ToDouble(int index, FPRegisterID value);
Jump emitJumpIfNotObject(RegisterID structureReg);
- Jump emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType);
Jump addStructureTransitionCheck(JSCell*, Structure*, StructureStubInfo*, RegisterID scratch);
void addStructureTransitionCheck(JSCell*, Structure*, StructureStubInfo*, JumpList& failureCases, RegisterID scratch);
@@ -452,8 +457,8 @@ namespace JSC {
void emitWriteBarrier(RegisterID owner, RegisterID valueTag, RegisterID scratch, RegisterID scratch2, WriteBarrierMode, WriteBarrierUseKind);
void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind);
- template<typename ClassType, MarkedBlock::DestructorType, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);
- template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
+ template<typename StructureType> // StructureType can be RegisterID or ImmPtr.
+ void emitAllocateJSObject(RegisterID allocator, StructureType, RegisterID result, RegisterID scratch);
#if ENABLE(VALUE_PROFILER)
// This assumes that the value to profile is in regT0 and that regT3 is available for
@@ -468,6 +473,7 @@ namespace JSC {
void emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile*);
void emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex);
void emitArrayProfileStoreToHoleSpecialCase(ArrayProfile*);
+ void emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile*);
JITArrayMode chooseArrayMode(ArrayProfile*);
@@ -594,7 +600,6 @@ namespace JSC {
Jump emitJumpIfJSCell(RegisterID);
Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID);
void emitJumpSlowCaseIfJSCell(RegisterID);
- Jump emitJumpIfNotJSCell(RegisterID);
void emitJumpSlowCaseIfNotJSCell(RegisterID);
void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
Jump emitJumpIfImmediateInteger(RegisterID);
@@ -605,7 +610,6 @@ namespace JSC {
void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
void emitFastArithReTagImmediate(RegisterID src, RegisterID dest);
- void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
void emitTagAsBoolImmediate(RegisterID reg);
void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
@@ -674,7 +678,6 @@ namespace JSC {
void emit_op_jeq_null(Instruction*);
void emit_op_jfalse(Instruction*);
void emit_op_jmp(Instruction*);
- void emit_op_jmp_scopes(Instruction*);
void emit_op_jneq_null(Instruction*);
void emit_op_jneq_ptr(Instruction*);
void emit_op_jless(Instruction*);
@@ -686,14 +689,7 @@ namespace JSC {
void emit_op_jngreater(Instruction*);
void emit_op_jngreatereq(Instruction*);
void emit_op_jtrue(Instruction*);
- void emit_op_loop(Instruction*);
void emit_op_loop_hint(Instruction*);
- void emit_op_loop_if_less(Instruction*);
- void emit_op_loop_if_lesseq(Instruction*);
- void emit_op_loop_if_greater(Instruction*);
- void emit_op_loop_if_greatereq(Instruction*);
- void emit_op_loop_if_true(Instruction*);
- void emit_op_loop_if_false(Instruction*);
void emit_op_lshift(Instruction*);
void emit_op_mod(Instruction*);
void emit_op_mov(Instruction*);
@@ -713,10 +709,8 @@ namespace JSC {
void emit_op_not(Instruction*);
void emit_op_nstricteq(Instruction*);
void emit_op_pop_scope(Instruction*);
- void emit_op_post_dec(Instruction*);
- void emit_op_post_inc(Instruction*);
- void emit_op_pre_dec(Instruction*);
- void emit_op_pre_inc(Instruction*);
+ void emit_op_dec(Instruction*);
+ void emit_op_inc(Instruction*);
void emit_op_profile_did_call(Instruction*);
void emit_op_profile_will_call(Instruction*);
void emit_op_push_name_scope(Instruction*);
@@ -731,7 +725,6 @@ namespace JSC {
void emitSlow_link_resolve_operations(ResolveOperations*, Vector<SlowCaseEntry>::iterator&);
void emit_op_resolve(Instruction*);
void emit_op_resolve_base(Instruction*);
- void emit_op_ensure_property_exists(Instruction*);
void emit_op_resolve_with_base(Instruction*);
void emit_op_resolve_with_this(Instruction*);
void emit_op_put_to_base(Instruction*);
@@ -748,10 +741,12 @@ namespace JSC {
void emit_op_tear_off_arguments(Instruction*);
void emit_op_throw(Instruction*);
void emit_op_throw_static_error(Instruction*);
- void emit_op_to_jsnumber(Instruction*);
+ void emit_op_to_number(Instruction*);
void emit_op_to_primitive(Instruction*);
void emit_op_unexpected_load(Instruction*);
void emit_op_urshift(Instruction*);
+ void emit_op_get_scoped_var(Instruction*);
+ void emit_op_put_scoped_var(Instruction*);
void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -782,12 +777,7 @@ namespace JSC {
void emitSlow_op_jngreater(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jngreatereq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_greater(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_greatereq(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_loop_if_false(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_loop_hint(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -796,17 +786,15 @@ namespace JSC {
void emitSlow_op_new_object(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_init_global_const_check(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_to_number(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -821,10 +809,7 @@ namespace JSC {
void emitInitRegister(unsigned dst);
- void emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
- void emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
void emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
- void emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry);
void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
#if USE(JSVALUE64)
@@ -855,27 +840,20 @@ namespace JSC {
Jump checkStructure(RegisterID reg, Structure* structure);
- void restoreArgumentReference();
void restoreArgumentReferenceForTrampoline();
void updateTopCallFrame();
Call emitNakedCall(CodePtr function = CodePtr());
- void preserveReturnAddressAfterCall(RegisterID);
- void restoreReturnAddressBeforeReturn(RegisterID);
- void restoreReturnAddressBeforeReturn(Address);
-
// Loads the character value of a single character string into dst.
void emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures);
- enum OptimizationCheckKind { LoopOptimizationCheck, EnterOptimizationCheck };
#if ENABLE(DFG_JIT)
- void emitOptimizationCheck(OptimizationCheckKind);
+ void emitEnterOptimizationCheck();
#else
- void emitOptimizationCheck(OptimizationCheckKind) { }
+ void emitEnterOptimizationCheck() { }
#endif
-
- void emitTimeoutCheck();
+
#ifndef NDEBUG
void printBytecodeOperandTypes(unsigned src1, unsigned src2);
#endif
@@ -901,16 +879,18 @@ namespace JSC {
#if ENABLE(DFG_JIT)
bool canBeOptimized() { return m_canBeOptimized; }
+ bool canBeOptimizedOrInlined() { return m_canBeOptimizedOrInlined; }
bool shouldEmitProfiling() { return m_shouldEmitProfiling; }
#else
bool canBeOptimized() { return false; }
+ bool canBeOptimizedOrInlined() { return false; }
// Enables use of value profiler with tiered compilation turned off,
// in which case all code gets profiled.
- bool shouldEmitProfiling() { return true; }
+ bool shouldEmitProfiling() { return false; }
#endif
Interpreter* m_interpreter;
- JSGlobalData* m_globalData;
+ VM* m_vm;
CodeBlock* m_codeBlock;
Vector<CallRecord> m_calls;
@@ -947,92 +927,17 @@ namespace JSC {
#endif
#endif
OwnPtr<JITDisassembler> m_disassembler;
+ RefPtr<Profiler::Compilation> m_compilation;
WeakRandom m_randomGenerator;
- static CodeRef stringGetByValStubGenerator(JSGlobalData*);
+ static CodeRef stringGetByValStubGenerator(VM*);
#if ENABLE(VALUE_PROFILER)
bool m_canBeOptimized;
+ bool m_canBeOptimizedOrInlined;
bool m_shouldEmitProfiling;
#endif
} JIT_CLASS_ALIGNMENT;
- inline void JIT::emit_op_loop(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jmp(currentInstruction);
- }
-
- inline void JIT::emit_op_loop_hint(Instruction*)
- {
- emitOptimizationCheck(LoopOptimizationCheck);
- }
-
- inline void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jtrue(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jtrue(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_false(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jfalse(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jfalse(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jless(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jless(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jlesseq(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jlesseq(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_greater(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jgreater(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_greater(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jgreater(currentInstruction, iter);
- }
-
- inline void JIT::emit_op_loop_if_greatereq(Instruction* currentInstruction)
- {
- emitTimeoutCheck();
- emit_op_jgreatereq(currentInstruction);
- }
-
- inline void JIT::emitSlow_op_loop_if_greatereq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
- {
- emitSlow_op_jgreatereq(currentInstruction, iter);
- }
-
} // namespace JSC
#endif // ENABLE(JIT)
diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp
index bcb3dd74a..713d05e3b 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp
@@ -35,6 +35,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "Operations.h"
#include "ResultType.h"
#include "SamplingTool.h"
@@ -628,61 +629,7 @@ void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEnt
}
}
-void JIT::emit_op_post_inc(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitGetVirtualRegister(srcDst, regT0);
- move(regT0, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT1));
- emitFastArithIntToImmNoCheck(regT1, regT1);
- emitPutVirtualRegister(srcDst, regT1);
- emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_post_inc);
- stubCall.addArgument(regT0);
- stubCall.addArgument(Imm32(srcDst));
- stubCall.call(result);
-}
-
-void JIT::emit_op_post_dec(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitGetVirtualRegister(srcDst, regT0);
- move(regT0, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT1));
- emitFastArithIntToImmNoCheck(regT1, regT1);
- emitPutVirtualRegister(srcDst, regT1);
- emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_post_dec);
- stubCall.addArgument(regT0);
- stubCall.addArgument(Imm32(srcDst));
- stubCall.call(result);
-}
-
-void JIT::emit_op_pre_inc(Instruction* currentInstruction)
+void JIT::emit_op_inc(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
@@ -693,7 +640,7 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction)
emitPutVirtualRegister(srcDst);
}
-void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
@@ -701,12 +648,12 @@ void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
emitGetVirtualRegister(srcDst, regT0);
notImm.link(this);
- JITStubCall stubCall(this, cti_op_pre_inc);
+ JITStubCall stubCall(this, cti_op_inc);
stubCall.addArgument(regT0);
stubCall.call(srcDst);
}
-void JIT::emit_op_pre_dec(Instruction* currentInstruction)
+void JIT::emit_op_dec(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
@@ -717,7 +664,7 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction)
emitPutVirtualRegister(srcDst);
}
-void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
@@ -725,7 +672,7 @@ void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
emitGetVirtualRegister(srcDst, regT0);
notImm.link(this);
- JITStubCall stubCall(this, cti_op_pre_dec);
+ JITStubCall stubCall(this, cti_op_dec);
stubCall.addArgument(regT0);
stubCall.call(srcDst);
}
@@ -794,7 +741,7 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
#endif // CPU(X86) || CPU(X86_64)
diff --git a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
index 960d06091..c1caf61f5 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
@@ -36,6 +36,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "Operations.h"
#include "ResultType.h"
#include "SamplingTool.h"
@@ -448,79 +449,7 @@ void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.call(dst);
}
-// PostInc (i++)
-
-void JIT::emit_op_post_inc(Instruction* currentInstruction)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-
- if (dst == srcDst) // x = x++ is a noop for ints.
- return;
-
- move(regT0, regT2);
- addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT2));
- emitStoreInt32(srcDst, regT2, true);
-
- emitStoreAndMapInt32(dst, regT1, regT0, false, OPCODE_LENGTH(op_post_inc));
-}
-
-void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter); // int32 check
- if (dst != srcDst)
- linkSlowCase(iter); // overflow check
-
- JITStubCall stubCall(this, cti_op_post_inc);
- stubCall.addArgument(srcDst);
- stubCall.addArgument(TrustedImm32(srcDst));
- stubCall.call(dst);
-}
-
-// PostDec (i--)
-
-void JIT::emit_op_post_dec(Instruction* currentInstruction)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- emitLoad(srcDst, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-
- if (dst == srcDst) // x = x-- is a noop for ints.
- return;
-
- move(regT0, regT2);
- addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT2));
- emitStoreInt32(srcDst, regT2, true);
-
- emitStoreAndMapInt32(dst, regT1, regT0, false, OPCODE_LENGTH(op_post_dec));
-}
-
-void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned dst = currentInstruction[1].u.operand;
- unsigned srcDst = currentInstruction[2].u.operand;
-
- linkSlowCase(iter); // int32 check
- if (dst != srcDst)
- linkSlowCase(iter); // overflow check
-
- JITStubCall stubCall(this, cti_op_post_dec);
- stubCall.addArgument(srcDst);
- stubCall.addArgument(TrustedImm32(srcDst));
- stubCall.call(dst);
-}
-
-// PreInc (++i)
-
-void JIT::emit_op_pre_inc(Instruction* currentInstruction)
+void JIT::emit_op_inc(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
@@ -528,24 +457,22 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction)
addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addSlowCase(branchAdd32(Overflow, TrustedImm32(1), regT0));
- emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_pre_inc));
+ emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_inc));
}
-void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
linkSlowCase(iter); // int32 check
linkSlowCase(iter); // overflow check
- JITStubCall stubCall(this, cti_op_pre_inc);
+ JITStubCall stubCall(this, cti_op_inc);
stubCall.addArgument(srcDst);
stubCall.call(srcDst);
}
-// PreDec (--i)
-
-void JIT::emit_op_pre_dec(Instruction* currentInstruction)
+void JIT::emit_op_dec(Instruction* currentInstruction)
{
unsigned srcDst = currentInstruction[1].u.operand;
@@ -553,17 +480,17 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction)
addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
addSlowCase(branchSub32(Overflow, TrustedImm32(1), regT0));
- emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_pre_dec));
+ emitStoreAndMapInt32(srcDst, regT1, regT0, true, OPCODE_LENGTH(op_dec));
}
-void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned srcDst = currentInstruction[1].u.operand;
linkSlowCase(iter); // int32 check
linkSlowCase(iter); // overflow check
- JITStubCall stubCall(this, cti_op_pre_dec);
+ JITStubCall stubCall(this, cti_op_dec);
stubCall.addArgument(srcDst);
stubCall.call(srcDst);
}
@@ -907,7 +834,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
addJump(branchDouble(DoubleGreaterThanOrUnordered, fpRegT0, fpRegT2), dst);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
if (!notInt32Op2.empty())
@@ -1011,7 +938,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
addJump(branchDouble(DoubleGreaterThanOrUnordered, fpRegT1, fpRegT0), dst);
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -1252,7 +1179,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
UNUSED_PARAM(iter);
// We would have really useful assertions here if it wasn't for the compiler's
// insistence on attribute noreturn.
- // ASSERT_NOT_REACHED();
+ // RELEASE_ASSERT_NOT_REACHED();
#endif
}
diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp
index 006c5b741..5520a4d34 100644
--- a/Source/JavaScriptCore/jit/JITCall.cpp
+++ b/Source/JavaScriptCore/jit/JITCall.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,8 +36,12 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "Operations.h"
+#include "RepatchBuffer.h"
#include "ResultType.h"
#include "SamplingTool.h"
+#include "ThunkGenerators.h"
+#include <wtf/StringPrintStream.h>
#ifndef NDEBUG
#include <stdio.h>
@@ -52,7 +56,7 @@ void JIT::emit_op_call_put_result(Instruction* instruction)
int dst = instruction[1].u.operand;
emitValueProfilingSite();
emitPutVirtualRegister(dst);
- if (canBeOptimized())
+ if (canBeOptimizedOrInlined())
killLastResultRegister(); // Make lastResultRegister tracking simpler in the DFG.
}
@@ -84,7 +88,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
addPtr(callFrameRegister, regT1);
// regT1: newCallFrame
- slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), regT1));
+ slowCase.append(branchPtr(Below, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), regT1));
// Initialize ArgumentCount.
store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
@@ -135,7 +139,7 @@ void JIT::compileCallEvalSlowCase(Vector<SlowCaseEntry>::iterator& iter)
linkSlowCase(iter);
emitGetFromCallFrameHeader64(JSStack::Callee, regT0);
- emitNakedCall(m_globalData->jitStubs->ctiVirtualCall());
+ emitNakedCall(m_vm->getCTIStub(virtualCallGenerator).code());
sampleCodeBlock(m_codeBlock);
}
@@ -164,7 +168,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
int argCount = instruction[2].u.operand;
int registerOffset = instruction[3].u.operand;
- if (opcodeID == op_call && canBeOptimized()) {
+ if (opcodeID == op_call && shouldEmitProfiling()) {
emitGetVirtualRegister(registerOffset + CallFrame::argumentOffsetIncludingThis(0), regT0);
Jump done = emitJumpIfNotJSCell(regT0);
loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
@@ -216,11 +220,57 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction*, Vector<SlowCase
linkSlowCase(iter);
- m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_globalData->jitStubs->ctiVirtualConstructLink() : m_globalData->jitStubs->ctiVirtualCallLink());
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_vm->getCTIStub(linkConstructGenerator).code() : m_vm->getCTIStub(linkCallGenerator).code());
sampleCodeBlock(m_codeBlock);
}
+void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
+{
+ JumpList slowCases;
+
+ slowCases.append(branchTestPtr(NonZero, regT0, tagMaskRegister));
+ slowCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(expectedStructure)));
+ slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
+
+ loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
+ emitPutToCallFrameHeader(regT1, JSStack::ScopeChain);
+
+ Call call = nearCall();
+ Jump done = jump();
+
+ slowCases.link(this);
+ move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
+ restoreReturnAddressBeforeReturn(regT2);
+ Jump slow = jump();
+
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
+
+ patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
+ patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
+ patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallGenerator).code()));
+
+ RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
+ FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline closure call stub for %s, return point %p, target %p (%s)",
+ toCString(*m_codeBlock).data(),
+ callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
+ codePtr.executableAddress(),
+ toCString(pointerDump(calleeCodeBlock)).data())),
+ *m_vm, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
+ callLinkInfo->codeOrigin));
+
+ RepatchBuffer repatchBuffer(m_codeBlock);
+
+ repatchBuffer.replaceWithJump(
+ RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
+ CodeLocationLabel(stubRoutine->code().code()));
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallGenerator).code());
+
+ callLinkInfo->stub = stubRoutine.release();
+}
+
} // namespace JSC
#endif // USE(JSVALUE64)
diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp
index ecd5cf126..c8be31206 100644
--- a/Source/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,8 +36,11 @@
#include "JITStubCall.h"
#include "JSArray.h"
#include "JSFunction.h"
+#include "Operations.h"
+#include "RepatchBuffer.h"
#include "ResultType.h"
#include "SamplingTool.h"
+#include <wtf/StringPrintStream.h>
#ifndef NDEBUG
#include <stdio.h>
@@ -159,7 +162,7 @@ void JIT::compileLoadVarargs(Instruction* instruction)
addPtr(callFrameRegister, regT3);
// regT3: newCallFrame
- slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), regT3));
+ slowCase.append(branchPtr(Below, AbsoluteAddress(m_vm->interpreter->stack().addressOfEnd()), regT3));
// Initialize ArgumentCount.
store32(regT2, payloadFor(JSStack::ArgumentCount, regT3));
@@ -212,7 +215,7 @@ void JIT::compileCallEvalSlowCase(Vector<SlowCaseEntry>::iterator& iter)
linkSlowCase(iter);
emitLoad(JSStack::Callee, regT1, regT0);
- emitNakedCall(m_globalData->jitStubs->ctiVirtualCall());
+ emitNakedCall(m_vm->getCTIStub(virtualCallGenerator).code());
sampleCodeBlock(m_codeBlock);
}
@@ -241,7 +244,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
int argCount = instruction[2].u.operand;
int registerOffset = instruction[3].u.operand;
- if (opcodeID == op_call && canBeOptimized()) {
+ if (opcodeID == op_call && shouldEmitProfiling()) {
emitLoad(registerOffset + CallFrame::argumentOffsetIncludingThis(0), regT0, regT1);
Jump done = branch32(NotEqual, regT0, TrustedImm32(JSValue::CellTag));
loadPtr(Address(regT1, JSCell::structureOffset()), regT1);
@@ -297,11 +300,57 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction*, Vector<SlowCase
linkSlowCase(iter);
linkSlowCase(iter);
- m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_globalData->jitStubs->ctiVirtualConstructLink() : m_globalData->jitStubs->ctiVirtualCallLink());
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(opcodeID == op_construct ? m_vm->getCTIStub(linkConstructGenerator).code() : m_vm->getCTIStub(linkCallGenerator).code());
sampleCodeBlock(m_codeBlock);
}
+void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
+{
+ JumpList slowCases;
+
+ slowCases.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
+ slowCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(expectedStructure)));
+ slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
+
+ loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
+ emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
+
+ Call call = nearCall();
+ Jump done = jump();
+
+ slowCases.link(this);
+ move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
+ restoreReturnAddressBeforeReturn(regT2);
+ Jump slow = jump();
+
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
+
+ patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
+ patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
+ patchBuffer.link(slow, CodeLocationLabel(m_vm->getCTIStub(virtualCallGenerator).code()));
+
+ RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
+ FINALIZE_CODE(
+ patchBuffer,
+ ("Baseline closure call stub for %s, return point %p, target %p (%s)",
+ toCString(*m_codeBlock).data(),
+ callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
+ codePtr.executableAddress(),
+ toCString(pointerDump(calleeCodeBlock)).data())),
+ *m_vm, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
+ callLinkInfo->codeOrigin));
+
+ RepatchBuffer repatchBuffer(m_codeBlock);
+
+ repatchBuffer.replaceWithJump(
+ RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
+ CodeLocationLabel(stubRoutine->code().code()));
+ repatchBuffer.relink(callLinkInfo->callReturnLocation, m_vm->getCTIStub(virtualCallGenerator).code());
+
+ callLinkInfo->stub = stubRoutine.release();
+}
+
} // namespace JSC
#endif // USE(JSVALUE32_64)
diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h
index 0929397ee..b7521fb21 100644
--- a/Source/JavaScriptCore/jit/JITCode.h
+++ b/Source/JavaScriptCore/jit/JITCode.h
@@ -28,16 +28,17 @@
#if ENABLE(JIT) || ENABLE(LLINT)
#include "CallFrame.h"
-#include "JSValue.h"
#include "Disassembler.h"
+#include "JITStubs.h"
+#include "JSCJSValue.h"
+#include "LegacyProfiler.h"
#include "MacroAssemblerCodeRef.h"
-#include "Profiler.h"
#endif
namespace JSC {
#if ENABLE(JIT)
- class JSGlobalData;
+ class VM;
class JSStack;
#endif
@@ -129,10 +130,10 @@ namespace JSC {
#if ENABLE(JIT)
// Execute the code!
- inline JSValue execute(JSStack* stack, CallFrame* callFrame, JSGlobalData* globalData)
+ inline JSValue execute(JSStack* stack, CallFrame* callFrame, VM* vm)
{
- JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), stack, callFrame, 0, 0, globalData));
- return globalData->exception ? jsNull() : result;
+ JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), stack, callFrame, 0, 0, vm));
+ return vm->exception ? jsNull() : result;
}
#endif
diff --git a/Source/JavaScriptCore/jit/JITDisassembler.cpp b/Source/JavaScriptCore/jit/JITDisassembler.cpp
index eaef844bf..39953fa34 100644
--- a/Source/JavaScriptCore/jit/JITDisassembler.cpp
+++ b/Source/JavaScriptCore/jit/JITDisassembler.cpp
@@ -31,6 +31,7 @@
#include "CodeBlock.h"
#include "CodeBlockWithJITType.h"
#include "JIT.h"
+#include <wtf/StringPrintStream.h>
namespace JSC {
@@ -47,18 +48,10 @@ JITDisassembler::~JITDisassembler()
void JITDisassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
{
- out.print("Baseline JIT code for ", CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT), ", instruction count = ", m_codeBlock->instructionCount(), "\n");
- out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
+ dumpHeader(out, linkBuffer);
dumpDisassembly(out, linkBuffer, m_startOfCode, m_labelForBytecodeIndexInMainPath[0]);
- MacroAssembler::Label firstSlowLabel;
- for (unsigned i = 0; i < m_labelForBytecodeIndexInSlowPath.size(); ++i) {
- if (m_labelForBytecodeIndexInSlowPath[i].isSet()) {
- firstSlowLabel = m_labelForBytecodeIndexInSlowPath[i];
- break;
- }
- }
- dumpForInstructions(out, linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel.isSet() ? firstSlowLabel : m_endOfSlowPath);
+ dumpForInstructions(out, linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel());
out.print(" (End Of Main Path)\n");
dumpForInstructions(out, linkBuffer, " (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath);
out.print(" (End Of Slow Path)\n");
@@ -71,27 +64,95 @@ void JITDisassembler::dump(LinkBuffer& linkBuffer)
dump(WTF::dataFile(), linkBuffer);
}
-void JITDisassembler::dumpForInstructions(PrintStream& out, LinkBuffer& linkBuffer, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel)
+void JITDisassembler::reportToProfiler(Profiler::Compilation* compilation, LinkBuffer& linkBuffer)
+{
+ StringPrintStream out;
+
+ dumpHeader(out, linkBuffer);
+ compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), out.toCString()));
+ out.reset();
+ dumpDisassembly(out, linkBuffer, m_startOfCode, m_labelForBytecodeIndexInMainPath[0]);
+ compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), out.toCString()));
+
+ reportInstructions(compilation, linkBuffer, " ", m_labelForBytecodeIndexInMainPath, firstSlowLabel());
+ compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), " (End Of Main Path)\n"));
+ reportInstructions(compilation, linkBuffer, " (S) ", m_labelForBytecodeIndexInSlowPath, m_endOfSlowPath);
+ compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), " (End Of Slow Path)\n"));
+ out.reset();
+ dumpDisassembly(out, linkBuffer, m_endOfSlowPath, m_endOfCode);
+ compilation->addDescription(Profiler::CompiledBytecode(Profiler::OriginStack(), out.toCString()));
+}
+
+void JITDisassembler::dumpHeader(PrintStream& out, LinkBuffer& linkBuffer)
+{
+ out.print("Generated Baseline JIT code for ", CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT), ", instruction count = ", m_codeBlock->instructionCount(), "\n");
+ out.print(" Source: ", m_codeBlock->sourceCodeOnOneLine(), "\n");
+ out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
+}
+
+MacroAssembler::Label JITDisassembler::firstSlowLabel()
+{
+ MacroAssembler::Label firstSlowLabel;
+ for (unsigned i = 0; i < m_labelForBytecodeIndexInSlowPath.size(); ++i) {
+ if (m_labelForBytecodeIndexInSlowPath[i].isSet()) {
+ firstSlowLabel = m_labelForBytecodeIndexInSlowPath[i];
+ break;
+ }
+ }
+ return firstSlowLabel.isSet() ? firstSlowLabel : m_endOfSlowPath;
+}
+
+Vector<JITDisassembler::DumpedOp> JITDisassembler::dumpVectorForInstructions(LinkBuffer& linkBuffer, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel)
{
- for (unsigned i = 0 ; i < labels.size();) {
+ StringPrintStream out;
+ Vector<DumpedOp> result;
+
+ for (unsigned i = 0; i < labels.size();) {
if (!labels[i].isSet()) {
i++;
continue;
}
+ out.reset();
+ result.append(DumpedOp());
+ result.last().index = i;
out.print(prefix);
- m_codeBlock->dumpBytecode(i);
+ m_codeBlock->dumpBytecode(out, i);
for (unsigned nextIndex = i + 1; ; nextIndex++) {
if (nextIndex >= labels.size()) {
dumpDisassembly(out, linkBuffer, labels[i], endLabel);
- return;
+ result.last().disassembly = out.toCString();
+ return result;
}
if (labels[nextIndex].isSet()) {
dumpDisassembly(out, linkBuffer, labels[i], labels[nextIndex]);
+ result.last().disassembly = out.toCString();
i = nextIndex;
break;
}
}
}
+
+ return result;
+}
+
+void JITDisassembler::dumpForInstructions(PrintStream& out, LinkBuffer& linkBuffer, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel)
+{
+ Vector<DumpedOp> dumpedOps = dumpVectorForInstructions(linkBuffer, prefix, labels, endLabel);
+
+ for (unsigned i = 0; i < dumpedOps.size(); ++i)
+ out.print(dumpedOps[i].disassembly);
+}
+
+void JITDisassembler::reportInstructions(Profiler::Compilation* compilation, LinkBuffer& linkBuffer, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel)
+{
+ Vector<DumpedOp> dumpedOps = dumpVectorForInstructions(linkBuffer, prefix, labels, endLabel);
+
+ for (unsigned i = 0; i < dumpedOps.size(); ++i) {
+ compilation->addDescription(
+ Profiler::CompiledBytecode(
+ Profiler::OriginStack(Profiler::Origin(compilation->bytecodes(), dumpedOps[i].index)),
+ dumpedOps[i].disassembly));
+ }
}
void JITDisassembler::dumpDisassembly(PrintStream& out, LinkBuffer& linkBuffer, MacroAssembler::Label from, MacroAssembler::Label to)
diff --git a/Source/JavaScriptCore/jit/JITDisassembler.h b/Source/JavaScriptCore/jit/JITDisassembler.h
index ca914748c..7edbb9cf7 100644
--- a/Source/JavaScriptCore/jit/JITDisassembler.h
+++ b/Source/JavaScriptCore/jit/JITDisassembler.h
@@ -32,6 +32,7 @@
#include "LinkBuffer.h"
#include "MacroAssembler.h"
+#include "ProfilerDatabase.h"
#include <wtf/Vector.h>
namespace JSC {
@@ -58,9 +59,21 @@ public:
void dump(LinkBuffer&);
void dump(PrintStream&, LinkBuffer&);
+ void reportToProfiler(Profiler::Compilation*, LinkBuffer&);
private:
+ void dumpHeader(PrintStream&, LinkBuffer&);
+ MacroAssembler::Label firstSlowLabel();
+
+ struct DumpedOp {
+ unsigned index;
+ CString disassembly;
+ };
+ Vector<DumpedOp> dumpVectorForInstructions(LinkBuffer&, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel);
+
void dumpForInstructions(PrintStream&, LinkBuffer&, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel);
+ void reportInstructions(Profiler::Compilation*, LinkBuffer&, const char* prefix, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel);
+
void dumpDisassembly(PrintStream&, LinkBuffer&, MacroAssembler::Label from, MacroAssembler::Label to);
CodeBlock* m_codeBlock;
diff --git a/Source/JavaScriptCore/jit/JITDriver.h b/Source/JavaScriptCore/jit/JITDriver.h
index 645c65b28..a2221fa0f 100644
--- a/Source/JavaScriptCore/jit/JITDriver.h
+++ b/Source/JavaScriptCore/jit/JITDriver.h
@@ -40,12 +40,12 @@ namespace JSC {
template<typename CodeBlockType>
inline bool jitCompileIfAppropriate(ExecState* exec, OwnPtr<CodeBlockType>& codeBlock, JITCode& jitCode, JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
if (jitType == codeBlock->getJITType())
return true;
- if (!globalData.canUseJIT())
+ if (!vm.canUseJIT())
return true;
codeBlock->unlinkIncomingCalls();
@@ -64,7 +64,7 @@ inline bool jitCompileIfAppropriate(ExecState* exec, OwnPtr<CodeBlockType>& code
jitCode = oldJITCode;
return false;
}
- jitCode = JIT::compile(&globalData, codeBlock.get(), effort);
+ jitCode = JIT::compile(&vm, codeBlock.get(), effort);
if (!jitCode) {
jitCode = oldJITCode;
return false;
@@ -77,12 +77,12 @@ inline bool jitCompileIfAppropriate(ExecState* exec, OwnPtr<CodeBlockType>& code
inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
if (jitType == codeBlock->getJITType())
return true;
- if (!globalData.canUseJIT())
+ if (!vm.canUseJIT())
return true;
codeBlock->unlinkIncomingCalls();
@@ -103,7 +103,7 @@ inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCode
jitCodeWithArityCheck = oldJITCodeWithArityCheck;
return false;
}
- jitCode = JIT::compile(&globalData, codeBlock.get(), effort, &jitCodeWithArityCheck);
+ jitCode = JIT::compile(&vm, codeBlock.get(), effort, &jitCodeWithArityCheck);
if (!jitCode) {
jitCode = oldJITCode;
jitCodeWithArityCheck = oldJITCodeWithArityCheck;
diff --git a/Source/JavaScriptCore/jit/JITExceptions.cpp b/Source/JavaScriptCore/jit/JITExceptions.cpp
index aeb869474..46f59a3a9 100644
--- a/Source/JavaScriptCore/jit/JITExceptions.cpp
+++ b/Source/JavaScriptCore/jit/JITExceptions.cpp
@@ -29,20 +29,21 @@
#include "CallFrame.h"
#include "CodeBlock.h"
#include "Interpreter.h"
-#include "JSGlobalData.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
+#include "VM.h"
+#include "Operations.h"
#if ENABLE(JIT) || ENABLE(LLINT)
namespace JSC {
-ExceptionHandler genericThrow(JSGlobalData* globalData, ExecState* callFrame, JSValue exceptionValue, unsigned vPCIndex)
+ExceptionHandler genericThrow(VM* vm, ExecState* callFrame, JSValue exceptionValue, unsigned vPCIndex)
{
- ASSERT(exceptionValue);
+ RELEASE_ASSERT(exceptionValue);
- globalData->exception = JSValue();
- HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex); // This may update callFrame & exceptionValue!
- globalData->exception = exceptionValue;
+ vm->exception = JSValue();
+ HandlerInfo* handler = vm->interpreter->throwException(callFrame, exceptionValue, vPCIndex); // This may update callFrame & exceptionValue!
+ vm->exception = exceptionValue;
void* catchRoutine;
Instruction* catchPCForInterpreter = 0;
@@ -52,18 +53,18 @@ ExceptionHandler genericThrow(JSGlobalData* globalData, ExecState* callFrame, JS
} else
catchRoutine = FunctionPtr(LLInt::getCodePtr(ctiOpThrowNotCaught)).value();
- globalData->callFrameForThrow = callFrame;
- globalData->targetMachinePCForThrow = catchRoutine;
- globalData->targetInterpreterPCForThrow = catchPCForInterpreter;
+ vm->callFrameForThrow = callFrame;
+ vm->targetMachinePCForThrow = catchRoutine;
+ vm->targetInterpreterPCForThrow = catchPCForInterpreter;
- ASSERT(catchRoutine);
+ RELEASE_ASSERT(catchRoutine);
ExceptionHandler exceptionHandler = { catchRoutine, callFrame };
return exceptionHandler;
}
-ExceptionHandler jitThrow(JSGlobalData* globalData, ExecState* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation)
+ExceptionHandler jitThrow(VM* vm, ExecState* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation)
{
- return genericThrow(globalData, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation));
+ return genericThrow(vm, callFrame, exceptionValue, callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation));
}
}
diff --git a/Source/JavaScriptCore/jit/JITExceptions.h b/Source/JavaScriptCore/jit/JITExceptions.h
index 1555f95dc..b611caf95 100644
--- a/Source/JavaScriptCore/jit/JITExceptions.h
+++ b/Source/JavaScriptCore/jit/JITExceptions.h
@@ -26,7 +26,7 @@
#ifndef JITExceptions_h
#define JITExceptions_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "MacroAssemblerCodeRef.h"
#if ENABLE(JIT) || ENABLE(LLINT)
@@ -34,7 +34,7 @@
namespace JSC {
class ExecState;
-class JSGlobalData;
+class VM;
// This header gives other parts of the system access to the JIT's prototocol
// for the throwing and handling exceptions.
@@ -44,9 +44,9 @@ struct ExceptionHandler {
ExecState* callFrame;
};
-ExceptionHandler genericThrow(JSGlobalData*, ExecState*, JSValue exceptionValue, unsigned vPCIndex);
+ExceptionHandler genericThrow(VM*, ExecState*, JSValue exceptionValue, unsigned vPCIndex);
-ExceptionHandler jitThrow(JSGlobalData*, ExecState*, JSValue exceptionValue, ReturnAddressPtr faultLocation);
+ExceptionHandler jitThrow(VM*, ExecState*, JSValue exceptionValue, ReturnAddressPtr faultLocation);
} // namespace JSC
diff --git a/Source/JavaScriptCore/jit/JITInlines.h b/Source/JavaScriptCore/jit/JITInlines.h
index e6f95b94c..5e5d834aa 100644
--- a/Source/JavaScriptCore/jit/JITInlines.h
+++ b/Source/JavaScriptCore/jit/JITInlines.h
@@ -42,16 +42,6 @@ ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src)
return m_codeBlock->getConstant(src);
}
-ALWAYS_INLINE void JIT::emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
-{
-#if USE(JSVALUE32_64)
- store32(TrustedImm32(JSValue::CellTag), tagFor(entry, callFrameRegister));
- store32(from, payloadFor(entry, callFrameRegister));
-#else
- store64(from, addressFor(entry, callFrameRegister));
-#endif
-}
-
ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
{
#if USE(JSVALUE32_64)
@@ -62,20 +52,6 @@ ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, JSStack::Ca
#endif
}
-ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
-{
-#if USE(JSVALUE32_64)
- storePtr(from, payloadFor(entry, callFrameRegister));
-#else
- store64(from, addressFor(entry, callFrameRegister));
-#endif
-}
-
-ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry entry)
-{
- storePtr(TrustedImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
-}
-
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
{
loadPtr(Address(from, entry * sizeof(Register)), to);
@@ -102,16 +78,16 @@ ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEnt
ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
{
- failures.append(branchPtr(NotEqual, Address(src, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ failures.append(branchPtr(NotEqual, Address(src, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
failures.append(branchTest32(Zero, dst));
- loadPtr(MacroAssembler::Address(dst, ThunkHelpers::stringImplFlagsOffset()), regT1);
- loadPtr(MacroAssembler::Address(dst, ThunkHelpers::stringImplDataOffset()), dst);
+ loadPtr(MacroAssembler::Address(dst, StringImpl::flagsOffset()), regT1);
+ loadPtr(MacroAssembler::Address(dst, StringImpl::dataOffset()), dst);
JumpList is16Bit;
JumpList cont8Bit;
- is16Bit.append(branchTest32(Zero, regT1, TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ is16Bit.append(branchTest32(Zero, regT1, TrustedImm32(StringImpl::flagIs8Bit())));
load8(MacroAssembler::Address(dst, 0), dst);
cont8Bit.append(jump());
is16Bit.link(this);
@@ -160,18 +136,15 @@ ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace
m_assembler.ensureSpace(insnSpace + m_assembler.maxInstructionSize + 2, constSpace + 8);
#endif
-#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL
#ifndef NDEBUG
m_uninterruptedInstructionSequenceBegin = label();
m_uninterruptedConstantSequenceBegin = sizeOfConstantPool();
#endif
-#endif
}
ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace, int dst)
{
- UNUSED_PARAM(dst);
-#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL
+#ifndef NDEBUG
/* There are several cases when the uninterrupted sequence is larger than
* maximum required offset for pathing the same sequence. Eg.: if in a
* uninterrupted sequence the last macroassembler's instruction is a stub
@@ -179,6 +152,7 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace,
* calculation of length of uninterrupted sequence. So, the insnSpace and
* constSpace should be upper limit instead of hard limit.
*/
+
#if CPU(SH4)
if ((dst > 15) || (dst < -16)) {
insnSpace += 8;
@@ -187,100 +161,30 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace,
if (((dst >= -16) && (dst < 0)) || ((dst > 7) && (dst <= 15)))
insnSpace += 8;
+#else
+ UNUSED_PARAM(dst);
#endif
+
ASSERT(differenceBetween(m_uninterruptedInstructionSequenceBegin, label()) <= insnSpace);
ASSERT(sizeOfConstantPool() - m_uninterruptedConstantSequenceBegin <= constSpace);
+#else
+ UNUSED_PARAM(insnSpace);
+ UNUSED_PARAM(constSpace);
+ UNUSED_PARAM(dst);
#endif
}
-#endif
-
-#if CPU(ARM)
-
-ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
-{
- move(linkRegister, reg);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
-{
- move(reg, linkRegister);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
-{
- loadPtr(address, linkRegister);
-}
-#elif CPU(SH4)
-
-ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
-{
- m_assembler.stspr(reg);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
-{
- m_assembler.ldspr(reg);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
-{
- loadPtrLinkReg(address);
-}
-
-#elif CPU(MIPS)
-
-ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
-{
- move(returnAddressRegister, reg);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
-{
- move(reg, returnAddressRegister);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
-{
- loadPtr(address, returnAddressRegister);
-}
-
-#else // CPU(X86) || CPU(X86_64)
-
-ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
-{
- pop(reg);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
-{
- push(reg);
-}
-
-ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
-{
- push(address);
-}
-
-#endif
-
-ALWAYS_INLINE void JIT::restoreArgumentReference()
-{
- move(stackPointerRegister, firstArgumentRegister);
- poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
-}
+#endif // ASSEMBLER_HAS_CONSTANT_POOL
ALWAYS_INLINE void JIT::updateTopCallFrame()
{
ASSERT(static_cast<int>(m_bytecodeOffset) >= 0);
- if (m_bytecodeOffset) {
#if USE(JSVALUE32_64)
- storePtr(TrustedImmPtr(m_codeBlock->instructions().begin() + m_bytecodeOffset + 1), intTagFor(JSStack::ArgumentCount));
+ storePtr(TrustedImmPtr(m_codeBlock->instructions().begin() + m_bytecodeOffset + 1), intTagFor(JSStack::ArgumentCount));
#else
- store32(TrustedImm32(m_bytecodeOffset + 1), intTagFor(JSStack::ArgumentCount));
+ store32(TrustedImm32(m_bytecodeOffset + 1), intTagFor(JSStack::ArgumentCount));
#endif
- }
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
+ storePtr(callFrameRegister, &m_vm->topCallFrame);
}
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
@@ -351,12 +255,6 @@ ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotObject(RegisterID structureReg)
return branch8(Below, Address(structureReg, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
}
-ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType type)
-{
- loadPtr(Address(baseReg, JSCell::structureOffset()), scratchReg);
- return branch8(NotEqual, Address(scratchReg, Structure::typeInfoTypeOffset()), TrustedImm32(type));
-}
-
#if ENABLE(SAMPLING_FLAGS)
ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag)
{
@@ -415,22 +313,15 @@ ALWAYS_INLINE bool JIT::isOperandConstantImmediateChar(unsigned src)
return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isString() && asString(getConstantOperand(src).asCell())->length() == 1;
}
-template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr)
+template<typename StructureType>
+inline void JIT::emitAllocateJSObject(RegisterID allocator, StructureType structure, RegisterID result, RegisterID scratch)
{
- size_t size = ClassType::allocationSize(INLINE_STORAGE_CAPACITY);
- MarkedAllocator* allocator = 0;
- if (destructorType == MarkedBlock::Normal)
- allocator = &m_globalData->heap.allocatorForObjectWithNormalDestructor(size);
- else if (destructorType == MarkedBlock::ImmortalStructure)
- allocator = &m_globalData->heap.allocatorForObjectWithImmortalStructureDestructor(size);
- else
- allocator = &m_globalData->heap.allocatorForObjectWithoutDestructor(size);
- loadPtr(&allocator->m_freeList.head, result);
+ loadPtr(Address(allocator, MarkedAllocator::offsetOfFreeListHead()), result);
addSlowCase(branchTestPtr(Zero, result));
// remove the object from the free list
- loadPtr(Address(result), storagePtr);
- storePtr(storagePtr, &allocator->m_freeList.head);
+ loadPtr(Address(result), scratch);
+ storePtr(scratch, Address(allocator, MarkedAllocator::offsetOfFreeListHead()));
// initialize the object's structure
storePtr(structure, Address(result, JSCell::structureOffset()));
@@ -439,11 +330,6 @@ template <typename ClassType, MarkedBlock::DestructorType destructorType, typena
storePtr(TrustedImmPtr(0), Address(result, JSObject::butterflyOffset()));
}
-template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch)
-{
- emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None, T>(structure, result, scratch);
-}
-
#if ENABLE(VALUE_PROFILER)
inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile)
{
@@ -503,7 +389,7 @@ inline void JIT::emitArrayProfilingSite(RegisterID structureAndIndexingType, Reg
RegisterID structure = structureAndIndexingType;
RegisterID indexingType = structureAndIndexingType;
- if (canBeOptimized())
+ if (shouldEmitProfiling())
storePtr(structure, arrayProfile->addressOfLastSeenStructure());
load8(Address(structure, Structure::indexingTypeOffset()), indexingType);
@@ -528,6 +414,15 @@ inline void JIT::emitArrayProfileStoreToHoleSpecialCase(ArrayProfile* arrayProfi
#endif
}
+inline void JIT::emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile* arrayProfile)
+{
+#if ENABLE(VALUE_PROFILER)
+ store8(TrustedImm32(1), arrayProfile->addressOfOutOfBounds());
+#else
+ UNUSED_PARAM(arrayProfile);
+#endif
+}
+
static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capability)
{
#if ENABLE(VALUE_PROFILER)
@@ -605,10 +500,10 @@ inline void JIT::emitLoad(const JSValue& v, RegisterID tag, RegisterID payload)
inline void JIT::emitLoad(int index, RegisterID tag, RegisterID payload, RegisterID base)
{
- ASSERT(tag != payload);
+ RELEASE_ASSERT(tag != payload);
if (base == callFrameRegister) {
- ASSERT(payload != base);
+ RELEASE_ASSERT(payload != base);
emitLoadPayload(index, payload);
emitLoadTag(index, tag);
return;
@@ -732,8 +627,8 @@ inline void JIT::map(unsigned bytecodeOffset, int virtualRegisterIndex, Register
m_mappedTag = tag;
m_mappedPayload = payload;
- ASSERT(!canBeOptimized() || m_mappedPayload == regT0);
- ASSERT(!canBeOptimized() || m_mappedTag == regT1);
+ ASSERT(!canBeOptimizedOrInlined() || m_mappedPayload == regT0);
+ ASSERT(!canBeOptimizedOrInlined() || m_mappedTag == regT1);
}
inline void JIT::unmap(RegisterID registerID)
@@ -919,11 +814,6 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfJSCell(RegisterID reg)
addSlowCase(emitJumpIfJSCell(reg));
}
-ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg)
-{
- return branchTest64(NonZero, reg, tagMaskRegister);
-}
-
ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg)
{
addSlowCase(emitJumpIfNotJSCell(reg));
@@ -990,14 +880,6 @@ ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID d
emitFastArithIntToImmNoCheck(src, dest);
}
-// operand is int32_t, must have been zero-extended if register is 64-bit.
-ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
-{
- if (src != dest)
- move(src, dest);
- or64(tagTypeNumberRegister, dest);
-}
-
ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
{
or32(TrustedImm32(static_cast<int32_t>(ValueFalse)), reg);
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index 36e7ece1b..2a88f5052 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -43,324 +43,9 @@ namespace JSC {
#if USE(JSVALUE64)
-PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGlobalData* globalData, TrampolineStructure *trampolines)
+JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction)
{
- // (2) The second function provides fast property access for string length
- Label stringLengthBegin = align();
-
- // Check eax is a string
- Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
- Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get()));
-
- // Checks out okay! - get the length from the Ustring.
- load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT0);
-
- Jump string_failureCases3 = branch32(LessThan, regT0, TrustedImm32(0));
-
- // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
- emitFastArithIntToImmNoCheck(regT0, regT0);
-
- ret();
-
- // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
- COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit);
-
- JumpList callSlowCase;
- JumpList constructSlowCase;
-
- // VirtualCallLink Trampoline
- // regT0 holds callee; callFrame is moved and partially initialized.
- Label virtualCallLinkBegin = align();
- callSlowCase.append(emitJumpIfNotJSCell(regT0));
- callSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- // Also initialize ReturnPC for use by lazy linking and exceptions.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callLazyLinkCall = call();
- restoreReturnAddressBeforeReturn(regT3);
- jump(regT0);
-
- // VirtualConstructLink Trampoline
- // regT0 holds callee; callFrame is moved and partially initialized.
- Label virtualConstructLinkBegin = align();
- constructSlowCase.append(emitJumpIfNotJSCell(regT0));
- constructSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- // Also initialize ReturnPC for use by lazy linking and exeptions.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callLazyLinkConstruct = call();
- restoreReturnAddressBeforeReturn(regT3);
- jump(regT0);
-
- // VirtualCall Trampoline
- // regT0 holds callee; regT2 will hold the FunctionExecutable.
- Label virtualCallBegin = align();
- callSlowCase.append(emitJumpIfNotJSCell(regT0));
- callSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock1 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), TrustedImm32(0));
- preserveReturnAddressAfterCall(regT3);
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callCompileCall = call();
- restoreReturnAddressBeforeReturn(regT3);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
- hasCodeBlock1.link(this);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCodeForCallWithArityCheck)), regT0);
- jump(regT0);
-
- // VirtualConstruct Trampoline
- // regT0 holds callee; regT2 will hold the FunctionExecutable.
- Label virtualConstructBegin = align();
- constructSlowCase.append(emitJumpIfNotJSCell(regT0));
- constructSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock2 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), TrustedImm32(0));
- preserveReturnAddressAfterCall(regT3);
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callCompileConstruct = call();
- restoreReturnAddressBeforeReturn(regT3);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
- hasCodeBlock2.link(this);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCodeForConstructWithArityCheck)), regT0);
- jump(regT0);
-
- callSlowCase.link(this);
- // Finish canonical initialization before JS function call.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2);
- emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain);
-
- // Also initialize ReturnPC and CodeBlock, like a JS function would.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
- emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callCallNotJSFunction = call();
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister);
- restoreReturnAddressBeforeReturn(regT3);
- ret();
-
- constructSlowCase.link(this);
- // Finish canonical initialization before JS function call.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2);
- emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain);
-
- // Also initialize ReturnPC and CodeBlock, like a JS function would.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
- emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callConstructNotJSFunction = call();
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister);
- restoreReturnAddressBeforeReturn(regT3);
- ret();
-
- // NativeCall Trampoline
- Label nativeCallThunk = privateCompileCTINativeCall(globalData);
- Label nativeConstructThunk = privateCompileCTINativeCall(globalData, true);
-
- Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1);
- Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2);
- Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3);
-
- // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
- LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID);
-
- patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail));
- patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail));
- patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
- patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
- patchBuffer.link(callLazyLinkConstruct, FunctionPtr(cti_vm_lazyLinkConstruct));
- patchBuffer.link(callCompileCall, FunctionPtr(cti_op_call_jitCompile));
- patchBuffer.link(callCompileConstruct, FunctionPtr(cti_op_construct_jitCompile));
- patchBuffer.link(callCallNotJSFunction, FunctionPtr(cti_op_call_NotJSFunction));
- patchBuffer.link(callConstructNotJSFunction, FunctionPtr(cti_op_construct_NotJSConstruct));
-
- CodeRef finalCode = FINALIZE_CODE(patchBuffer, ("JIT CTI machine trampolines"));
- RefPtr<ExecutableMemoryHandle> executableMemory = finalCode.executableMemory();
-
- trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin);
- trampolines->ctiVirtualConstructLink = patchBuffer.trampolineAt(virtualConstructLinkBegin);
- trampolines->ctiVirtualCall = patchBuffer.trampolineAt(virtualCallBegin);
- trampolines->ctiVirtualConstruct = patchBuffer.trampolineAt(virtualConstructBegin);
- trampolines->ctiNativeCall = patchBuffer.trampolineAt(nativeCallThunk);
- trampolines->ctiNativeConstruct = patchBuffer.trampolineAt(nativeConstructThunk);
- trampolines->ctiStringLengthTrampoline = patchBuffer.trampolineAt(stringLengthBegin);
-
- return executableMemory.release();
-}
-
-JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isConstruct)
-{
- int executableOffsetToFunction = isConstruct ? OBJECT_OFFSETOF(NativeExecutable, m_constructor) : OBJECT_OFFSETOF(NativeExecutable, m_function);
-
- Label nativeCallThunk = align();
-
- emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
-
-#if CPU(X86_64)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- peek(regT1);
- emitPutToCallFrameHeader(regT1, JSStack::ReturnPC);
-
-#if !OS(WINDOWS)
- // Calling convention: f(edi, esi, edx, ecx, ...);
- // Host function signature: f(ExecState*);
- move(callFrameRegister, X86Registers::edi);
-
- subPtr(TrustedImm32(16 - sizeof(int64_t)), stackPointerRegister); // Align stack after call.
-
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, X86Registers::esi);
- loadPtr(Address(X86Registers::esi, OBJECT_OFFSETOF(JSFunction, m_executable)), X86Registers::r9);
- move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- call(Address(X86Registers::r9, executableOffsetToFunction));
-
- addPtr(TrustedImm32(16 - sizeof(int64_t)), stackPointerRegister);
-#else
- // Calling convention: f(ecx, edx, r8, r9, ...);
- // Host function signature: f(ExecState*);
- move(callFrameRegister, X86Registers::ecx);
-
- // Leave space for the callee parameter home addresses and align the stack.
- subPtr(TrustedImm32(4 * sizeof(int64_t) + 16 - sizeof(int64_t)), stackPointerRegister);
-
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, X86Registers::edx);
- loadPtr(Address(X86Registers::edx, OBJECT_OFFSETOF(JSFunction, m_executable)), X86Registers::r9);
- move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- call(Address(X86Registers::r9, executableOffsetToFunction));
-
- addPtr(TrustedImm32(4 * sizeof(int64_t) + 16 - sizeof(int64_t)), stackPointerRegister);
-#endif
-
-#elif CPU(ARM)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- preserveReturnAddressAfterCall(regT3); // Callee preserved
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- // Calling convention: f(r0 == regT0, r1 == regT1, ...);
- // Host function signature: f(ExecState*);
- move(callFrameRegister, ARMRegisters::r0);
-
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, ARMRegisters::r1);
- move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- call(Address(regT2, executableOffsetToFunction));
-
- restoreReturnAddressBeforeReturn(regT3);
-
-#elif CPU(MIPS)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- preserveReturnAddressAfterCall(regT3); // Callee preserved
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- // Calling convention: f(a0, a1, a2, a3);
- // Host function signature: f(ExecState*);
-
- // Allocate stack space for 16 bytes (8-byte aligned)
- // 16 bytes (unused) for 4 arguments
- subPtr(TrustedImm32(16), stackPointerRegister);
-
- // Setup arg0
- move(callFrameRegister, MIPSRegisters::a0);
-
- // Call
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, MIPSRegisters::a2);
- loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- call(Address(regT2, executableOffsetToFunction));
-
- // Restore stack space
- addPtr(TrustedImm32(16), stackPointerRegister);
-
- restoreReturnAddressBeforeReturn(regT3);
-
-#else
-#error "JIT not supported on this platform."
- UNUSED_PARAM(executableOffsetToFunction);
- breakpoint();
-#endif
-
- // Check for an exception
- load64(&(globalData->exception), regT2);
- Jump exceptionHandler = branchTest64(NonZero, regT2);
-
- // Return.
- ret();
-
- // Handle an exception
- exceptionHandler.link(this);
-
- // Grab the return address.
- preserveReturnAddressAfterCall(regT1);
-
- move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
- storePtr(regT1, regT2);
- poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- // Set the return address.
- move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
- restoreReturnAddressBeforeReturn(regT1);
-
- ret();
-
- return nativeCallThunk;
-}
-
-JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFunction)
-{
- return CodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return vm->getCTIStub(nativeCallGenerator);
}
void JIT::emit_op_mov(Instruction* currentInstruction)
@@ -368,7 +53,7 @@ void JIT::emit_op_mov(Instruction* currentInstruction)
int dst = currentInstruction[1].u.operand;
int src = currentInstruction[2].u.operand;
- if (canBeOptimized()) {
+ if (canBeOptimizedOrInlined()) {
// Use simpler approach, since the DFG thinks that the last result register
// is always set to the destination on every operation.
emitGetVirtualRegister(src, regT0);
@@ -396,7 +81,7 @@ void JIT::emit_op_mov(Instruction* currentInstruction)
void JIT::emit_op_end(Instruction* currentInstruction)
{
- ASSERT(returnValueRegister != callFrameRegister);
+ RELEASE_ASSERT(returnValueRegister != callFrameRegister);
emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
restoreReturnAddressBeforeReturn(Address(callFrameRegister, JSStack::ReturnPC * static_cast<int>(sizeof(Register))));
ret();
@@ -410,15 +95,25 @@ void JIT::emit_op_jmp(Instruction* currentInstruction)
void JIT::emit_op_new_object(Instruction* currentInstruction)
{
- emitAllocateJSFinalObject(TrustedImmPtr(m_codeBlock->globalObject()->emptyObjectStructure()), regT0, regT1);
-
+ Structure* structure = currentInstruction[3].u.objectAllocationProfile->structure();
+ size_t allocationSize = JSObject::allocationSize(structure->inlineCapacity());
+ MarkedAllocator* allocator = &m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize);
+
+ RegisterID resultReg = regT0;
+ RegisterID allocatorReg = regT1;
+ RegisterID scratchReg = regT2;
+
+ move(TrustedImmPtr(allocator), allocatorReg);
+ emitAllocateJSObject(allocatorReg, TrustedImmPtr(structure), resultReg, scratchReg);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
void JIT::emitSlow_op_new_object(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
- JITStubCall(this, cti_op_new_object).call(currentInstruction[1].u.operand);
+ JITStubCall stubCall(this, cti_op_new_object);
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[3].u.objectAllocationProfile->structure()));
+ stubCall.call(currentInstruction[1].u.operand);
}
void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
@@ -655,7 +350,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
emitGetVirtualRegister(src, regT0);
Jump isImm = emitJumpIfNotJSCell(regT0);
- addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
isImm.link(this);
if (dst != src)
@@ -671,14 +366,6 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
stubCall.call(currentInstruction[1].u.operand);
}
-void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_ensure_property_exists);
- stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
- stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_not(Instruction* currentInstruction)
{
emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
@@ -989,18 +676,12 @@ void JIT::emit_op_nstricteq(Instruction* currentInstruction)
compileOpStrictEq(currentInstruction, OpNStrictEq);
}
-void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
+void JIT::emit_op_to_number(Instruction* currentInstruction)
{
int srcVReg = currentInstruction[2].u.operand;
emitGetVirtualRegister(srcVReg, regT0);
- Jump wasImmediate = emitJumpIfImmediateInteger(regT0);
-
- emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
- loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
- addSlowCase(branch8(NotEqual, Address(regT2, Structure::typeInfoTypeOffset()), TrustedImm32(NumberType)));
-
- wasImmediate.link(this);
+ addSlowCase(emitJumpIfNotImmediateNumber(regT0));
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -1018,20 +699,12 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
{
killLastResultRegister(); // FIXME: Implicitly treat op_catch as a labeled statement, and remove this line of code.
move(regT0, callFrameRegister);
- peek(regT3, OBJECT_OFFSETOF(struct JITStackFrame, globalData) / sizeof(void*));
- load64(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception)), regT0);
- store64(TrustedImm64(JSValue::encode(JSValue())), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception)));
+ peek(regT3, OBJECT_OFFSETOF(struct JITStackFrame, vm) / sizeof(void*));
+ load64(Address(regT3, OBJECT_OFFSETOF(VM, exception)), regT0);
+ store64(TrustedImm64(JSValue::encode(JSValue())), Address(regT3, OBJECT_OFFSETOF(VM, exception)));
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
-void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_jmp_scopes);
- stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
- stubCall.call();
- addJump(jump(), currentInstruction[2].u.operand);
-}
-
void JIT::emit_op_switch_imm(Instruction* currentInstruction)
{
unsigned tableIndex = currentInstruction[1].u.operand;
@@ -1176,7 +849,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
void JIT::emit_op_enter(Instruction*)
{
- emitOptimizationCheck(EnterOptimizationCheck);
+ emitEnterOptimizationCheck();
// Even though CTI doesn't use them, we initialize our constant
// registers to zap stale pointers, to avoid unnecessarily prolonging
@@ -1223,7 +896,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
loadPtr(Address(regT1, JSCell::structureOffset()), regT0);
emitValueProfilingSite();
}
- addSlowCase(branchPtr(Equal, Address(regT1, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ addSlowCase(branchPtr(Equal, Address(regT1, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
}
void JIT::emit_op_get_callee(Instruction* currentInstruction)
@@ -1237,22 +910,28 @@ void JIT::emit_op_get_callee(Instruction* currentInstruction)
void JIT::emit_op_create_this(Instruction* currentInstruction)
{
int callee = currentInstruction[2].u.operand;
- emitGetVirtualRegister(callee, regT0);
- loadPtr(Address(regT0, JSFunction::offsetOfCachedInheritorID()), regT2);
- addSlowCase(branchTestPtr(Zero, regT2));
-
- // now regT2 contains the inheritorID, which is the structure that the newly
- // allocated object will have.
-
- emitAllocateJSFinalObject(regT2, regT0, regT1);
+ RegisterID calleeReg = regT0;
+ RegisterID resultReg = regT0;
+ RegisterID allocatorReg = regT1;
+ RegisterID structureReg = regT2;
+ RegisterID scratchReg = regT3;
+
+ emitGetVirtualRegister(callee, calleeReg);
+ loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg);
+ loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg);
+ addSlowCase(branchTestPtr(Zero, allocatorReg));
+
+ emitAllocateJSObject(allocatorReg, structureReg, resultReg, scratchReg);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- linkSlowCase(iter); // doesn't have an inheritor ID
+ linkSlowCase(iter); // doesn't have an allocation profile
linkSlowCase(iter); // allocation failed
+
JITStubCall stubCall(this, cti_op_create_this);
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1288,7 +967,7 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC
linkSlowCase(iter);
if (shouldEmitProfiling())
- move(TrustedImm64(JSValue::encode(m_globalData->stringStructure.get())), regT0);
+ move(TrustedImm64(JSValue::encode(m_vm->stringStructure.get())), regT0);
isNotUndefined.link(this);
emitValueProfilingSite();
JITStubCall stubCall(this, cti_op_convert_this);
@@ -1446,12 +1125,11 @@ void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCase
compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
}
-void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand);
linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_to_jsnumber);
+ JITStubCall stubCall(this, cti_op_to_number);
stubCall.addArgument(regT0);
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1529,7 +1207,7 @@ void JIT::emit_op_put_to_base(Instruction* currentInstruction)
int id = currentInstruction[2].u.operand;
int value = currentInstruction[3].u.operand;
- PutToBaseOperation* operation = m_codeBlock->putToBaseOperation(currentInstruction[4].u.operand);
+ PutToBaseOperation* operation = currentInstruction[4].u.putToBaseOperation;
switch (operation->m_kind) {
case PutToBaseOperation::GlobalVariablePutChecked:
addSlowCase(branchTest8(NonZero, AbsoluteAddress(operation->m_predicatePointer)));
@@ -1584,6 +1262,45 @@ void JIT::emit_op_put_to_base(Instruction* currentInstruction)
#endif // USE(JSVALUE64)
+void JIT::emit_op_loop_hint(Instruction*)
+{
+ // Emit the JIT optimization check:
+ if (canBeOptimized())
+ addSlowCase(branchAdd32(PositiveOrZero, TrustedImm32(Options::executionCounterIncrementForLoop()),
+ AbsoluteAddress(m_codeBlock->addressOfJITExecuteCounter())));
+
+ // Emit the watchdog timer check:
+ if (m_vm->watchdog.isEnabled())
+ addSlowCase(branchTest8(NonZero, AbsoluteAddress(m_vm->watchdog.timerDidFireAddress())));
+}
+
+void JIT::emitSlow_op_loop_hint(Instruction*, Vector<SlowCaseEntry>::iterator& iter)
+{
+#if ENABLE(DFG_JIT)
+ // Emit the slow path for the JIT optimization check:
+ if (canBeOptimized()) {
+ linkSlowCase(iter);
+
+ JITStubCall stubCall(this, cti_optimize);
+ stubCall.addArgument(TrustedImm32(m_bytecodeOffset));
+ stubCall.call();
+
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_loop_hint));
+ }
+#endif
+
+ // Emit the slow path of the watchdog timer check:
+ if (m_vm->watchdog.isEnabled()) {
+ linkSlowCase(iter);
+
+ JITStubCall stubCall(this, cti_handle_watchdog_timer);
+ stubCall.call();
+
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_loop_hint));
+ }
+
+}
+
void JIT::emit_resolve_operations(ResolveOperations* resolveOperations, const int* baseVR, const int* valueVR)
{
@@ -1621,7 +1338,7 @@ void JIT::emit_resolve_operations(ResolveOperations* resolveOperations, const in
emitStoreCell(*baseVR, value);
return;
case ResolveOperation::SetBaseToGlobal:
- ASSERT(baseVR);
+ RELEASE_ASSERT(baseVR);
setBase = true;
move(TrustedImmPtr(globalObject), scratch);
emitStoreCell(*baseVR, scratch);
@@ -1629,7 +1346,7 @@ void JIT::emit_resolve_operations(ResolveOperations* resolveOperations, const in
++pc;
break;
case ResolveOperation::SetBaseToUndefined: {
- ASSERT(baseVR);
+ RELEASE_ASSERT(baseVR);
setBase = true;
#if USE(JSVALUE64)
move(TrustedImm64(JSValue::encode(jsUndefined())), scratch);
@@ -1642,7 +1359,7 @@ void JIT::emit_resolve_operations(ResolveOperations* resolveOperations, const in
break;
}
case ResolveOperation::SetBaseToScope:
- ASSERT(baseVR);
+ RELEASE_ASSERT(baseVR);
setBase = true;
emitStoreCell(*baseVR, scope);
resolvingBase = false;
@@ -1650,7 +1367,7 @@ void JIT::emit_resolve_operations(ResolveOperations* resolveOperations, const in
break;
case ResolveOperation::ReturnScopeAsBase:
emitStoreCell(*baseVR, scope);
- ASSERT(value == regT0);
+ RELEASE_ASSERT(value == regT0);
move(scope, value);
#if USE(JSVALUE32_64)
move(TrustedImm32(JSValue::CellTag), valueTag);
@@ -1700,7 +1417,7 @@ void JIT::emit_resolve_operations(ResolveOperations* resolveOperations, const in
if (baseVR && !setBase)
emitStoreCell(*baseVR, scope);
- ASSERT(valueVR);
+ RELEASE_ASSERT(valueVR);
ResolveOperation* resolveValueOperation = pc;
switch (resolveValueOperation->m_operation) {
case ResolveOperation::GetAndReturnGlobalProperty: {
@@ -1821,42 +1538,42 @@ void JIT::emitSlow_link_resolve_operations(ResolveOperations* resolveOperations,
void JIT::emit_op_resolve(Instruction* currentInstruction)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[3].u.operand);
+ ResolveOperations* operations = currentInstruction[3].u.resolveOperations;
int dst = currentInstruction[1].u.operand;
emit_resolve_operations(operations, 0, &dst);
}
void JIT::emitSlow_op_resolve(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[3].u.operand);
+ ResolveOperations* operations = currentInstruction[3].u.resolveOperations;
emitSlow_link_resolve_operations(operations, iter);
JITStubCall stubCall(this, cti_op_resolve);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->resolveOperations(currentInstruction[3].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[3].u.resolveOperations));
stubCall.callWithValueProfiling(currentInstruction[1].u.operand);
}
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[4].u.operand);
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
int dst = currentInstruction[1].u.operand;
emit_resolve_operations(operations, &dst, 0);
}
void JIT::emitSlow_op_resolve_base(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[4].u.operand);
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
emitSlow_link_resolve_operations(operations, iter);
JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->resolveOperations(currentInstruction[4].u.operand)));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->putToBaseOperation(currentInstruction[5].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[4].u.resolveOperations));
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[5].u.putToBaseOperation));
stubCall.callWithValueProfiling(currentInstruction[1].u.operand);
}
void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[4].u.operand);
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
int base = currentInstruction[1].u.operand;
int value = currentInstruction[2].u.operand;
emit_resolve_operations(operations, &base, &value);
@@ -1864,19 +1581,19 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
void JIT::emitSlow_op_resolve_with_base(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[4].u.operand);
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
emitSlow_link_resolve_operations(operations, iter);
JITStubCall stubCall(this, cti_op_resolve_with_base);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->resolveOperations(currentInstruction[4].u.operand)));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->putToBaseOperation(currentInstruction[5].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[4].u.resolveOperations));
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[5].u.putToBaseOperation));
stubCall.callWithValueProfiling(currentInstruction[2].u.operand);
}
void JIT::emit_op_resolve_with_this(Instruction* currentInstruction)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[4].u.operand);
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
int base = currentInstruction[1].u.operand;
int value = currentInstruction[2].u.operand;
emit_resolve_operations(operations, &base, &value);
@@ -1884,12 +1601,12 @@ void JIT::emit_op_resolve_with_this(Instruction* currentInstruction)
void JIT::emitSlow_op_resolve_with_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- ResolveOperations* operations = m_codeBlock->resolveOperations(currentInstruction[4].u.operand);
+ ResolveOperations* operations = currentInstruction[4].u.resolveOperations;
emitSlow_link_resolve_operations(operations, iter);
JITStubCall stubCall(this, cti_op_resolve_with_this);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->resolveOperations(currentInstruction[4].u.operand)));
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[4].u.resolveOperations));
stubCall.callWithValueProfiling(currentInstruction[2].u.operand);
}
@@ -1898,13 +1615,14 @@ void JIT::emitSlow_op_put_to_base(Instruction* currentInstruction, Vector<SlowCa
int base = currentInstruction[1].u.operand;
int id = currentInstruction[2].u.operand;
int value = currentInstruction[3].u.operand;
- int operation = currentInstruction[4].u.operand;
- PutToBaseOperation* putToBaseOperation = m_codeBlock->putToBaseOperation(currentInstruction[4].u.operand);
+ PutToBaseOperation* putToBaseOperation = currentInstruction[4].u.putToBaseOperation;
switch (putToBaseOperation->m_kind) {
case PutToBaseOperation::VariablePut:
return;
+ case PutToBaseOperation::GlobalVariablePutChecked:
+ linkSlowCase(iter);
case PutToBaseOperation::GlobalVariablePut:
if (!putToBaseOperation->m_isDynamic)
return;
@@ -1916,7 +1634,6 @@ void JIT::emitSlow_op_put_to_base(Instruction* currentInstruction, Vector<SlowCa
case PutToBaseOperation::Generic:
return;
- case PutToBaseOperation::GlobalVariablePutChecked:
case PutToBaseOperation::GlobalPropertyPut:
linkSlowCase(iter);
break;
@@ -1928,7 +1645,7 @@ void JIT::emitSlow_op_put_to_base(Instruction* currentInstruction, Vector<SlowCa
stubCall.addArgument(TrustedImm32(base));
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(id)));
stubCall.addArgument(TrustedImm32(value));
- stubCall.addArgument(TrustedImmPtr(m_codeBlock->putToBaseOperation(operation)));
+ stubCall.addArgument(TrustedImmPtr(putToBaseOperation));
stubCall.call();
}
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 13daf962a..4836a66b5 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -41,330 +41,12 @@
namespace JSC {
-PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGlobalData* globalData, TrampolineStructure *trampolines)
-{
- // (1) This function provides fast property access for string length
- Label stringLengthBegin = align();
-
- // regT0 holds payload, regT1 holds tag
-
- Jump string_failureCases1 = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get()));
-
- // Checks out okay! - get the length from the Ustring.
- load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT2);
-
- Jump string_failureCases3 = branch32(Above, regT2, TrustedImm32(INT_MAX));
- move(regT2, regT0);
- move(TrustedImm32(JSValue::Int32Tag), regT1);
-
- ret();
-
- JumpList callSlowCase;
- JumpList constructSlowCase;
-
- // VirtualCallLink Trampoline
- // regT1, regT0 holds callee; callFrame is moved and partially initialized.
- Label virtualCallLinkBegin = align();
- callSlowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
- callSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- // Also initialize ReturnPC for use by lazy linking and exceptions.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callLazyLinkCall = call();
- restoreReturnAddressBeforeReturn(regT3);
- jump(regT0);
-
- // VirtualConstructLink Trampoline
- // regT1, regT0 holds callee; callFrame is moved and partially initialized.
- Label virtualConstructLinkBegin = align();
- constructSlowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
- constructSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- // Also initialize ReturnPC for use by lazy linking and exeptions.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callLazyLinkConstruct = call();
- restoreReturnAddressBeforeReturn(regT3);
- jump(regT0);
-
- // VirtualCall Trampoline
- // regT1, regT0 holds callee; regT2 will hold the FunctionExecutable.
- Label virtualCallBegin = align();
- callSlowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
- callSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock1 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), TrustedImm32(0));
- preserveReturnAddressAfterCall(regT3);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callCompileCall = call();
- restoreReturnAddressBeforeReturn(regT3);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
- hasCodeBlock1.link(this);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCodeForCallWithArityCheck)), regT0);
- jump(regT0);
-
- // VirtualConstruct Trampoline
- // regT1, regT0 holds callee; regT2 will hold the FunctionExecutable.
- Label virtualConstructBegin = align();
- constructSlowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
- constructSlowCase.append(emitJumpIfNotType(regT0, regT1, JSFunctionType));
-
- // Finish canonical initialization before JS function call.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- Jump hasCodeBlock2 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), TrustedImm32(0));
- preserveReturnAddressAfterCall(regT3);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callCompileConstruct = call();
- restoreReturnAddressBeforeReturn(regT3);
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
- hasCodeBlock2.link(this);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCodeForConstructWithArityCheck)), regT0);
- jump(regT0);
-
- callSlowCase.link(this);
- // Finish canonical initialization before JS function call.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2);
- emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain);
-
- // Also initialize ReturnPC and CodeBlock, like a JS function would.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
- emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callCallNotJSFunction = call();
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister);
- restoreReturnAddressBeforeReturn(regT3);
- ret();
-
- constructSlowCase.link(this);
- // Finish canonical initialization before JS function call.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2);
- emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain);
-
- // Also initialize ReturnPC and CodeBlock, like a JS function would.
- preserveReturnAddressAfterCall(regT3);
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
- emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- restoreArgumentReference();
- Call callConstructNotJSFunction = call();
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister);
- restoreReturnAddressBeforeReturn(regT3);
- ret();
-
- // NativeCall Trampoline
- Label nativeCallThunk = privateCompileCTINativeCall(globalData);
- Label nativeConstructThunk = privateCompileCTINativeCall(globalData, true);
-
- Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1);
- Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2);
- Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3);
-
- // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
- LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID);
-
- patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail));
- patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail));
- patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
- patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
- patchBuffer.link(callLazyLinkConstruct, FunctionPtr(cti_vm_lazyLinkConstruct));
- patchBuffer.link(callCompileCall, FunctionPtr(cti_op_call_jitCompile));
- patchBuffer.link(callCompileConstruct, FunctionPtr(cti_op_construct_jitCompile));
- patchBuffer.link(callCallNotJSFunction, FunctionPtr(cti_op_call_NotJSFunction));
- patchBuffer.link(callConstructNotJSFunction, FunctionPtr(cti_op_construct_NotJSConstruct));
-
- CodeRef finalCode = FINALIZE_CODE(patchBuffer, ("JIT CTI machine trampolines"));
- RefPtr<ExecutableMemoryHandle> executableMemory = finalCode.executableMemory();
-
- trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin);
- trampolines->ctiVirtualConstructLink = patchBuffer.trampolineAt(virtualConstructLinkBegin);
- trampolines->ctiVirtualCall = patchBuffer.trampolineAt(virtualCallBegin);
- trampolines->ctiVirtualConstruct = patchBuffer.trampolineAt(virtualConstructBegin);
- trampolines->ctiNativeCall = patchBuffer.trampolineAt(nativeCallThunk);
- trampolines->ctiNativeConstruct = patchBuffer.trampolineAt(nativeConstructThunk);
- trampolines->ctiStringLengthTrampoline = patchBuffer.trampolineAt(stringLengthBegin);
-
- return executableMemory.release();
-}
-
-JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isConstruct)
-{
- int executableOffsetToFunction = isConstruct ? OBJECT_OFFSETOF(NativeExecutable, m_constructor) : OBJECT_OFFSETOF(NativeExecutable, m_function);
-
- Label nativeCallThunk = align();
-
- emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
-
-#if CPU(X86)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- peek(regT1);
- emitPutToCallFrameHeader(regT1, JSStack::ReturnPC);
-
- // Calling convention: f(ecx, edx, ...);
- // Host function signature: f(ExecState*);
- move(callFrameRegister, X86Registers::ecx);
-
- subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call.
-
- // call the function
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT1);
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT1);
- move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- call(Address(regT1, executableOffsetToFunction));
-
- addPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister);
-
-#elif CPU(ARM)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- preserveReturnAddressAfterCall(regT3); // Callee preserved
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- // Calling convention: f(r0 == regT0, r1 == regT1, ...);
- // Host function signature: f(ExecState*);
- move(callFrameRegister, ARMRegisters::r0);
-
- // call the function
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, ARMRegisters::r1);
- move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- call(Address(regT2, executableOffsetToFunction));
-
- restoreReturnAddressBeforeReturn(regT3);
-#elif CPU(SH4)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- preserveReturnAddressAfterCall(regT3); // Callee preserved
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- // Calling convention: f(r0 == regT4, r1 == regT5, ...);
- // Host function signature: f(ExecState*);
- move(callFrameRegister, regT4);
-
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT5);
- move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- loadPtr(Address(regT5, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
- call(Address(regT2, executableOffsetToFunction), regT0);
- restoreReturnAddressBeforeReturn(regT3);
-#elif CPU(MIPS)
- // Load caller frame's scope chain into this callframe so that whatever we call can
- // get to its global data.
- emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0);
- emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0);
- emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
-
- preserveReturnAddressAfterCall(regT3); // Callee preserved
- emitPutToCallFrameHeader(regT3, JSStack::ReturnPC);
-
- // Calling convention: f(a0, a1, a2, a3);
- // Host function signature: f(ExecState*);
-
- // Allocate stack space for 16 bytes (8-byte aligned)
- // 16 bytes (unused) for 4 arguments
- subPtr(TrustedImm32(16), stackPointerRegister);
-
- // Setup arg0
- move(callFrameRegister, MIPSRegisters::a0);
-
- // Call
- emitGetFromCallFrameHeaderPtr(JSStack::Callee, MIPSRegisters::a2);
- loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
- move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
- call(Address(regT2, executableOffsetToFunction));
-
- // Restore stack space
- addPtr(TrustedImm32(16), stackPointerRegister);
-
- restoreReturnAddressBeforeReturn(regT3);
-
-#else
-#error "JIT not supported on this platform."
- UNUSED_PARAM(executableOffsetToFunction);
- breakpoint();
-#endif // CPU(X86)
-
- // Check for an exception
- Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
-
- // Return.
- ret();
-
- // Handle an exception
- sawException.link(this);
-
- // Grab the return address.
- preserveReturnAddressAfterCall(regT1);
-
- move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
- storePtr(regT1, regT2);
- poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
-
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
- // Set the return address.
- move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
- restoreReturnAddressBeforeReturn(regT1);
-
- ret();
-
- return nativeCallThunk;
-}
-
-JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFunction func)
+JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
{
Call nativeCall;
emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
+ storePtr(callFrameRegister, &m_vm->topCallFrame);
#if CPU(X86)
// Load caller frame's scope chain into this callframe so that whatever we call can
@@ -472,7 +154,7 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu
#endif // CPU(X86)
// Check for an exception
- Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
+ Jump sawException = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&vm->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
// Return.
ret();
@@ -483,11 +165,11 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu
// Grab the return address.
preserveReturnAddressAfterCall(regT1);
- move(TrustedImmPtr(&globalData->exceptionLocation), regT2);
+ move(TrustedImmPtr(&vm->exceptionLocation), regT2);
storePtr(regT1, regT2);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
- storePtr(callFrameRegister, &m_globalData->topCallFrame);
+ storePtr(callFrameRegister, &m_vm->topCallFrame);
// Set the return address.
move(TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT1);
restoreReturnAddressBeforeReturn(regT1);
@@ -495,7 +177,7 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu
ret();
// All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
- LinkBuffer patchBuffer(*m_globalData, this, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*m_vm, this, GLOBAL_THUNK_ID);
patchBuffer.link(nativeCall, FunctionPtr(func));
return FINALIZE_CODE(patchBuffer, ("JIT CTI native call"));
@@ -531,15 +213,25 @@ void JIT::emit_op_jmp(Instruction* currentInstruction)
void JIT::emit_op_new_object(Instruction* currentInstruction)
{
- emitAllocateJSFinalObject(TrustedImmPtr(m_codeBlock->globalObject()->emptyObjectStructure()), regT0, regT1);
-
- emitStoreCell(currentInstruction[1].u.operand, regT0);
+ Structure* structure = currentInstruction[3].u.objectAllocationProfile->structure();
+ size_t allocationSize = JSObject::allocationSize(structure->inlineCapacity());
+ MarkedAllocator* allocator = &m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize);
+
+ RegisterID resultReg = regT0;
+ RegisterID allocatorReg = regT1;
+ RegisterID scratchReg = regT2;
+
+ move(TrustedImmPtr(allocator), allocatorReg);
+ emitAllocateJSObject(allocatorReg, TrustedImmPtr(structure), resultReg, scratchReg);
+ emitStoreCell(currentInstruction[1].u.operand, resultReg);
}
void JIT::emitSlow_op_new_object(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
- JITStubCall(this, cti_op_new_object).call(currentInstruction[1].u.operand);
+ JITStubCall stubCall(this, cti_op_new_object);
+ stubCall.addArgument(TrustedImmPtr(currentInstruction[3].u.objectAllocationProfile->structure()));
+ stubCall.call(currentInstruction[1].u.operand);
}
void JIT::emit_op_check_has_instance(Instruction* currentInstruction)
@@ -727,7 +419,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump isImm = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
isImm.link(this);
if (dst != src)
@@ -754,14 +446,6 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
stubCall.call(currentInstruction[1].u.operand);
}
-void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_ensure_property_exists);
- stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
- stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_not(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
@@ -951,8 +635,8 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+ genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
// String case.
JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -999,8 +683,8 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+ genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
// String case.
JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1036,8 +720,8 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
// Jump to a slow case if both are strings.
Jump notCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get()));
- addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get()));
+ addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
notCell.link(this);
firstNotString.link(this);
@@ -1100,8 +784,8 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
- Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
move(TrustedImm32(0), regT1);
Jump wasNotMasqueradesAsUndefined = jump();
@@ -1131,8 +815,8 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump isImmediate = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
- Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ Jump isMasqueradesAsUndefined = branchTest8(NonZero, Address(regT2, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined));
move(TrustedImm32(1), regT1);
Jump wasNotMasqueradesAsUndefined = jump();
@@ -1287,7 +971,7 @@ void JIT::emit_op_pop_scope(Instruction*)
JITStubCall(this, cti_op_pop_scope).call();
}
-void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
+void JIT::emit_op_to_number(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
int src = currentInstruction[2].u.operand;
@@ -1295,21 +979,21 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump isInt32 = branch32(Equal, regT1, TrustedImm32(JSValue::Int32Tag));
- addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)));
+ addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
isInt32.link(this);
if (src != dst)
emitStore(dst, regT1, regT0);
- map(m_bytecodeOffset + OPCODE_LENGTH(op_to_jsnumber), dst, regT1, regT0);
+ map(m_bytecodeOffset + OPCODE_LENGTH(op_to_number), dst, regT1, regT0);
}
-void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
int dst = currentInstruction[1].u.operand;
linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_to_jsnumber);
+ JITStubCall stubCall(this, cti_op_to_number);
stubCall.addArgument(regT1, regT0);
stubCall.call(dst);
}
@@ -1329,25 +1013,17 @@ void JIT::emit_op_catch(Instruction* currentInstruction)
move(regT0, callFrameRegister);
// Now store the exception returned by cti_op_throw.
- loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(struct JITStackFrame, globalData)), regT3);
- load32(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
- load32(Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
- store32(TrustedImm32(JSValue().payload()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- store32(TrustedImm32(JSValue().tag()), Address(regT3, OBJECT_OFFSETOF(JSGlobalData, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+ loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(struct JITStackFrame, vm)), regT3);
+ load32(Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0);
+ load32(Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1);
+ store32(TrustedImm32(JSValue().payload()), Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+ store32(TrustedImm32(JSValue().tag()), Address(regT3, OBJECT_OFFSETOF(VM, exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
unsigned exception = currentInstruction[1].u.operand;
emitStore(exception, regT1, regT0);
map(m_bytecodeOffset + OPCODE_LENGTH(op_catch), exception, regT1, regT0);
}
-void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_jmp_scopes);
- stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
- stubCall.call();
- addJump(jump(), currentInstruction[2].u.operand);
-}
-
void JIT::emit_op_switch_imm(Instruction* currentInstruction)
{
unsigned tableIndex = currentInstruction[1].u.operand;
@@ -1429,7 +1105,7 @@ void JIT::emit_op_debug(Instruction* currentInstruction)
void JIT::emit_op_enter(Instruction*)
{
- emitOptimizationCheck(EnterOptimizationCheck);
+ emitEnterOptimizationCheck();
// Even though JIT code doesn't use them, we initialize our constant
// registers to zap stale pointers, to avoid unnecessarily prolonging
@@ -1479,22 +1155,28 @@ void JIT::emit_op_get_callee(Instruction* currentInstruction)
void JIT::emit_op_create_this(Instruction* currentInstruction)
{
int callee = currentInstruction[2].u.operand;
- emitLoadPayload(callee, regT0);
- loadPtr(Address(regT0, JSFunction::offsetOfCachedInheritorID()), regT2);
- addSlowCase(branchTestPtr(Zero, regT2));
-
- // now regT2 contains the inheritorID, which is the structure that the newly
- // allocated object will have.
-
- emitAllocateJSFinalObject(regT2, regT0, regT1);
- emitStoreCell(currentInstruction[1].u.operand, regT0);
+ RegisterID calleeReg = regT0;
+ RegisterID resultReg = regT0;
+ RegisterID allocatorReg = regT1;
+ RegisterID structureReg = regT2;
+ RegisterID scratchReg = regT3;
+
+ emitLoadPayload(callee, calleeReg);
+ loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()), allocatorReg);
+ loadPtr(Address(calleeReg, JSFunction::offsetOfAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureReg);
+ addSlowCase(branchTestPtr(Zero, allocatorReg));
+
+ emitAllocateJSObject(allocatorReg, structureReg, resultReg, scratchReg);
+ emitStoreCell(currentInstruction[1].u.operand, resultReg);
}
void JIT::emitSlow_op_create_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- linkSlowCase(iter); // doesn't have an inheritor ID
+ linkSlowCase(iter); // doesn't have an allocation profile
linkSlowCase(iter); // allocation failed
+
JITStubCall stubCall(this, cti_op_create_this);
+ stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1510,7 +1192,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
move(regT3, regT1);
emitValueProfilingSite();
}
- addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
}
void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -1533,7 +1215,7 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC
linkSlowCase(iter);
if (shouldEmitProfiling()) {
move(TrustedImm32(JSValue::CellTag), regT1);
- move(TrustedImmPtr(m_globalData->stringStructure.get()), regT0);
+ move(TrustedImmPtr(m_vm->stringStructure.get()), regT0);
}
isNotUndefined.link(this);
emitValueProfilingSite();
@@ -1627,7 +1309,7 @@ void JIT::emit_op_put_to_base(Instruction* currentInstruction)
int id = currentInstruction[2].u.operand;
int value = currentInstruction[3].u.operand;
- PutToBaseOperation* operation = m_codeBlock->putToBaseOperation(currentInstruction[4].u.operand);
+ PutToBaseOperation* operation = currentInstruction[4].u.putToBaseOperation;
switch (operation->m_kind) {
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index e377c8adb..2d1b2929d 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -53,11 +53,11 @@ using namespace std;
namespace JSC {
#if USE(JSVALUE64)
-JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
+JIT::CodeRef JIT::stringGetByValStubGenerator(VM* vm)
{
JSInterfaceJIT jit;
JumpList failures;
- failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get())));
+ failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(vm->stringStructure.get())));
// Load string length to regT2, and start the process of loading the data pointer into regT0
jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2);
@@ -71,9 +71,9 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
JumpList is16Bit;
JumpList cont8Bit;
// Load the string flags
- jit.loadPtr(Address(regT0, ThunkHelpers::stringImplFlagsOffset()), regT2);
- jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
- is16Bit.append(jit.branchTest32(Zero, regT2, TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ jit.loadPtr(Address(regT0, StringImpl::flagsOffset()), regT2);
+ jit.loadPtr(Address(regT0, StringImpl::dataOffset()), regT0);
+ is16Bit.append(jit.branchTest32(Zero, regT2, TrustedImm32(StringImpl::flagIs8Bit())));
jit.load8(BaseIndex(regT0, regT1, TimesOne, 0), regT0);
cont8Bit.append(jit.jump());
is16Bit.link(&jit);
@@ -81,7 +81,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
cont8Bit.link(&jit);
failures.append(jit.branch32(AboveOrEqual, regT0, TrustedImm32(0x100)));
- jit.move(TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
+ jit.move(TrustedImmPtr(vm->smallStrings.singleCharacterStrings()), regT1);
jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
jit.ret();
@@ -89,7 +89,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
jit.move(TrustedImm32(0), regT0);
jit.ret();
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(patchBuffer, ("String get_by_val stub"));
}
@@ -204,13 +204,14 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
unsigned dst = currentInstruction[1].u.operand;
unsigned base = currentInstruction[2].u.operand;
unsigned property = currentInstruction[3].u.operand;
+ ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
linkSlowCase(iter); // property int32 check
linkSlowCaseIfNotJSCell(iter, base); // base cell check
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get()));
- emitNakedCall(CodeLocationLabel(m_globalData->getCTIStub(stringGetByValStubGenerator).code()));
+ Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get()));
+ emitNakedCall(CodeLocationLabel(m_vm->getCTIStub(stringGetByValStubGenerator).code()));
Jump failed = branchTest64(Zero, regT0);
emitPutVirtualRegister(dst, regT0);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
@@ -218,9 +219,15 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
notString.link(this);
nonCell.link(this);
+ Jump skipProfiling = jump();
+
linkSlowCase(iter); // vector length check
linkSlowCase(iter); // empty value
+ emitArrayProfileOutOfBoundsSpecialCase(profile);
+
+ skipProfiling.link(this);
+
Label slowPath = label();
JITStubCall stubCall(this, cti_op_get_by_val);
@@ -451,7 +458,6 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
linkSlowCase(iter); // property int32 check
linkSlowCaseIfNotJSCell(iter, base); // base cell check
linkSlowCase(iter); // base not array check
- linkSlowCase(iter); // out of bounds
JITArrayMode mode = chooseArrayMode(profile);
switch (mode) {
@@ -463,6 +469,11 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
break;
}
+ Jump skipProfiling = jump();
+ linkSlowCase(iter); // out of bounds
+ emitArrayProfileOutOfBoundsSpecialCase(profile);
+ skipProfiling.link(this);
+
Label slowPath = label();
JITStubCall stubPutByValCall(this, cti_op_put_by_val);
@@ -524,7 +535,7 @@ void JIT::compileGetByIdHotPath(int baseVReg, Identifier* ident)
emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
- if (*ident == m_globalData->propertyNames->length && canBeOptimized()) {
+ if (*ident == m_vm->propertyNames->length && shouldEmitProfiling()) {
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
emitArrayProfilingSiteForBytecodeIndex(regT1, regT2, m_bytecodeOffset);
}
@@ -694,7 +705,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
// If we succeed in all of our checks, and the code was optimizable, then make sure we
// decrement the rare case counter.
#if ENABLE(VALUE_PROFILER)
- if (m_codeBlock->canCompileWithDFG() >= DFG::ShouldProfile) {
+ if (m_codeBlock->canCompileWithDFG() >= DFG::MayInline) {
sub32(
TrustedImm32(1),
AbsoluteAddress(&m_codeBlock->rareCaseProfileForBytecodeOffset(stubInfo->bytecodeIndex)->m_counter));
@@ -735,7 +746,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
restoreArgumentReferenceForTrampoline();
Call failureCall = tailRecursiveCall();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail));
@@ -749,7 +760,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
patchBuffer,
("Baseline put_by_id transition for %s, return point %p",
toCString(*m_codeBlock).data(), returnAddress.value())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
willNeedStorageRealloc,
newStructure);
@@ -802,7 +813,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
emitFastArithIntToImmNoCheck(regT2, regT0);
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
// Use the patch information to link the failure cases back to the original slow case routine.
CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
@@ -864,7 +875,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
} else
compileGetDirectOffset(protoObject, regT0, cachedOffset);
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
// Use the patch information to link the failure cases back to the original slow case routine.
CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
@@ -888,7 +899,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
("Baseline JIT get_by_id proto stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
@@ -928,7 +939,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
}
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
@@ -953,11 +964,11 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
("Baseline JIT get_by_id list stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
- polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, isDirect);
+ polymorphicStructures->list[currentIndex].set(*m_vm, m_codeBlock->ownerExecutable(), stubCode, structure, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -1003,7 +1014,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
@@ -1027,10 +1038,10 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
("Baseline JIT get_by_id proto list stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
- prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure, isDirect);
+ prototypeStructures->list[currentIndex].set(*m_vm, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -1081,7 +1092,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
}
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
@@ -1104,12 +1115,12 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
("Baseline JIT get_by_id chain list stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
// Track the stub we have created so that it will be deleted later.
- prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);
+ prototypeStructures->list[currentIndex].set(callFrame->vm(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -1157,7 +1168,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
compileGetDirectOffset(protoObject, regT0, cachedOffset);
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
@@ -1179,7 +1190,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
("Baseline JIT get_by_id chain stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
stubInfo->stubRoutine = stubRoutine;
@@ -1193,6 +1204,54 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
}
+void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
+{
+ int skip = currentInstruction[3].u.operand;
+
+ emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT0);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
+ activationNotCreated.link(this);
+ }
+ while (skip--)
+ loadPtr(Address(regT0, JSScope::offsetOfNext()), regT0);
+
+ loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0);
+ loadPtr(Address(regT0, currentInstruction[2].u.operand * sizeof(Register)), regT0);
+ emitValueProfilingSite();
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
+{
+ int skip = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+
+ emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT1, JSScope::offsetOfNext()), regT1);
+ activationNotCreated.link(this);
+ }
+ while (skip--)
+ loadPtr(Address(regT1, JSScope::offsetOfNext()), regT1);
+
+ emitWriteBarrier(regT1, regT0, regT2, regT3, ShouldFilterImmediates, WriteBarrierForVariableAccess);
+
+ loadPtr(Address(regT1, JSVariableObject::offsetOfRegisters()), regT1);
+ storePtr(regT0, Address(regT1, currentInstruction[1].u.operand * sizeof(Register)));
+}
+
void JIT::emit_op_init_global_const(Instruction* currentInstruction)
{
JSGlobalObject* globalObject = m_codeBlock->globalObject();
@@ -1230,7 +1289,7 @@ void JIT::emitSlow_op_init_global_const_check(Instruction* currentInstruction, V
void JIT::resetPatchGetById(RepatchBuffer& repatchBuffer, StructureStubInfo* stubInfo)
{
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_get_by_id);
- repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.get.structureToCompare), reinterpret_cast<void*>(-1));
+ repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.get.structureToCompare), reinterpret_cast<void*>(unusedPointer));
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel), 0);
repatchBuffer.relink(stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck), stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin));
}
@@ -1241,7 +1300,7 @@ void JIT::resetPatchPutById(RepatchBuffer& repatchBuffer, StructureStubInfo* stu
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id_direct);
else
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id);
- repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.put.structureToCompare), reinterpret_cast<void*>(-1));
+ repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.put.structureToCompare), reinterpret_cast<void*>(unusedPointer));
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel), 0);
}
@@ -1261,26 +1320,6 @@ void JIT::emitWriteBarrier(RegisterID owner, RegisterID value, RegisterID scratc
#if ENABLE(WRITE_BARRIER_PROFILING)
emitCount(WriteBarrierCounters::jitCounterFor(useKind));
#endif
-
-#if ENABLE(GGC)
- Jump filterCells;
- if (mode == ShouldFilterImmediates)
- filterCells = emitJumpIfNotJSCell(value);
- move(owner, scratch);
- andPtr(TrustedImm32(static_cast<int32_t>(MarkedBlock::blockMask)), scratch);
- move(owner, scratch2);
- // consume additional 8 bits as we're using an approximate filter
- rshift32(TrustedImm32(MarkedBlock::atomShift + 8), scratch2);
- andPtr(TrustedImm32(MarkedBlock::atomMask >> 8), scratch2);
- Jump filter = branchTest8(Zero, BaseIndex(scratch, scratch2, TimesOne, MarkedBlock::offsetOfMarks()));
- move(owner, scratch2);
- rshift32(TrustedImm32(MarkedBlock::cardShift), scratch2);
- andPtr(TrustedImm32(MarkedBlock::cardMask), scratch2);
- store8(TrustedImm32(1), BaseIndex(scratch, scratch2, TimesOne, MarkedBlock::offsetOfCards()));
- filter.link(this);
- if (mode == ShouldFilterImmediates)
- filterCells.link(this);
-#endif
}
void JIT::emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode mode, WriteBarrierUseKind useKind)
@@ -1294,17 +1333,6 @@ void JIT::emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch,
#if ENABLE(WRITE_BARRIER_PROFILING)
emitCount(WriteBarrierCounters::jitCounterFor(useKind));
#endif
-
-#if ENABLE(GGC)
- Jump filterCells;
- if (mode == ShouldFilterImmediates)
- filterCells = emitJumpIfNotJSCell(value);
- uint8_t* cardAddress = Heap::addressOfCardFor(owner);
- move(TrustedImmPtr(cardAddress), scratch);
- store8(TrustedImm32(1), Address(scratch));
- if (mode == ShouldFilterImmediates)
- filterCells.link(this);
-#endif
}
JIT::Jump JIT::addStructureTransitionCheck(JSCell* object, Structure* structure, StructureStubInfo* stubInfo, RegisterID scratch)
@@ -1363,7 +1391,7 @@ bool JIT::isDirectPutById(StructureStubInfo* stubInfo)
return false;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
@@ -1389,31 +1417,31 @@ void JIT::privateCompileGetByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd
slowCases = emitArrayStorageGetByVal(currentInstruction, badType);
break;
case JITInt8Array:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->int8ArrayDescriptor(), 1, SignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->int8ArrayDescriptor(), 1, SignedTypedArray);
break;
case JITInt16Array:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->int16ArrayDescriptor(), 2, SignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->int16ArrayDescriptor(), 2, SignedTypedArray);
break;
case JITInt32Array:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->int32ArrayDescriptor(), 4, SignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->int32ArrayDescriptor(), 4, SignedTypedArray);
break;
case JITUint8Array:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint8ArrayDescriptor(), 1, UnsignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->uint8ArrayDescriptor(), 1, UnsignedTypedArray);
break;
case JITUint8ClampedArray:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint8ClampedArrayDescriptor(), 1, UnsignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->uint8ClampedArrayDescriptor(), 1, UnsignedTypedArray);
break;
case JITUint16Array:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint16ArrayDescriptor(), 2, UnsignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->uint16ArrayDescriptor(), 2, UnsignedTypedArray);
break;
case JITUint32Array:
- slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint32ArrayDescriptor(), 4, UnsignedTypedArray);
+ slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_vm->uint32ArrayDescriptor(), 4, UnsignedTypedArray);
break;
case JITFloat32Array:
- slowCases = emitFloatTypedArrayGetByVal(currentInstruction, badType, m_globalData->float32ArrayDescriptor(), 4);
+ slowCases = emitFloatTypedArrayGetByVal(currentInstruction, badType, m_vm->float32ArrayDescriptor(), 4);
break;
case JITFloat64Array:
- slowCases = emitFloatTypedArrayGetByVal(currentInstruction, badType, m_globalData->float64ArrayDescriptor(), 8);
+ slowCases = emitFloatTypedArrayGetByVal(currentInstruction, badType, m_vm->float64ArrayDescriptor(), 8);
break;
default:
CRASH();
@@ -1421,7 +1449,7 @@ void JIT::privateCompileGetByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd
Jump done = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
@@ -1458,31 +1486,31 @@ void JIT::privateCompilePutByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd
slowCases = emitArrayStoragePutByVal(currentInstruction, badType);
break;
case JITInt8Array:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->int8ArrayDescriptor(), 1, SignedTypedArray, TruncateRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->int8ArrayDescriptor(), 1, SignedTypedArray, TruncateRounding);
break;
case JITInt16Array:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->int16ArrayDescriptor(), 2, SignedTypedArray, TruncateRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->int16ArrayDescriptor(), 2, SignedTypedArray, TruncateRounding);
break;
case JITInt32Array:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->int32ArrayDescriptor(), 4, SignedTypedArray, TruncateRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->int32ArrayDescriptor(), 4, SignedTypedArray, TruncateRounding);
break;
case JITUint8Array:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint8ArrayDescriptor(), 1, UnsignedTypedArray, TruncateRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->uint8ArrayDescriptor(), 1, UnsignedTypedArray, TruncateRounding);
break;
case JITUint8ClampedArray:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint8ClampedArrayDescriptor(), 1, UnsignedTypedArray, ClampRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->uint8ClampedArrayDescriptor(), 1, UnsignedTypedArray, ClampRounding);
break;
case JITUint16Array:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint16ArrayDescriptor(), 2, UnsignedTypedArray, TruncateRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->uint16ArrayDescriptor(), 2, UnsignedTypedArray, TruncateRounding);
break;
case JITUint32Array:
- slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint32ArrayDescriptor(), 4, UnsignedTypedArray, TruncateRounding);
+ slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_vm->uint32ArrayDescriptor(), 4, UnsignedTypedArray, TruncateRounding);
break;
case JITFloat32Array:
- slowCases = emitFloatTypedArrayPutByVal(currentInstruction, badType, m_globalData->float32ArrayDescriptor(), 4);
+ slowCases = emitFloatTypedArrayPutByVal(currentInstruction, badType, m_vm->float32ArrayDescriptor(), 4);
break;
case JITFloat64Array:
- slowCases = emitFloatTypedArrayPutByVal(currentInstruction, badType, m_globalData->float64ArrayDescriptor(), 8);
+ slowCases = emitFloatTypedArrayPutByVal(currentInstruction, badType, m_vm->float64ArrayDescriptor(), 8);
break;
default:
CRASH();
@@ -1491,7 +1519,7 @@ void JIT::privateCompilePutByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAd
Jump done = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath));
@@ -1608,16 +1636,17 @@ JIT::JumpList JIT::emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badT
break;
case 8: {
loadDouble(BaseIndex(base, property, TimesEight), fpRegT0);
- Jump notNaN = branchDouble(DoubleEqual, fpRegT0, fpRegT0);
- static const double NaN = QNaN;
- loadDouble(&NaN, fpRegT0);
- notNaN.link(this);
break;
}
default:
CRASH();
}
+ Jump notNaN = branchDouble(DoubleEqual, fpRegT0, fpRegT0);
+ static const double NaN = QNaN;
+ loadDouble(&NaN, fpRegT0);
+ notNaN.link(this);
+
#if USE(JSVALUE64)
moveDoubleTo64(fpRegT0, resultPayload);
sub64(tagTypeNumberRegister, resultPayload);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 391dd1d8c..1cc98ef66 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -92,11 +92,11 @@ void JIT::emit_op_del_by_id(Instruction* currentInstruction)
stubCall.call(dst);
}
-JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
+JIT::CodeRef JIT::stringGetByValStubGenerator(VM* vm)
{
JSInterfaceJIT jit;
JumpList failures;
- failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get())));
+ failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(vm->stringStructure.get())));
// Load string length to regT1, and start the process of loading the data pointer into regT0
jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
@@ -110,9 +110,9 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
JumpList is16Bit;
JumpList cont8Bit;
// Load the string flags
- jit.loadPtr(Address(regT0, ThunkHelpers::stringImplFlagsOffset()), regT1);
- jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
- is16Bit.append(jit.branchTest32(Zero, regT1, TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ jit.loadPtr(Address(regT0, StringImpl::flagsOffset()), regT1);
+ jit.loadPtr(Address(regT0, StringImpl::dataOffset()), regT0);
+ is16Bit.append(jit.branchTest32(Zero, regT1, TrustedImm32(StringImpl::flagIs8Bit())));
jit.load8(BaseIndex(regT0, regT2, TimesOne, 0), regT0);
cont8Bit.append(jit.jump());
is16Bit.link(&jit);
@@ -121,7 +121,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
cont8Bit.link(&jit);
failures.append(jit.branch32(AboveOrEqual, regT0, TrustedImm32(0x100)));
- jit.move(TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
+ jit.move(TrustedImmPtr(vm->smallStrings.singleCharacterStrings()), regT1);
jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
jit.move(TrustedImm32(JSValue::CellTag), regT1); // We null check regT0 on return so this is safe
jit.ret();
@@ -130,7 +130,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
jit.move(TrustedImm32(0), regT0);
jit.ret();
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(patchBuffer, ("String get_by_val stub"));
}
@@ -242,24 +242,31 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
unsigned dst = currentInstruction[1].u.operand;
unsigned base = currentInstruction[2].u.operand;
unsigned property = currentInstruction[3].u.operand;
+ ArrayProfile* profile = currentInstruction[4].u.arrayProfile;
linkSlowCase(iter); // property int32 check
linkSlowCaseIfNotJSCell(iter, base); // base cell check
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get()));
- emitNakedCall(m_globalData->getCTIStub(stringGetByValStubGenerator).code());
+ Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get()));
+ emitNakedCall(m_vm->getCTIStub(stringGetByValStubGenerator).code());
Jump failed = branchTestPtr(Zero, regT0);
emitStore(dst, regT1, regT0);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
failed.link(this);
notString.link(this);
nonCell.link(this);
+
+ Jump skipProfiling = jump();
linkSlowCase(iter); // vector length check
linkSlowCase(iter); // empty value
+ emitArrayProfileOutOfBoundsSpecialCase(profile);
+
+ skipProfiling.link(this);
+
Label slowPath = label();
JITStubCall stubCall(this, cti_op_get_by_val);
@@ -420,7 +427,6 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
linkSlowCase(iter); // property int32 check
linkSlowCaseIfNotJSCell(iter, base); // base cell check
linkSlowCase(iter); // base not array check
- linkSlowCase(iter); // out of bounds
JITArrayMode mode = chooseArrayMode(profile);
switch (mode) {
@@ -432,6 +438,11 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
break;
}
+ Jump skipProfiling = jump();
+ linkSlowCase(iter); // out of bounds
+ emitArrayProfileOutOfBoundsSpecialCase(profile);
+ skipProfiling.link(this);
+
Label slowPath = label();
JITStubCall stubPutByValCall(this, cti_op_put_by_val);
@@ -466,7 +477,7 @@ void JIT::compileGetByIdHotPath(Identifier* ident)
// to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
// to jump back to if one of these trampolies finds a match.
- if (*ident == m_globalData->propertyNames->length && canBeOptimized()) {
+ if (*ident == m_vm->propertyNames->length && shouldEmitProfiling()) {
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
emitArrayProfilingSiteForBytecodeIndex(regT2, regT3, m_bytecodeOffset);
}
@@ -637,7 +648,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
// If we succeed in all of our checks, and the code was optimizable, then make sure we
// decrement the rare case counter.
#if ENABLE(VALUE_PROFILER)
- if (m_codeBlock->canCompileWithDFG() >= DFG::ShouldProfile) {
+ if (m_codeBlock->canCompileWithDFG() >= DFG::MayInline) {
sub32(
TrustedImm32(1),
AbsoluteAddress(&m_codeBlock->rareCaseProfileForBytecodeOffset(stubInfo->bytecodeIndex)->m_counter));
@@ -693,7 +704,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
restoreArgumentReferenceForTrampoline();
Call failureCall = tailRecursiveCall();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail));
@@ -707,7 +718,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
patchBuffer,
("Baseline put_by_id transition stub for %s, return point %p",
toCString(*m_codeBlock).data(), returnAddress.value())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
willNeedStorageRealloc,
newStructure);
@@ -765,7 +776,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
move(TrustedImm32(JSValue::Int32Tag), regT1);
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
// Use the patch information to link the failure cases back to the original slow case routine.
CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
@@ -828,7 +839,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
// Use the patch information to link the failure cases back to the original slow case routine.
CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin);
@@ -853,7 +864,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
("Baseline get_by_id proto stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
@@ -896,7 +907,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
if (iter->to)
@@ -919,11 +930,11 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
("Baseline get_by_id self list stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
- polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
+ polymorphicStructures->list[currentIndex].set(*m_vm, m_codeBlock->ownerExecutable(), stubRoutine, structure, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -970,7 +981,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
if (iter->to)
@@ -992,11 +1003,11 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
("Baseline get_by_id proto list stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
- prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure, isDirect);
+ prototypeStructures->list[currentIndex].set(callFrame->vm(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -1049,7 +1060,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
if (iter->to)
@@ -1070,12 +1081,12 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
("Baseline get_by_id chain list stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
// Track the stub we have created so that it will be deleted later.
- prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);
+ prototypeStructures->list[currentIndex].set(callFrame->vm(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect);
// Finally patch the jump to slow case back in the hot path to jump here instead.
CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck);
@@ -1124,7 +1135,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
Jump success = jump();
- LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+ LinkBuffer patchBuffer(*m_vm, this, m_codeBlock);
if (needsStubLink) {
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
if (iter->to)
@@ -1144,7 +1155,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
("Baseline get_by_id chain stub for %s, return point %p",
toCString(*m_codeBlock).data(), stubInfo->hotPathBegin.labelAtOffset(
stubInfo->patch.baseline.u.get.putResult).executableAddress())),
- *m_globalData,
+ *m_vm,
m_codeBlock->ownerExecutable(),
needsStubLink);
stubInfo->stubRoutine = stubRoutine;
@@ -1233,6 +1244,59 @@ void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowC
stubCall.call(dst);
}
+void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int index = currentInstruction[2].u.operand;
+ int skip = currentInstruction[3].u.operand;
+
+ emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), TrustedImm32(JSValue::EmptyValueTag));
+ loadPtr(Address(regT2, JSScope::offsetOfNext()), regT2);
+ activationNotCreated.link(this);
+ }
+ while (skip--)
+ loadPtr(Address(regT2, JSScope::offsetOfNext()), regT2);
+
+ loadPtr(Address(regT2, JSVariableObject::offsetOfRegisters()), regT2);
+
+ emitLoad(index, regT1, regT0, regT2);
+ emitValueProfilingSite();
+ emitStore(dst, regT1, regT0);
+ map(m_bytecodeOffset + OPCODE_LENGTH(op_get_scoped_var), dst, regT1, regT0);
+}
+
+void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
+{
+ int index = currentInstruction[1].u.operand;
+ int skip = currentInstruction[2].u.operand;
+ int value = currentInstruction[3].u.operand;
+
+ emitLoad(value, regT1, regT0);
+
+ emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), TrustedImm32(JSValue::EmptyValueTag));
+ loadPtr(Address(regT2, JSScope::offsetOfNext()), regT2);
+ activationNotCreated.link(this);
+ }
+ while (skip--)
+ loadPtr(Address(regT2, JSScope::offsetOfNext()), regT2);
+
+ loadPtr(Address(regT2, JSVariableObject::offsetOfRegisters()), regT3);
+ emitStore(index, regT1, regT0, regT3);
+ emitWriteBarrier(regT2, regT1, regT0, regT1, ShouldFilterImmediates, WriteBarrierForVariableAccess);
+}
+
void JIT::emit_op_init_global_const(Instruction* currentInstruction)
{
WriteBarrier<Unknown>* registerPointer = currentInstruction[1].u.registerPointer;
@@ -1287,7 +1351,7 @@ void JIT::emitSlow_op_init_global_const_check(Instruction* currentInstruction, V
void JIT::resetPatchGetById(RepatchBuffer& repatchBuffer, StructureStubInfo* stubInfo)
{
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_get_by_id);
- repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.get.structureToCompare), reinterpret_cast<void*>(-1));
+ repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.get.structureToCompare), reinterpret_cast<void*>(unusedPointer));
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel1), 0);
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelCompactAtOffset(stubInfo->patch.baseline.u.get.displacementLabel2), 0);
repatchBuffer.relink(stubInfo->hotPathBegin.jumpAtOffset(stubInfo->patch.baseline.u.get.structureCheck), stubInfo->callReturnLocation.labelAtOffset(-stubInfo->patch.baseline.u.get.coldPathBegin));
@@ -1299,7 +1363,7 @@ void JIT::resetPatchPutById(RepatchBuffer& repatchBuffer, StructureStubInfo* stu
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id_direct);
else
repatchBuffer.relink(stubInfo->callReturnLocation, cti_op_put_by_id);
- repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.put.structureToCompare), reinterpret_cast<void*>(-1));
+ repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(stubInfo->patch.baseline.u.put.structureToCompare), reinterpret_cast<void*>(unusedPointer));
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel1), 0);
repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(stubInfo->patch.baseline.u.put.displacementLabel2), 0);
}
diff --git a/Source/JavaScriptCore/jit/JITStubRoutine.cpp b/Source/JavaScriptCore/jit/JITStubRoutine.cpp
index 121836ce9..28543a8b8 100644
--- a/Source/JavaScriptCore/jit/JITStubRoutine.cpp
+++ b/Source/JavaScriptCore/jit/JITStubRoutine.cpp
@@ -38,7 +38,7 @@ JITStubRoutine::~JITStubRoutine() { }
void JITStubRoutine::observeZeroRefCount()
{
- ASSERT(!m_refCount);
+ RELEASE_ASSERT(!m_refCount);
delete this;
}
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 168769c12..e4a30aee2 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
* Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
*
@@ -56,17 +56,19 @@
#include "JSPropertyNameIterator.h"
#include "JSString.h"
#include "JSWithScope.h"
+#include "LegacyProfiler.h"
#include "NameInstance.h"
+#include "ObjectConstructor.h"
#include "ObjectPrototype.h"
#include "Operations.h"
#include "Parser.h"
-#include "Profiler.h"
#include "RegExpObject.h"
#include "RegExpPrototype.h"
#include "Register.h"
#include "RepatchBuffer.h"
#include "SamplingTool.h"
#include "Strong.h"
+#include "StructureRareDataInlines.h"
#include <wtf/StdLibExtras.h>
#include <stdarg.h>
#include <stdio.h>
@@ -97,6 +99,9 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
"pushl %edi" "\n"
"pushl %ebx" "\n"
"subl $0x3c, %esp" "\n"
+ "movw $0x02FF, %bx" "\n"
+ "movw %bx, 0(%esp)" "\n"
+ "fldcw 0(%esp)" "\n"
"movl 0x58(%esp), %edi" "\n"
"call *0x50(%esp)" "\n"
"addl $0x3c, %esp" "\n"
@@ -104,6 +109,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
"popl %edi" "\n"
"popl %esi" "\n"
"popl %ebp" "\n"
+ "ffree %st(1)" "\n"
"ret" "\n"
".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
HIDE_SYMBOL(ctiTrampolineEnd) "\n"
@@ -226,7 +232,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_
extern "C" {
- __declspec(naked) EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*)
+ __declspec(naked) EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*)
{
__asm {
push ebp;
@@ -287,9 +293,13 @@ extern "C" {
#define REGISTER_FILE_OFFSET 92
#define GLOBAL_DATA_OFFSET 108
#define STACK_LENGTH 112
+
#elif CPU(SH4)
#define SYMBOL_STRING(name) #name
-/* code (r4), JSStack* (r5), CallFrame* (r6), void* unused1 (r7), void* unused2(sp), JSGlobalData (sp)*/
+/* code (r4), JSStack* (r5), CallFrame* (r6), void* unused1 (r7), void* unused2(sp), VM (sp)*/
+
+#define THUNK_RETURN_ADDRESS_OFFSET 56
+#define SAVED_R8_OFFSET 60
asm volatile (
".text\n"
@@ -299,27 +309,31 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
"mov.l r7, @-r15" "\n"
"mov.l r6, @-r15" "\n"
"mov.l r5, @-r15" "\n"
- "mov.l r8, @-r15" "\n"
- "mov #127, r8" "\n"
"mov.l r14, @-r15" "\n"
"sts.l pr, @-r15" "\n"
"mov.l r13, @-r15" "\n"
"mov.l r11, @-r15" "\n"
"mov.l r10, @-r15" "\n"
- "add #-60, r15" "\n"
+ "mov.l r9, @-r15" "\n"
+ "mov.l r8, @-r15" "\n"
+ "add #-" STRINGIZE_VALUE_OF(SAVED_R8_OFFSET) ", r15" "\n"
"mov r6, r14" "\n"
"jsr @r4" "\n"
"nop" "\n"
- "add #60, r15" "\n"
+ "add #" STRINGIZE_VALUE_OF(SAVED_R8_OFFSET) ", r15" "\n"
+ "mov.l @r15+,r8" "\n"
+ "mov.l @r15+,r9" "\n"
"mov.l @r15+,r10" "\n"
"mov.l @r15+,r11" "\n"
"mov.l @r15+,r13" "\n"
"lds.l @r15+,pr" "\n"
"mov.l @r15+,r14" "\n"
- "mov.l @r15+,r8" "\n"
"add #12, r15" "\n"
"rts" "\n"
"nop" "\n"
+".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
+HIDE_SYMBOL(ctiTrampolineEnd) "\n"
+SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
);
asm volatile (
@@ -331,13 +345,14 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"mov.l @(r0,r12),r11" "\n"
"jsr @r11" "\n"
"nop" "\n"
- "add #60, r15" "\n"
+ "add #" STRINGIZE_VALUE_OF(SAVED_R8_OFFSET) ", r15" "\n"
+ "mov.l @r15+,r8" "\n"
+ "mov.l @r15+,r9" "\n"
"mov.l @r15+,r10" "\n"
"mov.l @r15+,r11" "\n"
"mov.l @r15+,r13" "\n"
"lds.l @r15+,pr" "\n"
"mov.l @r15+,r14" "\n"
- "mov.l @r15+,r8" "\n"
"add #12, r15" "\n"
"rts" "\n"
"nop" "\n"
@@ -349,13 +364,14 @@ asm volatile (
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
- "add #60, r15" "\n"
+ "add #" STRINGIZE_VALUE_OF(SAVED_R8_OFFSET) ", r15" "\n"
+ "mov.l @r15+,r8" "\n"
+ "mov.l @r15+,r9" "\n"
"mov.l @r15+,r10" "\n"
"mov.l @r15+,r11" "\n"
"mov.l @r15+,r13" "\n"
"lds.l @r15+,pr" "\n"
"mov.l @r15+,r14" "\n"
- "mov.l @r15+,r8" "\n"
"add #12, r15" "\n"
"rts" "\n"
"nop" "\n"
@@ -538,12 +554,11 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n"
"sw $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n"
#endif
"move $16,$6 # set callFrameRegister" "\n"
- "li $17,512 # set timeoutCheckRegister" "\n"
"move $25,$4 # move executableAddress to t9" "\n"
"sw $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store JSStack to current stack" "\n"
- "lw $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29) # load globalData from previous stack" "\n"
+ "lw $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29) # load vm from previous stack" "\n"
"jalr $25" "\n"
- "sw $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29) # store globalData to current stack" "\n"
+ "sw $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29) # store vm to current stack" "\n"
"lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
"lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
"lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
@@ -750,7 +765,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif COMPILER(RVCT) && CPU(ARM_THUMB2)
-__asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*)
+__asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*)
{
PRESERVE8
sub sp, sp, # FIRST_STACK_ARGUMENT
@@ -818,7 +833,7 @@ __asm void ctiOpThrowNotCaught()
#elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL)
-__asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*)
+__asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*)
{
ARM
stmdb sp!, {r1-r3}
@@ -860,19 +875,16 @@ __asm void ctiOpThrowNotCaught()
#endif
#if ENABLE(OPCODE_SAMPLING)
- #define CTI_SAMPLER stackFrame.globalData->interpreter->sampler()
+ #define CTI_SAMPLER stackFrame.vm->interpreter->sampler()
#else
#define CTI_SAMPLER 0
#endif
-JITThunks::JITThunks(JSGlobalData* globalData)
- : m_hostFunctionStubMap(adoptPtr(new HostFunctionStubMap))
+void performPlatformSpecificJITAssertions(VM* vm)
{
- if (!globalData->canUseJIT())
+ if (!vm->canUseJIT())
return;
- m_executableMemory = JIT::compileCTIMachineTrampolines(globalData, &m_trampolineStructure);
- ASSERT(!!m_executableMemory);
#if CPU(ARM_THUMB2)
// Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
// and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT
@@ -907,16 +919,15 @@ JITThunks::JITThunks(JSGlobalData* globalData)
ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, stack) == REGISTER_FILE_OFFSET);
- ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == GLOBAL_DATA_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, vm) == GLOBAL_DATA_OFFSET);
+#elif CPU(SH4)
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
+ ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, savedR8) == SAVED_R8_OFFSET);
#endif
}
-JITThunks::~JITThunks()
-{
-}
-
-NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct)
+NEVER_INLINE static void tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct)
{
// The interpreter checks for recursion here; I do not believe this can occur in CTI.
@@ -960,17 +971,17 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
- stubInfo->initPutByIdTransition(callFrame->globalData(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain, direct);
- JIT::compilePutByIdTransition(callFrame->scope()->globalData(), codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
+ stubInfo->initPutByIdTransition(callFrame->vm(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain, direct);
+ JIT::compilePutByIdTransition(callFrame->scope()->vm(), codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
return;
}
- stubInfo->initPutByIdReplace(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
+ stubInfo->initPutByIdReplace(callFrame->vm(), codeBlock->ownerExecutable(), structure);
JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct);
}
-NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
+NEVER_INLINE static void tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
{
// FIXME: Write a test that proves we need to check for recursion here just
// like the interpreter does, then add a check for recursion.
@@ -981,17 +992,17 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
return;
}
- JSGlobalData* globalData = &callFrame->globalData();
+ VM* vm = &callFrame->vm();
if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
- JIT::compilePatchGetArrayLength(callFrame->scope()->globalData(), codeBlock, returnAddress);
+ JIT::compilePatchGetArrayLength(callFrame->scope()->vm(), codeBlock, returnAddress);
return;
}
if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
// The tradeoff of compiling an patched inline string length access routine does not seem
// to pay off, so we currently only do this for arrays.
- ctiPatchCallByReturnAddress(codeBlock, returnAddress, globalData->jitStubs->ctiStringLengthTrampoline());
+ ctiPatchCallByReturnAddress(codeBlock, returnAddress, vm->getCTIStub(stringLengthTrampolineGenerator).code());
return;
}
@@ -1014,13 +1025,14 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
// Cache hit: Specialize instruction and ref Structures.
if (slot.slotBase() == baseValue) {
- // set this up, so derefStructures can do it's job.
- stubInfo->initGetByIdSelf(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
+ RELEASE_ASSERT(stubInfo->accessType == access_unset);
if ((slot.cachedPropertyType() != PropertySlot::Value)
- || !MacroAssembler::isCompactPtrAlignedAddressOffset(offsetRelativeToPatchedStorage(slot.cachedOffset())))
+ || !MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset())))
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
- else
+ else {
JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
+ stubInfo->initGetByIdSelf(callFrame->vm(), codeBlock->ownerExecutable(), structure);
+ }
return;
}
@@ -1045,15 +1057,15 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
if (slotBaseObject->structure()->isDictionary()) {
- slotBaseObject->flattenDictionaryObject(callFrame->globalData());
- offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName);
+ slotBaseObject->flattenDictionaryObject(callFrame->vm());
+ offset = slotBaseObject->structure()->get(callFrame->vm(), propertyName);
}
- stubInfo->initGetByIdProto(callFrame->globalData(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure(), slot.cachedPropertyType() == PropertySlot::Value);
+ stubInfo->initGetByIdProto(callFrame->vm(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure(), slot.cachedPropertyType() == PropertySlot::Value);
ASSERT(!structure->isDictionary());
ASSERT(!slotBaseObject->structure()->isDictionary());
- JIT::compileGetByIdProto(callFrame->scope()->globalData(), callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), propertyName, slot, offset, returnAddress);
+ JIT::compileGetByIdProto(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), propertyName, slot, offset, returnAddress);
return;
}
@@ -1066,8 +1078,8 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
}
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- stubInfo->initGetByIdChain(callFrame->globalData(), codeBlock->ownerExecutable(), structure, prototypeChain, count, slot.cachedPropertyType() == PropertySlot::Value);
- JIT::compileGetByIdChain(callFrame->scope()->globalData(), callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
+ stubInfo->initGetByIdChain(callFrame->vm(), codeBlock->ownerExecutable(), structure, prototypeChain, count, slot.cachedPropertyType() == PropertySlot::Value);
+ JIT::compileGetByIdChain(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
}
#if !defined(NDEBUG)
@@ -1117,10 +1129,10 @@ struct StackHack {
// to get the address of the ctiVMThrowTrampoline function. It's also
// good to keep the code size down by leaving as much of the exception
// handling code out of line as possible.
-static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
+static NEVER_INLINE void returnToThrowTrampoline(VM* vm, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
{
- ASSERT(globalData->exception);
- globalData->exceptionLocation = exceptionLocation;
+ RELEASE_ASSERT(vm->exception);
+ vm->exceptionLocation = exceptionLocation;
returnAddressSlot = ReturnAddressPtr(FunctionPtr(ctiVMThrowTrampoline));
}
@@ -1131,44 +1143,102 @@ static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, Retur
} while (0)
#define VM_THROW_EXCEPTION_AT_END() \
do {\
- returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
+ returnToThrowTrampoline(stackFrame.vm, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
} while (0)
#define CHECK_FOR_EXCEPTION() \
do { \
- if (UNLIKELY(stackFrame.globalData->exception)) \
+ if (UNLIKELY(stackFrame.vm->exception)) \
VM_THROW_EXCEPTION(); \
} while (0)
#define CHECK_FOR_EXCEPTION_AT_END() \
do { \
- if (UNLIKELY(stackFrame.globalData->exception)) \
+ if (UNLIKELY(stackFrame.vm->exception)) \
VM_THROW_EXCEPTION_AT_END(); \
} while (0)
#define CHECK_FOR_EXCEPTION_VOID() \
do { \
- if (UNLIKELY(stackFrame.globalData->exception)) { \
+ if (UNLIKELY(stackFrame.vm->exception)) { \
VM_THROW_EXCEPTION_AT_END(); \
return; \
} \
} while (0)
+class ErrorFunctor {
+public:
+ virtual ~ErrorFunctor() { }
+ virtual JSValue operator()(ExecState*) = 0;
+};
+
+class ErrorWithExecFunctor : public ErrorFunctor {
+public:
+ typedef JSObject* (*Factory)(ExecState* exec);
+
+ ErrorWithExecFunctor(Factory factory)
+ : m_factory(factory)
+ {
+ }
+ JSValue operator()(ExecState* exec)
+ {
+ return m_factory(exec);
+ }
+
+private:
+ Factory m_factory;
+};
+
+class ErrorWithExecAndCalleeFunctor : public ErrorFunctor {
+public:
+ typedef JSObject* (*Factory)(ExecState* exec, JSValue callee);
+
+ ErrorWithExecAndCalleeFunctor(Factory factory, JSValue callee)
+ : m_factory(factory), m_callee(callee)
+ {
+ }
+ JSValue operator()(ExecState* exec)
+ {
+ return m_factory(exec, m_callee);
+ }
+private:
+ Factory m_factory;
+ JSValue m_callee;
+};
+
+class ErrorWithExceptionFunctor : public ErrorFunctor {
+ public:
+ ErrorWithExceptionFunctor(JSValue exception)
+ : m_exception(exception)
+ {
+ }
+ JSValue operator()(ExecState*)
+ {
+ return m_exception;
+ }
+
+private:
+ JSValue m_exception;
+};
+
// Helper function for JIT stubs that may throw an exception in the middle of
// processing a function call. This function rolls back the stack to
// our caller, so exception processing can proceed from a valid state.
-template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot)
+template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, ErrorFunctor& createError )
{
CallFrame* callFrame = newCallFrame->callerFrame();
- ASSERT(callFrame->globalData().exception);
jitStackFrame.callFrame = callFrame;
- callFrame->globalData().topCallFrame = callFrame;
- returnToThrowTrampoline(&callFrame->globalData(), ReturnAddressPtr(newCallFrame->returnPC()), returnAddressSlot);
+ callFrame->vm().topCallFrame = callFrame;
+ callFrame->vm().exception = createError(callFrame);
+ ASSERT(callFrame->vm().exception);
+ returnToThrowTrampoline(&callFrame->vm(), ReturnAddressPtr(newCallFrame->returnPC()), returnAddressSlot);
return T();
}
-template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, JSValue exception)
+template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot)
{
- newCallFrame->callerFrame()->globalData().exception = exception;
- return throwExceptionFromOpCall<T>(jitStackFrame, newCallFrame, returnAddressSlot);
+ CallFrame* callFrame = newCallFrame->callerFrame();
+ ASSERT(callFrame->vm().exception);
+ ErrorWithExceptionFunctor functor = ErrorWithExceptionFunctor(callFrame->vm().exception);
+ return throwExceptionFromOpCall<T>(jitStackFrame, newCallFrame, returnAddressSlot, functor);
}
#if CPU(ARM_THUMB2) && COMPILER(GCC)
@@ -1362,12 +1432,12 @@ MSVC_END( END)
".globl " SYMBOL_STRING(cti_##op) "\n" \
SYMBOL_STRING(cti_##op) ":" "\n" \
"sts pr, r11" "\n" \
- "mov.l r11, @(0x38, r15)" "\n" \
+ "mov.l r11, @(" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) ", r15)" "\n" \
"mov.l .L2"SYMBOL_STRING(JITStubThunked_##op)",r0" "\n" \
"mov.l @(r0,r12),r11" "\n" \
"jsr @r11" "\n" \
"nop" "\n" \
- "mov.l @(0x38, r15), r11 " "\n" \
+ "mov.l @(" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) ", r15), r11 " "\n" \
"lds r11, pr " "\n" \
"rts" "\n" \
"nop" "\n" \
@@ -1383,6 +1453,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this)
{
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
+ size_t inlineCapacity = stackFrame.args[0].int32();
JSFunction* constructor = jsCast<JSFunction*>(callFrame->callee());
#if !ASSERT_DISABLED
@@ -1390,7 +1461,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this)
ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
#endif
- Structure* structure = constructor->cachedInheritorID(callFrame);
+ Structure* structure = constructor->allocationProfile(callFrame, inlineCapacity)->structure();
JSValue result = constructEmptyObject(callFrame, structure);
return JSValue::encode(result);
@@ -1433,7 +1504,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_inc)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -1445,22 +1516,16 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(int, timeout_check)
+DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)
{
STUB_INIT_STACK_FRAME(stackFrame);
-
- JSGlobalData* globalData = stackFrame.globalData;
- TimeoutChecker& timeoutChecker = globalData->timeoutChecker;
-
- if (globalData->terminator.shouldTerminate()) {
- globalData->exception = createTerminatedExecutionException(globalData);
- VM_THROW_EXCEPTION_AT_END();
- } else if (timeoutChecker.didTimeOut(stackFrame.callFrame)) {
- globalData->exception = createInterruptedExecutionException(globalData);
+ CallFrame* callFrame = stackFrame.callFrame;
+ VM* vm = stackFrame.vm;
+ if (UNLIKELY(vm->watchdog.didFire(callFrame))) {
+ vm->exception = createTerminatedExecutionException(vm);
VM_THROW_EXCEPTION_AT_END();
+ return;
}
-
- return timeoutChecker.ticksUntilNextCheck();
}
DEFINE_STUB_FUNCTION(void*, stack_check)
@@ -1468,8 +1533,10 @@ DEFINE_STUB_FUNCTION(void*, stack_check)
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
- if (UNLIKELY(!stackFrame.stack->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters])))
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
+ if (UNLIKELY(!stackFrame.stack->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) {
+ ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
+ return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ }
return callFrame;
}
@@ -1478,7 +1545,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_object)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return constructEmptyObject(stackFrame.callFrame);
+ return constructEmptyObject(stackFrame.callFrame, stackFrame.args[0].structure());
}
DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
@@ -1497,7 +1564,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
JSValue baseValue = stackFrame.args[0].jsValue();
ASSERT(baseValue.isObject());
- asObject(baseValue)->putDirect(stackFrame.callFrame->globalData(), stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
+ asObject(baseValue)->putDirect(stackFrame.callFrame->vm(), stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1530,10 +1597,8 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id)
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
- if (!stubInfo->seenOnce())
- stubInfo->setSeen();
- else
- JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
+ stubInfo->setSeen();
+ tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
}
CHECK_FOR_EXCEPTION_AT_END();
@@ -1553,13 +1618,11 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
JSValue baseValue = stackFrame.args[0].jsValue();
ASSERT(baseValue.isObject());
- asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
+ asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
- if (!stubInfo->seenOnce())
- stubInfo->setSeen();
- else
- JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
+ stubInfo->setSeen();
+ tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
}
CHECK_FOR_EXCEPTION_AT_END();
@@ -1588,7 +1651,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
JSValue baseValue = stackFrame.args[0].jsValue();
ASSERT(baseValue.isObject());
- asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
+ asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1607,9 +1670,9 @@ DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
ASSERT(baseValue.isObject());
JSObject* base = asObject(baseValue);
- JSGlobalData& globalData = *stackFrame.globalData;
- Butterfly* butterfly = base->growOutOfLineStorage(globalData, oldSize, newSize);
- base->setButterfly(globalData, butterfly, newStructure);
+ VM& vm = *stackFrame.vm;
+ Butterfly* butterfly = base->growOutOfLineStorage(vm, oldSize, newSize);
+ base->setButterfly(vm, butterfly, newStructure);
return base;
}
@@ -1634,7 +1697,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
if (!stubInfo->seenOnce())
stubInfo->setSeen();
else
- JITThunks::tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
+ tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
@@ -1670,9 +1733,12 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
PolymorphicAccessStructureList* polymorphicStructureList;
int listIndex = 1;
+ if (stubInfo->accessType == access_unset)
+ stubInfo->initGetByIdSelf(callFrame->vm(), codeBlock->ownerExecutable(), baseValue.asCell()->structure());
+
if (stubInfo->accessType == access_get_by_id_self) {
ASSERT(!stubInfo->stubRoutine);
- polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), 0, stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
+ polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->vm(), codeBlock->ownerExecutable(), 0, stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
} else {
polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
@@ -1680,7 +1746,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
}
if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
stubInfo->u.getByIdSelfList.listSize++;
- JIT::compileGetByIdSelfList(callFrame->scope()->globalData(), codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset());
+ JIT::compileGetByIdSelfList(callFrame->scope()->vm(), codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset());
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
@@ -1690,19 +1756,19 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
return JSValue::encode(result);
}
-static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSGlobalData& globalData, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(VM& vm, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
{
PolymorphicAccessStructureList* prototypeStructureList = 0;
listIndex = 1;
switch (stubInfo->accessType) {
case access_get_by_id_proto:
- prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true);
+ prototypeStructureList = new PolymorphicAccessStructureList(vm, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true);
stubInfo->stubRoutine.clear();
stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
break;
case access_get_by_id_chain:
- prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true);
+ prototypeStructureList = new PolymorphicAccessStructureList(vm, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true);
stubInfo->stubRoutine.clear();
stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
break;
@@ -1713,7 +1779,7 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSG
stubInfo->u.getByIdProtoList.listSize++;
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE);
@@ -1732,7 +1798,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
CallType callType = getter->methodTable()->getCallData(getter, callData);
JSValue result = call(callFrame, getter, callType, callData, stackFrame.args[1].jsObject(), ArgList());
if (callFrame->hadException())
- returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
+ returnToThrowTrampoline(&callFrame->vm(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1746,7 +1812,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_custom_stub)
const Identifier& ident = stackFrame.args[2].identifier();
JSValue result = getter(callFrame, slotBase, ident);
if (callFrame->hadException())
- returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
+ returnToThrowTrampoline(&callFrame->vm(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
@@ -1797,14 +1863,14 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
if (slotBaseObject->structure()->isDictionary()) {
- slotBaseObject->flattenDictionaryObject(callFrame->globalData());
- offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName);
+ slotBaseObject->flattenDictionaryObject(callFrame->vm());
+ offset = slotBaseObject->structure()->get(callFrame->vm(), propertyName);
}
int listIndex;
- PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->vm(), codeBlock->ownerExecutable(), stubInfo, listIndex);
if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
- JIT::compileGetByIdProtoList(callFrame->scope()->globalData(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
+ JIT::compileGetByIdProtoList(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
@@ -1818,11 +1884,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
ASSERT(!baseValue.asCell()->structure()->isDictionary());
int listIndex;
- PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->vm(), codeBlock->ownerExecutable(), stubInfo, listIndex);
if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
StructureChain* protoChain = structure->prototypeChain(callFrame);
- JIT::compileGetByIdChainList(callFrame->scope()->globalData(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
+ JIT::compileGetByIdChainList(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
@@ -1898,7 +1964,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_check_has_instance)
}
}
- stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal);
+ stackFrame.vm->exception = createInvalidParameterError(callFrame, "instanceof", baseVal);
VM_THROW_EXCEPTION_AT_END();
return JSValue::encode(JSValue());
}
@@ -1927,12 +1993,15 @@ DEFINE_STUB_FUNCTION(void, optimize)
if (!codeBlock->checkIfOptimizationThresholdReached()) {
codeBlock->updateAllPredictions();
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog("Choosing not to optimize ", *codeBlock, " yet.\n");
+#endif
return;
}
if (codeBlock->hasOptimizedReplacement()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
+ dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
#endif
// If we have an optimized replacement, then it must be the case that we entered
// cti_optimize from a loop. That's because is there's an optimized replacement,
@@ -1949,7 +2018,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
// additional checking anyway, to reduce the amount of recompilation thrashing.
if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Triggering reoptimization of ", *codeBlock, "(", *codeBlock->replacement(), ") (in loop).\n");
+ dataLog("Triggering reoptimization of ", *codeBlock, "(", *codeBlock->replacement(), ") (in loop).\n");
#endif
codeBlock->reoptimize();
return;
@@ -1957,23 +2026,27 @@ DEFINE_STUB_FUNCTION(void, optimize)
} else {
if (!codeBlock->shouldOptimizeNow()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Delaying optimization for ", *codeBlock, " (in loop) because of insufficient profiling.\n");
+ dataLog("Delaying optimization for ", *codeBlock, " (in loop) because of insufficient profiling.\n");
#endif
return;
}
+#if ENABLE(JIT_VERBOSE_OSR)
+ dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
+#endif
+
JSScope* scope = callFrame->scope();
JSObject* error = codeBlock->compileOptimized(callFrame, scope, bytecodeIndex);
#if ENABLE(JIT_VERBOSE_OSR)
if (error)
- dataLogF("WARNING: optimized compilation failed.\n");
+ dataLog("WARNING: optimized compilation failed.\n");
#else
UNUSED_PARAM(error);
#endif
if (codeBlock->replacement() == codeBlock) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Optimizing ", *codeBlock, " failed.\n");
+ dataLog("Optimizing ", *codeBlock, " failed.\n");
#endif
ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
@@ -1992,7 +2065,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
RawPointer((STUB_RETURN_ADDRESS).value()), " -> ", RawPointer(address), ".\n");
}
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Optimizing ", *codeBlock, " succeeded, performing OSR after a delay of ", codeBlock->optimizationDelayCounter(), ".\n");
+ dataLog("Optimizing ", *codeBlock, " succeeded, performing OSR after a delay of ", codeBlock->optimizationDelayCounter(), ".\n");
#endif
codeBlock->optimizeSoon();
@@ -2001,7 +2074,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
}
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Optimizing ", *codeBlock, " succeeded, OSR failed, after a delay of ", codeBlock->optimizationDelayCounter(), ".\n");
+ dataLog("Optimizing ", *codeBlock, " succeeded, OSR failed, after a delay of ", codeBlock->optimizationDelayCounter(), ".\n");
#endif
// Count the OSR failure as a speculation failure. If this happens a lot, then
@@ -2009,7 +2082,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
optimizedCodeBlock->countOSRExit();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Encountered OSR failure ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
+ dataLog("Encountered OSR failure ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
#endif
// We are a lot more conservative about triggering reoptimization after OSR failure than
@@ -2022,7 +2095,7 @@ DEFINE_STUB_FUNCTION(void, optimize)
// reoptimization trigger.
if (optimizedCodeBlock->shouldReoptimizeNow()) {
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("Triggering reoptimization of ", *codeBlock, " -> ", *codeBlock->replacement(), " (after OSR fail).\n");
+ dataLog("Triggering reoptimization of ", *codeBlock, " -> ", *codeBlock->replacement(), " (after OSR fail).\n");
#endif
codeBlock->reoptimize();
return;
@@ -2060,7 +2133,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
bool couldDelete = baseObj->methodTable()->deleteProperty(baseObj, callFrame, stackFrame.args[1].identifier());
JSValue result = jsBoolean(couldDelete);
if (!couldDelete && callFrame->codeBlock()->isStrictMode())
- stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+ stackFrame.vm->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
@@ -2116,7 +2189,7 @@ inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
if (!error)
return function;
- callFrame->globalData().exception = error;
+ callFrame->vm().exception = error;
return 0;
}
@@ -2161,9 +2234,10 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
CallFrame* callFrame = stackFrame.callFrame;
CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForCall);
- if (!newCallFrame)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
-
+ if (!newCallFrame) {
+ ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
+ return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ }
return newCallFrame;
}
@@ -2174,9 +2248,10 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
CallFrame* callFrame = stackFrame.callFrame;
CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForConstruct);
- if (!newCallFrame)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
-
+ if (!newCallFrame) {
+ ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
+ return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
+ }
return newCallFrame;
}
@@ -2211,7 +2286,7 @@ inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
- callFrame->globalData().exception = error;
+ callFrame->vm().exception = error;
return 0;
}
codeBlock = &functionExecutable->generatedBytecodeFor(kind);
@@ -2225,7 +2300,7 @@ inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
if (!callLinkInfo->seenOnce())
callLinkInfo->setSeen();
else
- JIT::linkFor(callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->globalData(), kind);
+ JIT::linkFor(callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->vm(), kind);
return codePtr.executableAddress();
}
@@ -2242,6 +2317,69 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
return result;
}
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkClosureCall)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ CallFrame* callFrame = stackFrame.callFrame;
+
+ CodeBlock* callerCodeBlock = callFrame->callerFrame()->codeBlock();
+ VM* vm = callerCodeBlock->vm();
+ CallLinkInfo* callLinkInfo = &callerCodeBlock->getCallLinkInfo(callFrame->returnPC());
+ JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
+ ExecutableBase* executable = callee->executable();
+ Structure* structure = callee->structure();
+
+ ASSERT(callLinkInfo->callType == CallLinkInfo::Call);
+ ASSERT(callLinkInfo->isLinked());
+ ASSERT(callLinkInfo->callee);
+ ASSERT(callee != callLinkInfo->callee.get());
+
+ bool shouldLink = false;
+ CodeBlock* calleeCodeBlock = 0;
+ MacroAssemblerCodePtr codePtr;
+
+ if (executable == callLinkInfo->callee.get()->executable()
+ && structure == callLinkInfo->callee.get()->structure()) {
+
+ shouldLink = true;
+
+ ASSERT(executable->hasJITCodeForCall());
+ codePtr = executable->generatedJITCodeForCall().addressForCall();
+ if (!callee->executable()->isHostFunction()) {
+ calleeCodeBlock = &jsCast<FunctionExecutable*>(executable)->generatedBytecodeForCall();
+ if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(calleeCodeBlock->numParameters())) {
+ shouldLink = false;
+ codePtr = executable->generatedJITCodeWithArityCheckFor(CodeForCall);
+ }
+ }
+ } else if (callee->isHostFunction())
+ codePtr = executable->generatedJITCodeForCall().addressForCall();
+ else {
+ // Need to clear the code block before compilation, because compilation can GC.
+ callFrame->setCodeBlock(0);
+
+ FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
+ JSScope* scopeChain = callee->scope();
+ JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
+ if (error) {
+ callFrame->vm().exception = error;
+ return 0;
+ }
+
+ codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(CodeForCall);
+ }
+
+ if (shouldLink) {
+ ASSERT(codePtr);
+ JIT::compileClosureCall(vm, callLinkInfo, callerCodeBlock, calleeCodeBlock, structure, executable, codePtr);
+ callLinkInfo->hasSeenClosure = true;
+ } else
+ JIT::linkSlowCall(callerCodeBlock, callLinkInfo);
+
+ return codePtr.executableAddress();
+}
+
DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2258,7 +2396,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
{
STUB_INIT_STACK_FRAME(stackFrame);
- JSActivation* activation = JSActivation::create(stackFrame.callFrame->globalData(), stackFrame.callFrame, stackFrame.callFrame->codeBlock());
+ JSActivation* activation = JSActivation::create(stackFrame.callFrame->vm(), stackFrame.callFrame, stackFrame.callFrame->codeBlock());
stackFrame.callFrame->setScope(activation);
return activation;
}
@@ -2277,7 +2415,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
ASSERT(callType != CallTypeJS);
if (callType != CallTypeHost) {
ASSERT(callType == CallTypeNone);
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createNotAFunctionError(callFrame->callerFrame(), callee));
+ ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
+ return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
}
EncodedJSValue returnValue;
@@ -2286,7 +2425,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
returnValue = callData.native.function(callFrame);
}
- if (stackFrame.globalData->exception)
+ if (stackFrame.vm->exception)
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return returnValue;
@@ -2296,7 +2435,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
{
STUB_INIT_STACK_FRAME(stackFrame);
- Arguments* arguments = Arguments::create(*stackFrame.globalData, stackFrame.callFrame);
+ Arguments* arguments = Arguments::create(*stackFrame.vm, stackFrame.callFrame);
return JSValue::encode(JSValue(arguments));
}
@@ -2305,7 +2444,7 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
STUB_INIT_STACK_FRAME(stackFrame);
ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
- jsCast<JSActivation*>(stackFrame.args[0].jsValue())->tearOff(*stackFrame.globalData);
+ jsCast<JSActivation*>(stackFrame.args[0].jsValue())->tearOff(*stackFrame.vm);
}
DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
@@ -2326,7 +2465,7 @@ DEFINE_STUB_FUNCTION(void, op_profile_will_call)
{
STUB_INIT_STACK_FRAME(stackFrame);
- if (Profiler* profiler = stackFrame.globalData->enabledProfiler())
+ if (LegacyProfiler* profiler = stackFrame.vm->enabledProfiler())
profiler->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
}
@@ -2334,7 +2473,7 @@ DEFINE_STUB_FUNCTION(void, op_profile_did_call)
{
STUB_INIT_STACK_FRAME(stackFrame);
- if (Profiler* profiler = stackFrame.globalData->enabledProfiler())
+ if (LegacyProfiler* profiler = stackFrame.vm->enabledProfiler())
profiler->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
}
@@ -2403,7 +2542,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
ASSERT(constructType != ConstructTypeJS);
if (constructType != ConstructTypeHost) {
ASSERT(constructType == ConstructTypeNone);
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createNotAConstructorError(callFrame->callerFrame(), callee));
+ ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
+ return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
}
EncodedJSValue returnValue;
@@ -2412,7 +2552,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
returnValue = constructData.native.function(callFrame);
}
- if (stackFrame.globalData->exception)
+ if (stackFrame.vm->exception)
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return returnValue;
@@ -2465,7 +2605,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
// Attempt to optimize.
JITArrayMode arrayMode = jitArrayModeForStructure(object->structure());
if (arrayMode != byValInfo.arrayMode) {
- JIT::compileGetByVal(&callFrame->globalData(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
+ JIT::compileGetByVal(&callFrame->vm(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
didOptimize = true;
}
}
@@ -2558,7 +2698,7 @@ static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript,
if (baseValue.isObject()) {
JSObject* object = asObject(baseValue);
if (object->canSetIndexQuickly(i))
- object->setIndexQuickly(callFrame->globalData(), i, value);
+ object->setIndexQuickly(callFrame->vm(), i, value);
else
object->methodTable()->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
} else
@@ -2568,7 +2708,7 @@ static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript,
baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
} else {
Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- if (!callFrame->globalData().exception) { // Don't put to an object if toString threw an exception.
+ if (!callFrame->vm().exception) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
@@ -2599,7 +2739,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
// Attempt to optimize.
JITArrayMode arrayMode = jitArrayModeForStructure(object->structure());
if (arrayMode != byValInfo.arrayMode) {
- JIT::compilePutByVal(&callFrame->globalData(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
+ JIT::compilePutByVal(&callFrame->vm(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
didOptimize = true;
}
}
@@ -2726,21 +2866,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
VM_THROW_EXCEPTION();
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_ensure_property_exists)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
- JSValue base = stackFrame.callFrame->r(stackFrame.args[0].int32()).jsValue();
- JSObject* object = asObject(base);
- PropertySlot slot(object);
- ASSERT(stackFrame.callFrame->codeBlock()->isStrictMode());
- if (!object->getPropertySlot(stackFrame.callFrame, stackFrame.args[1].identifier(), slot)) {
- stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[1].identifier().string());
- VM_THROW_EXCEPTION();
- }
-
- return JSValue::encode(base);
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2757,7 +2882,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_dec)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2843,21 +2968,6 @@ DEFINE_STUB_FUNCTION(int, op_jtrue)
return result;
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = v.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
-
- callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number + 1);
- return JSValue::encode(jsNumber(number));
-}
-
DEFINE_STUB_FUNCTION(int, op_eq)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2969,7 +3079,7 @@ DEFINE_STUB_FUNCTION(int, op_eq_strings)
return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
#else
UNUSED_PARAM(args);
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
#endif
}
@@ -3061,21 +3171,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = v.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
-
- callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number - 1);
- return JSValue::encode(jsNumber(number));
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -3111,11 +3206,11 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
RegExp* regExp = stackFrame.args[0].regExp();
if (!regExp->isValid()) {
- stackFrame.globalData->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
+ stackFrame.vm->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
VM_THROW_EXCEPTION();
}
- return RegExpObject::create(*stackFrame.globalData, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
+ return RegExpObject::create(*stackFrame.vm, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
@@ -3150,7 +3245,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
return JSValue::encode(JSValue());
JSValue result = eval(callFrame);
- if (stackFrame.globalData->exception)
+ if (stackFrame.vm->exception)
return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
return JSValue::encode(result);
@@ -3159,7 +3254,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
DEFINE_STUB_FUNCTION(void*, op_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
- ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
+ ExceptionHandler handler = jitThrow(stackFrame.vm, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -3265,7 +3360,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
return JSValue::encode(jsBoolean(result));
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_number)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -3285,7 +3380,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
JSValue baseVal = stackFrame.args[1].jsValue();
if (!baseVal.isObject()) {
- stackFrame.globalData->exception = createInvalidParamError(stackFrame.callFrame, "in", baseVal);
+ stackFrame.vm->exception = createInvalidParameterError(stackFrame.callFrame, "in", baseVal);
VM_THROW_EXCEPTION();
}
@@ -3314,19 +3409,6 @@ DEFINE_STUB_FUNCTION(void, op_push_name_scope)
callFrame->setScope(scope);
}
-DEFINE_STUB_FUNCTION(void, op_jmp_scopes)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- unsigned count = stackFrame.args[0].int32();
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSScope* tmp = callFrame->scope();
- while (count--)
- tmp = tmp->next();
- callFrame->setScope(tmp);
-}
-
DEFINE_STUB_FUNCTION(void, op_put_by_index)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -3420,7 +3502,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
}
if (!result && callFrame->codeBlock()->isStrictMode())
- stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+ stackFrame.vm->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(jsBoolean(result));
@@ -3444,9 +3526,9 @@ DEFINE_STUB_FUNCTION(void, op_put_getter_setter)
ASSERT(getter.isObject() || setter.isObject());
if (!getter.isUndefined())
- accessor->setGetter(callFrame->globalData(), asObject(getter));
+ accessor->setGetter(callFrame->vm(), asObject(getter));
if (!setter.isUndefined())
- accessor->setSetter(callFrame->globalData(), asObject(setter));
+ accessor->setSetter(callFrame->vm(), asObject(setter));
baseObj->putDirectAccessor(callFrame, stackFrame.args[1].identifier(), accessor, Accessor);
}
@@ -3455,11 +3537,11 @@ DEFINE_STUB_FUNCTION(void, op_throw_static_error)
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
- String message = stackFrame.args[0].jsValue().toString(callFrame)->value(callFrame);
+ String message = errorDescriptionForValue(callFrame, stackFrame.args[0].jsValue())->value(callFrame);
if (stackFrame.args[1].asInt32)
- stackFrame.globalData->exception = createReferenceError(callFrame, message);
+ stackFrame.vm->exception = createReferenceError(callFrame, message);
else
- stackFrame.globalData->exception = createTypeError(callFrame, message);
+ stackFrame.vm->exception = createTypeError(callFrame, message);
VM_THROW_EXCEPTION_AT_END();
}
@@ -3474,14 +3556,14 @@ DEFINE_STUB_FUNCTION(void, op_debug)
int lastLine = stackFrame.args[2].int32();
int column = stackFrame.args[3].int32();
- stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
+ stackFrame.vm->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
}
DEFINE_STUB_FUNCTION(void*, vm_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
- JSGlobalData* globalData = stackFrame.globalData;
- ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation);
+ VM* vm = stackFrame.vm;
+ ExceptionHandler handler = jitThrow(vm, stackFrame.callFrame, vm->exception, vm->exceptionLocation);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -3494,48 +3576,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
}
-MacroAssemblerCodeRef JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerator generator)
-{
- CTIStubMap::AddResult entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef());
- if (entry.isNewEntry)
- entry.iterator->value = generator(globalData);
- return entry.iterator->value;
-}
-
-NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, NativeFunction constructor)
-{
- if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(function))
- return nativeExecutable;
-
- NativeExecutable* nativeExecutable = NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), constructor, NoIntrinsic);
- weakAdd(*m_hostFunctionStubMap, function, PassWeak<NativeExecutable>(nativeExecutable));
- return nativeExecutable;
-}
-
-NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
-{
- if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(function))
- return nativeExecutable;
-
- MacroAssemblerCodeRef code;
- if (generator) {
- if (globalData->canUseJIT())
- code = generator(globalData);
- else
- code = MacroAssemblerCodeRef();
- } else
- code = JIT::compileCTINativeCall(globalData, function);
-
- NativeExecutable* nativeExecutable = NativeExecutable::create(*globalData, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, intrinsic);
- weakAdd(*m_hostFunctionStubMap, function, PassWeak<NativeExecutable>(nativeExecutable));
- return nativeExecutable;
-}
-
-void JITThunks::clearHostFunctionStubs()
-{
- m_hostFunctionStubMap.clear();
-}
-
} // namespace JSC
#endif // ENABLE(JIT)
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index c03bc929e..51873507e 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,264 +36,257 @@
#include "MacroAssemblerCodeRef.h"
#include "Register.h"
#include "ResolveOperation.h"
-#include "ThunkGenerators.h"
-#include <wtf/HashMap.h>
namespace JSC {
#if ENABLE(JIT)
- struct StructureStubInfo;
-
- class ArrayAllocationProfile;
- class CodeBlock;
- class ExecutablePool;
- class FunctionExecutable;
- class Identifier;
- class JSGlobalData;
- class JSGlobalObject;
- class JSObject;
- class JSPropertyNameIterator;
- class JSStack;
- class JSValue;
- class JSValueEncodedAsPointer;
- class NativeExecutable;
- class Profiler;
- class PropertySlot;
- class PutPropertySlot;
- class RegExp;
- class Structure;
-
- template <typename T> class Weak;
-
- union JITStubArg {
- void* asPointer;
- EncodedJSValue asEncodedJSValue;
- int32_t asInt32;
-
- JSValue jsValue() { return JSValue::decode(asEncodedJSValue); }
- JSObject* jsObject() { return static_cast<JSObject*>(asPointer); }
- Register* reg() { return static_cast<Register*>(asPointer); }
- Identifier& identifier() { return *static_cast<Identifier*>(asPointer); }
- int32_t int32() { return asInt32; }
- CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); }
- FunctionExecutable* function() { return static_cast<FunctionExecutable*>(asPointer); }
- RegExp* regExp() { return static_cast<RegExp*>(asPointer); }
- JSPropertyNameIterator* propertyNameIterator() { return static_cast<JSPropertyNameIterator*>(asPointer); }
- JSGlobalObject* globalObject() { return static_cast<JSGlobalObject*>(asPointer); }
- JSString* jsString() { return static_cast<JSString*>(asPointer); }
- Structure* structure() { return static_cast<Structure*>(asPointer); }
- ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
- ResolveOperations* resolveOperations() { return static_cast<ResolveOperations*>(asPointer); }
- PutToBaseOperation* putToBaseOperation() { return static_cast<PutToBaseOperation*>(asPointer); }
- ArrayAllocationProfile* arrayAllocationProfile() { return static_cast<ArrayAllocationProfile*>(asPointer); }
- };
+struct StructureStubInfo;
+
+class ArrayAllocationProfile;
+class CodeBlock;
+class ExecutablePool;
+class FunctionExecutable;
+class Identifier;
+class VM;
+class JSGlobalObject;
+class JSObject;
+class JSPropertyNameIterator;
+class JSStack;
+class JSValue;
+class JSValueEncodedAsPointer;
+class LegacyProfiler;
+class NativeExecutable;
+class PropertySlot;
+class PutPropertySlot;
+class RegExp;
+class Structure;
+
+template <typename T> class Weak;
+
+union JITStubArg {
+ void* asPointer;
+ EncodedJSValue asEncodedJSValue;
+ int32_t asInt32;
+
+ JSValue jsValue() { return JSValue::decode(asEncodedJSValue); }
+ JSObject* jsObject() { return static_cast<JSObject*>(asPointer); }
+ Register* reg() { return static_cast<Register*>(asPointer); }
+ Identifier& identifier() { return *static_cast<Identifier*>(asPointer); }
+ int32_t int32() { return asInt32; }
+ CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); }
+ FunctionExecutable* function() { return static_cast<FunctionExecutable*>(asPointer); }
+ RegExp* regExp() { return static_cast<RegExp*>(asPointer); }
+ JSPropertyNameIterator* propertyNameIterator() { return static_cast<JSPropertyNameIterator*>(asPointer); }
+ JSGlobalObject* globalObject() { return static_cast<JSGlobalObject*>(asPointer); }
+ JSString* jsString() { return static_cast<JSString*>(asPointer); }
+ Structure* structure() { return static_cast<Structure*>(asPointer); }
+ ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
+ ResolveOperations* resolveOperations() { return static_cast<ResolveOperations*>(asPointer); }
+ PutToBaseOperation* putToBaseOperation() { return static_cast<PutToBaseOperation*>(asPointer); }
+ ArrayAllocationProfile* arrayAllocationProfile() { return static_cast<ArrayAllocationProfile*>(asPointer); }
+};
- struct TrampolineStructure {
- MacroAssemblerCodePtr ctiStringLengthTrampoline;
- MacroAssemblerCodePtr ctiVirtualCallLink;
- MacroAssemblerCodePtr ctiVirtualConstructLink;
- MacroAssemblerCodePtr ctiVirtualCall;
- MacroAssemblerCodePtr ctiVirtualConstruct;
- MacroAssemblerCodePtr ctiNativeCall;
- MacroAssemblerCodePtr ctiNativeConstruct;
- };
-
#if !OS(WINDOWS) && CPU(X86_64)
- struct JITStackFrame {
- void* reserved; // Unused
- JITStubArg args[6];
- void* padding[2]; // Maintain 32-byte stack alignment (possibly overkill).
-
- void* code;
- JSStack* stack;
- CallFrame* callFrame;
- void* unused1;
- void* unused2;
- JSGlobalData* globalData;
-
- void* savedRBX;
- void* savedR15;
- void* savedR14;
- void* savedR13;
- void* savedR12;
- void* savedRBP;
- void* savedRIP;
-
- // When JIT code makes a call, it pushes its return address just below the rest of the stack.
- ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
- };
+struct JITStackFrame {
+ void* reserved; // Unused
+ JITStubArg args[6];
+ void* padding[2]; // Maintain 32-byte stack alignment (possibly overkill).
+
+ void* code;
+ JSStack* stack;
+ CallFrame* callFrame;
+ void* unused1;
+ void* unused2;
+ VM* vm;
+
+ void* savedRBX;
+ void* savedR15;
+ void* savedR14;
+ void* savedR13;
+ void* savedR12;
+ void* savedRBP;
+ void* savedRIP;
+
+ // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+ ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
+};
#elif OS(WINDOWS) && CPU(X86_64)
- struct JITStackFrame {
- void* shadow[4]; // Shadow space reserved for a callee's parameters home addresses
- void* reserved; // Unused, also maintains the 16-bytes stack alignment
- JITStubArg args[6];
-
- void* savedRBX;
- void* savedR15;
- void* savedR14;
- void* savedR13;
- void* savedR12;
- void* savedRBP;
- void* savedRIP;
-
- // Home addresses for our register passed parameters
- // http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
- void* code;
- JSStack* stack;
- CallFrame* callFrame;
- void* unused1;
-
- // Passed on the stack
- void* unused2;
- JSGlobalData* globalData;
-
- // When JIT code makes a call, it pushes its return address just below the rest of the stack.
- ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
- };
+struct JITStackFrame {
+ void* shadow[4]; // Shadow space reserved for a callee's parameters home addresses
+ void* reserved; // Unused, also maintains the 16-bytes stack alignment
+ JITStubArg args[6];
+
+ void* savedRBX;
+ void* savedR15;
+ void* savedR14;
+ void* savedR13;
+ void* savedR12;
+ void* savedRBP;
+ void* savedRIP;
+
+ // Home addresses for our register passed parameters
+ // http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
+ void* code;
+ JSStack* stack;
+ CallFrame* callFrame;
+ void* unused1;
+
+ // Passed on the stack
+ void* unused2;
+ VM* vm;
+
+ // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+ ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
+};
#elif CPU(X86)
#if COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
#pragma pack(push)
#pragma pack(4)
#endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
- struct JITStackFrame {
- void* reserved; // Unused
- JITStubArg args[6];
+struct JITStackFrame {
+ void* reserved; // Unused
+ JITStubArg args[6];
#if USE(JSVALUE32_64)
- void* padding[2]; // Maintain 16-byte stack alignment.
+ void* padding[2]; // Maintain 16-byte stack alignment.
#endif
- void* savedEBX;
- void* savedEDI;
- void* savedESI;
- void* savedEBP;
- void* savedEIP;
-
- void* code;
- JSStack* stack;
- CallFrame* callFrame;
- void* unused1;
- void* unused2;
- JSGlobalData* globalData;
+ void* savedEBX;
+ void* savedEDI;
+ void* savedESI;
+ void* savedEBP;
+ void* savedEIP;
+
+ void* code;
+ JSStack* stack;
+ CallFrame* callFrame;
+ void* unused1;
+ void* unused2;
+ VM* vm;
- // When JIT code makes a call, it pushes its return address just below the rest of the stack.
- ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
- };
+ // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+ ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
+};
#if COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
#pragma pack(pop)
#endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
#elif CPU(ARM_THUMB2)
- struct JITStackFrame {
- JITStubArg reserved; // Unused
- JITStubArg args[6];
-
- ReturnAddressPtr thunkReturnAddress;
-
- void* preservedReturnAddress;
- void* preservedR4;
- void* preservedR5;
- void* preservedR6;
- void* preservedR7;
- void* preservedR8;
- void* preservedR9;
- void* preservedR10;
- void* preservedR11;
-
- // These arguments passed in r1..r3 (r0 contained the entry code pointed, which is not preserved)
- JSStack* stack;
- CallFrame* callFrame;
-
- // These arguments passed on the stack.
- void* unused1;
- JSGlobalData* globalData;
+struct JITStackFrame {
+ JITStubArg reserved; // Unused
+ JITStubArg args[6];
+
+ ReturnAddressPtr thunkReturnAddress;
+
+ void* preservedReturnAddress;
+ void* preservedR4;
+ void* preservedR5;
+ void* preservedR6;
+ void* preservedR7;
+ void* preservedR8;
+ void* preservedR9;
+ void* preservedR10;
+ void* preservedR11;
+
+ // These arguments passed in r1..r3 (r0 contained the entry code pointed, which is not preserved)
+ JSStack* stack;
+ CallFrame* callFrame;
+
+ // These arguments passed on the stack.
+ void* unused1;
+ VM* vm;
- ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
- };
+ ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+};
#elif CPU(ARM_TRADITIONAL)
#if COMPILER(MSVC)
#pragma pack(push)
#pragma pack(4)
#endif // COMPILER(MSVC)
- struct JITStackFrame {
- JITStubArg padding; // Unused
- JITStubArg args[7];
-
- ReturnAddressPtr thunkReturnAddress;
-
- void* preservedR4;
- void* preservedR5;
- void* preservedR6;
- void* preservedR8;
- void* preservedR9;
- void* preservedR10;
- void* preservedR11;
- void* preservedLink;
-
- JSStack* stack;
- CallFrame* callFrame;
- void* unused1;
-
- // These arguments passed on the stack.
- void* unused2;
- JSGlobalData* globalData;
-
- // When JIT code makes a call, it pushes its return address just below the rest of the stack.
- ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
- };
+struct JITStackFrame {
+ JITStubArg padding; // Unused
+ JITStubArg args[7];
+
+ ReturnAddressPtr thunkReturnAddress;
+
+ void* preservedR4;
+ void* preservedR5;
+ void* preservedR6;
+ void* preservedR8;
+ void* preservedR9;
+ void* preservedR10;
+ void* preservedR11;
+ void* preservedLink;
+
+ JSStack* stack;
+ CallFrame* callFrame;
+ void* unused1;
+
+ // These arguments passed on the stack.
+ void* unused2;
+ VM* vm;
+
+ // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+ ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+};
#if COMPILER(MSVC)
#pragma pack(pop)
#endif // COMPILER(MSVC)
#elif CPU(MIPS)
- struct JITStackFrame {
- JITStubArg reserved; // Unused
- JITStubArg args[6];
+struct JITStackFrame {
+ JITStubArg reserved; // Unused
+ JITStubArg args[6];
#if USE(JSVALUE32_64)
- void* padding; // Make the overall stack length 8-byte aligned.
+ void* padding; // Make the overall stack length 8-byte aligned.
#endif
- void* preservedGP; // store GP when using PIC code
- void* preservedS0;
- void* preservedS1;
- void* preservedS2;
- void* preservedS3;
- void* preservedS4;
- void* preservedReturnAddress;
+ void* preservedGP; // store GP when using PIC code
+ void* preservedS0;
+ void* preservedS1;
+ void* preservedS2;
+ void* preservedS3;
+ void* preservedS4;
+ void* preservedReturnAddress;
- ReturnAddressPtr thunkReturnAddress;
+ ReturnAddressPtr thunkReturnAddress;
- // These arguments passed in a1..a3 (a0 contained the entry code pointed, which is not preserved)
- JSStack* stack;
- CallFrame* callFrame;
- void* unused1;
+ // These arguments passed in a1..a3 (a0 contained the entry code pointed, which is not preserved)
+ JSStack* stack;
+ CallFrame* callFrame;
+ void* unused1;
- // These arguments passed on the stack.
- void* unused2;
- JSGlobalData* globalData;
+ // These arguments passed on the stack.
+ void* unused2;
+ VM* vm;
- ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
- };
+ ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+};
#elif CPU(SH4)
- struct JITStackFrame {
- JITStubArg padding; // Unused
- JITStubArg args[6];
-
- ReturnAddressPtr thunkReturnAddress;
- void* savedR10;
- void* savedR11;
- void* savedR13;
- void* savedRPR;
- void* savedR14;
- void* savedTimeoutReg;
-
- JSStack* stack;
- CallFrame* callFrame;
- JSValue* exception;
- void* unused1;
- JSGlobalData* globalData;
-
- ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
- };
+struct JITStackFrame {
+ JITStubArg padding; // Unused
+ JITStubArg args[6];
+
+ ReturnAddressPtr thunkReturnAddress;
+
+ void* savedR8;
+ void* savedR9;
+ void* savedR10;
+ void* savedR11;
+ void* savedR13;
+ void* savedRPR;
+ void* savedR14;
+
+ // These arguments are passed in r5, r6 and r7.
+ JSStack* stack;
+ CallFrame* callFrame;
+ JSValue* exception;
+
+ // These arguments are passed on the stack.
+ void* unused1;
+ VM* vm;
+
+ ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+};
#else
#error "JITStackFrame not defined for this platform."
#endif
@@ -304,208 +297,160 @@ namespace JSC {
#define STUB_ARGS (args)
#if CPU(X86)
- #if COMPILER(MSVC)
- #define JIT_STUB __fastcall
- #elif COMPILER(GCC)
- #define JIT_STUB __attribute__ ((fastcall))
- #elif COMPILER(SUNCC)
- #define JIT_STUB
- #else
- #error "JIT_STUB function calls require fastcall conventions on x86, add appropriate directive/attribute here for your compiler!"
- #endif
+#if COMPILER(MSVC)
+#define JIT_STUB __fastcall
+#elif COMPILER(GCC)
+#define JIT_STUB __attribute__ ((fastcall))
+#elif COMPILER(SUNCC)
+#define JIT_STUB
+#else
+#error "JIT_STUB function calls require fastcall conventions on x86, add appropriate directive/attribute here for your compiler!"
+#endif
#else
- #define JIT_STUB
+#define JIT_STUB
#endif
- extern "C" void ctiVMThrowTrampoline();
- extern "C" void ctiOpThrowNotCaught();
- extern "C" EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*);
+extern "C" void ctiVMThrowTrampoline();
+extern "C" void ctiOpThrowNotCaught();
+extern "C" EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*);
#if ENABLE(DFG_JIT)
- extern "C" void ctiTrampolineEnd();
+extern "C" void ctiTrampolineEnd();
- inline bool returnAddressIsInCtiTrampoline(ReturnAddressPtr returnAddress)
- {
- return returnAddress.value() >= bitwise_cast<void*>(&ctiTrampoline)
- && returnAddress.value() < bitwise_cast<void*>(&ctiTrampolineEnd);
- }
+inline bool returnAddressIsInCtiTrampoline(ReturnAddressPtr returnAddress)
+{
+ return returnAddress.value() >= bitwise_cast<void*>(&ctiTrampoline)
+ && returnAddress.value() < bitwise_cast<void*>(&ctiTrampolineEnd);
+}
#endif
- class JITThunks {
- public:
- JITThunks(JSGlobalData*);
- ~JITThunks();
-
- static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo);
- static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo, bool direct);
-
- MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_trampolineStructure.ctiStringLengthTrampoline; }
- MacroAssemblerCodePtr ctiVirtualCallLink() { return m_trampolineStructure.ctiVirtualCallLink; }
- MacroAssemblerCodePtr ctiVirtualConstructLink() { return m_trampolineStructure.ctiVirtualConstructLink; }
- MacroAssemblerCodePtr ctiVirtualCall() { return m_trampolineStructure.ctiVirtualCall; }
- MacroAssemblerCodePtr ctiVirtualConstruct() { return m_trampolineStructure.ctiVirtualConstruct; }
- 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;
- }
-
- MacroAssemblerCodeRef ctiStub(JSGlobalData*, ThunkGenerator);
-
- NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction, NativeFunction constructor);
- NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction, ThunkGenerator, Intrinsic);
-
- void clearHostFunctionStubs();
-
- private:
- typedef HashMap<ThunkGenerator, MacroAssemblerCodeRef> CTIStubMap;
- CTIStubMap m_ctiStubMap;
- typedef HashMap<NativeFunction, Weak<NativeExecutable> > HostFunctionStubMap;
- OwnPtr<HostFunctionStubMap> m_hostFunctionStubMap;
- RefPtr<ExecutableMemoryHandle> m_executableMemory;
-
- TrampolineStructure m_trampolineStructure;
- };
+void performPlatformSpecificJITAssertions(VM*);
extern "C" {
- EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_custom_stub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_getter_stub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_val_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_is_function(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_is_number(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_is_object(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_is_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_is_undefined(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_greater(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_greatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_ensure_property_exists(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_resolve_with_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_to_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_array_with_size(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_array_buffer(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_push_name_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_push_with_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_jgreater(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_jgreatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_id_direct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_id_direct_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_id_direct_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_by_val_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_put_getter_setter(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_init_global_const_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void JIT_STUB cti_op_throw_static_error(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_custom_stub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_getter_stub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_val_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_is_function(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_is_number(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_is_object(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_is_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_is_undefined(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_greater(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_greatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_dec(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_inc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_resolve_with_this(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_to_base(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_to_number(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_array_with_size(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_array_buffer(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_push_name_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_push_with_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_jgreater(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_jgreatereq(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_handle_watchdog_timer(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_id_direct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_id_direct_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_id_direct_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_by_val_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_put_getter_setter(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_init_global_const_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_op_throw_static_error(STUB_ARGS_DECLARATION) WTF_INTERNAL;
#if ENABLE(DFG_JIT)
- void JIT_STUB cti_optimize(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void JIT_STUB cti_optimize(STUB_ARGS_DECLARATION) WTF_INTERNAL;
#endif
- void* JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_construct_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_call_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_construct_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_stack_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
- void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL;
+void* JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_construct_arityCheck(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_call_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_construct_jitCompile(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_stack_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_vm_lazyLinkClosureCall(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL;
} // extern "C"
#elif ENABLE(LLINT_C_LOOP)
struct JITStackFrame {
- JSGlobalData* globalData;
+ VM* vm;
};
#endif // ENABLE(LLINT_C_LOOP)
diff --git a/Source/JavaScriptCore/jit/JITThunks.cpp b/Source/JavaScriptCore/jit/JITThunks.cpp
new file mode 100644
index 000000000..e11774be0
--- /dev/null
+++ b/Source/JavaScriptCore/jit/JITThunks.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "JITThunks.h"
+
+#if ENABLE(JIT)
+
+#include "Executable.h"
+#include "JIT.h"
+#include "VM.h"
+#include "Operations.h"
+
+namespace JSC {
+
+JITThunks::JITThunks()
+ : m_hostFunctionStubMap(adoptPtr(new HostFunctionStubMap))
+{
+}
+
+JITThunks::~JITThunks()
+{
+}
+
+MacroAssemblerCodePtr JITThunks::ctiNativeCall(VM* vm)
+{
+#if ENABLE(LLINT)
+ if (!vm->canUseJIT())
+ return MacroAssemblerCodePtr::createLLIntCodePtr(llint_native_call_trampoline);
+#endif
+ return ctiStub(vm, nativeCallGenerator).code();
+}
+MacroAssemblerCodePtr JITThunks::ctiNativeConstruct(VM* vm)
+{
+#if ENABLE(LLINT)
+ if (!vm->canUseJIT())
+ return MacroAssemblerCodePtr::createLLIntCodePtr(llint_native_construct_trampoline);
+#endif
+ return ctiStub(vm, nativeConstructGenerator).code();
+}
+
+MacroAssemblerCodeRef JITThunks::ctiStub(VM* vm, ThunkGenerator generator)
+{
+ CTIStubMap::AddResult entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef());
+ if (entry.isNewEntry)
+ entry.iterator->value = generator(vm);
+ return entry.iterator->value;
+}
+
+NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, NativeFunction constructor)
+{
+ if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, constructor)))
+ return nativeExecutable;
+
+ NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, JIT::compileCTINativeCall(vm, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), constructor, NoIntrinsic);
+ weakAdd(*m_hostFunctionStubMap, std::make_pair(function, constructor), PassWeak<NativeExecutable>(nativeExecutable));
+ return nativeExecutable;
+}
+
+NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
+{
+ if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, &callHostFunctionAsConstructor)))
+ return nativeExecutable;
+
+ MacroAssemblerCodeRef code;
+ if (generator) {
+ if (vm->canUseJIT())
+ code = generator(vm);
+ else
+ code = MacroAssemblerCodeRef();
+ } else
+ code = JIT::compileCTINativeCall(vm, function);
+
+ NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), callHostFunctionAsConstructor, intrinsic);
+ weakAdd(*m_hostFunctionStubMap, std::make_pair(function, &callHostFunctionAsConstructor), PassWeak<NativeExecutable>(nativeExecutable));
+ return nativeExecutable;
+}
+
+void JITThunks::clearHostFunctionStubs()
+{
+ m_hostFunctionStubMap.clear();
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/Source/JavaScriptCore/jit/JITThunks.h b/Source/JavaScriptCore/jit/JITThunks.h
new file mode 100644
index 000000000..769583b1d
--- /dev/null
+++ b/Source/JavaScriptCore/jit/JITThunks.h
@@ -0,0 +1,76 @@
+/*
+ * 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 JITThunks_h
+#define JITThunks_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+#include "CallData.h"
+#include "Intrinsic.h"
+#include "LowLevelInterpreter.h"
+#include "MacroAssemblerCodeRef.h"
+#include "ThunkGenerator.h"
+#include "Weak.h"
+#include "WeakInlines.h"
+#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+class VM;
+class NativeExecutable;
+
+class JITThunks {
+public:
+ JITThunks();
+ ~JITThunks();
+
+ MacroAssemblerCodePtr ctiNativeCall(VM*);
+ MacroAssemblerCodePtr ctiNativeConstruct(VM*);
+
+ MacroAssemblerCodeRef ctiStub(VM*, ThunkGenerator);
+
+ NativeExecutable* hostFunctionStub(VM*, NativeFunction, NativeFunction constructor);
+ NativeExecutable* hostFunctionStub(VM*, NativeFunction, ThunkGenerator, Intrinsic);
+
+ void clearHostFunctionStubs();
+
+private:
+ typedef HashMap<ThunkGenerator, MacroAssemblerCodeRef> CTIStubMap;
+ CTIStubMap m_ctiStubMap;
+ typedef HashMap<std::pair<NativeFunction, NativeFunction>, Weak<NativeExecutable> > HostFunctionStubMap;
+ OwnPtr<HostFunctionStubMap> m_hostFunctionStubMap;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITThunks_h
+
diff --git a/Source/JavaScriptCore/jit/JITWriteBarrier.h b/Source/JavaScriptCore/jit/JITWriteBarrier.h
index ee73b702f..9da1ea782 100644
--- a/Source/JavaScriptCore/jit/JITWriteBarrier.h
+++ b/Source/JavaScriptCore/jit/JITWriteBarrier.h
@@ -30,12 +30,13 @@
#include "MacroAssembler.h"
#include "SlotVisitor.h"
+#include "UnusedPointer.h"
#include "WriteBarrier.h"
namespace JSC {
class JSCell;
-class JSGlobalData;
+class VM;
// Needs to be even to appease some of the backends.
#define JITWriteBarrierFlag ((void*)2)
@@ -69,14 +70,14 @@ public:
}
void clear() { clear(0); }
- void clearToMaxUnsigned() { clear(reinterpret_cast<void*>(-1)); }
+ void clearToUnusedPointer() { clear(reinterpret_cast<void*>(unusedPointer)); }
protected:
JITWriteBarrierBase()
{
}
- void set(JSGlobalData&, CodeLocationDataLabelPtr location, JSCell* owner, JSCell* value)
+ void set(VM&, CodeLocationDataLabelPtr location, JSCell* owner, JSCell* value)
{
Heap::writeBarrier(owner, value);
m_location = location;
@@ -90,8 +91,7 @@ protected:
if (!m_location || m_location.executableAddress() == JITWriteBarrierFlag)
return 0;
void* result = static_cast<JSCell*>(MacroAssembler::readPointer(m_location));
- // We use -1 to indicate a "safe" empty value in the instruction stream
- if (result == (void*)-1)
+ if (result == reinterpret_cast<void*>(unusedPointer))
return 0;
return static_cast<JSCell*>(result);
}
@@ -116,15 +116,15 @@ public:
{
}
- void set(JSGlobalData& globalData, CodeLocationDataLabelPtr location, JSCell* owner, T* value)
+ void set(VM& vm, CodeLocationDataLabelPtr location, JSCell* owner, T* value)
{
validateCell(owner);
validateCell(value);
- JITWriteBarrierBase::set(globalData, location, owner, value);
+ JITWriteBarrierBase::set(vm, location, owner, value);
}
- void set(JSGlobalData& globalData, JSCell* owner, T* value)
+ void set(VM& vm, JSCell* owner, T* value)
{
- set(globalData, location(), owner, value);
+ set(vm, location(), owner, value);
}
T* get() const
{
diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
index 7afdc06dc..0cf7589dd 100644
--- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h
+++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
@@ -29,11 +29,10 @@
#include "BytecodeConventions.h"
#include "JITCode.h"
#include "JITStubs.h"
+#include "JSCJSValue.h"
#include "JSStack.h"
#include "JSString.h"
-#include "JSValue.h"
#include "MacroAssembler.h"
-#include <wtf/AlwaysInline.h>
#include <wtf/Vector.h>
#if ENABLE(JIT)
@@ -67,7 +66,6 @@ namespace JSC {
static const RegisterID bucketCounterRegister = X86Registers::r10;
#endif
- static const RegisterID timeoutCheckRegister = X86Registers::r12;
static const RegisterID callFrameRegister = X86Registers::r13;
static const RegisterID tagTypeNumberRegister = X86Registers::r14;
static const RegisterID tagMaskRegister = X86Registers::r15;
@@ -118,7 +116,6 @@ namespace JSC {
// Update ctiTrampoline in JITStubs.cpp if these values are changed!
static const RegisterID callFrameRegister = ARMRegisters::r5;
- static const RegisterID timeoutCheckRegister = ARMRegisters::r6;
static const FPRegisterID fpRegT0 = ARMRegisters::d0;
static const FPRegisterID fpRegT1 = ARMRegisters::d1;
@@ -145,16 +142,18 @@ namespace JSC {
static const RegisterID regT3 = MIPSRegisters::s2;
static const RegisterID callFrameRegister = MIPSRegisters::s0;
- static const RegisterID timeoutCheckRegister = MIPSRegisters::s1;
static const FPRegisterID fpRegT0 = MIPSRegisters::f4;
static const FPRegisterID fpRegT1 = MIPSRegisters::f6;
static const FPRegisterID fpRegT2 = MIPSRegisters::f8;
static const FPRegisterID fpRegT3 = MIPSRegisters::f10;
#elif CPU(SH4)
- static const RegisterID timeoutCheckRegister = SH4Registers::r8;
static const RegisterID callFrameRegister = SH4Registers::fp;
+#if ENABLE(VALUE_PROFILER)
+ static const RegisterID bucketCounterRegister = SH4Registers::r8;
+#endif
+
static const RegisterID regT0 = SH4Registers::r0;
static const RegisterID regT1 = SH4Registers::r1;
static const RegisterID regT2 = SH4Registers::r2;
@@ -163,19 +162,17 @@ namespace JSC {
static const RegisterID regT5 = SH4Registers::r5;
static const RegisterID regT6 = SH4Registers::r6;
static const RegisterID regT7 = SH4Registers::r7;
- static const RegisterID firstArgumentRegister =regT4;
+ static const RegisterID firstArgumentRegister = regT4;
static const RegisterID returnValueRegister = SH4Registers::r0;
static const RegisterID cachedResultRegister = SH4Registers::r0;
- static const FPRegisterID fpRegT0 = SH4Registers::fr0;
- static const FPRegisterID fpRegT1 = SH4Registers::fr2;
- static const FPRegisterID fpRegT2 = SH4Registers::fr4;
- static const FPRegisterID fpRegT3 = SH4Registers::fr6;
- static const FPRegisterID fpRegT4 = SH4Registers::fr8;
- static const FPRegisterID fpRegT5 = SH4Registers::fr10;
- static const FPRegisterID fpRegT6 = SH4Registers::fr12;
- static const FPRegisterID fpRegT7 = SH4Registers::fr14;
+ static const FPRegisterID fpRegT0 = SH4Registers::dr0;
+ static const FPRegisterID fpRegT1 = SH4Registers::dr2;
+ static const FPRegisterID fpRegT2 = SH4Registers::dr4;
+ static const FPRegisterID fpRegT3 = SH4Registers::dr6;
+ static const FPRegisterID fpRegT4 = SH4Registers::dr8;
+ static const FPRegisterID fpRegT5 = SH4Registers::dr10;
#else
#error "JIT not supported on this platform."
#endif
@@ -197,11 +194,25 @@ namespace JSC {
#endif
#if USE(JSVALUE64)
+ Jump emitJumpIfNotJSCell(RegisterID);
Jump emitJumpIfImmediateNumber(RegisterID reg);
Jump emitJumpIfNotImmediateNumber(RegisterID reg);
void emitFastArithImmToInt(RegisterID reg);
+ void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
#endif
+ Jump emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType);
+
+ void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
+ void emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
+ void emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry);
+ void emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
+
+ void preserveReturnAddressAfterCall(RegisterID);
+ void restoreReturnAddressBeforeReturn(RegisterID);
+ void restoreReturnAddressBeforeReturn(Address);
+ void restoreArgumentReference();
+
inline Address payloadFor(int index, RegisterID base = callFrameRegister);
inline Address intPayloadFor(int index, RegisterID base = callFrameRegister);
inline Address intTagFor(int index, RegisterID base = callFrameRegister);
@@ -209,9 +220,6 @@ namespace JSC {
};
struct ThunkHelpers {
- static unsigned stringImplFlagsOffset() { return StringImpl::flagsOffset(); }
- static unsigned stringImpl8BitFlag() { return StringImpl::flagIs8Bit(); }
- static unsigned stringImplDataOffset() { return StringImpl::dataOffset(); }
static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); }
static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); }
};
@@ -276,6 +284,11 @@ namespace JSC {
#endif
#if USE(JSVALUE64)
+ ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotJSCell(RegisterID reg)
+ {
+ return branchTest64(NonZero, reg, tagMaskRegister);
+ }
+
ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfImmediateNumber(RegisterID reg)
{
return branchTest64(NonZero, reg, tagTypeNumberRegister);
@@ -316,6 +329,13 @@ namespace JSC {
{
}
+ // operand is int32_t, must have been zero-extended if register is 64-bit.
+ ALWAYS_INLINE void JSInterfaceJIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ or64(tagTypeNumberRegister, dest);
+ }
#endif
#if USE(JSVALUE64)
@@ -337,12 +357,122 @@ namespace JSC {
}
#endif
+ ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType type)
+ {
+ loadPtr(Address(baseReg, JSCell::structureOffset()), scratchReg);
+ return branch8(NotEqual, Address(scratchReg, Structure::typeInfoTypeOffset()), TrustedImm32(type));
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
+ {
+ loadPtr(Address(from, entry * sizeof(Register)), to);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
+ {
+#if USE(JSVALUE32_64)
+ storePtr(from, payloadFor(entry, callFrameRegister));
+#else
+ store64(from, addressFor(entry, callFrameRegister));
+#endif
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry entry)
+ {
+ storePtr(TrustedImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
+ {
+#if USE(JSVALUE32_64)
+ store32(TrustedImm32(JSValue::CellTag), tagFor(entry, callFrameRegister));
+ store32(from, payloadFor(entry, callFrameRegister));
+#else
+ store64(from, addressFor(entry, callFrameRegister));
+#endif
+ }
+
inline JSInterfaceJIT::Address JSInterfaceJIT::addressFor(int virtualRegisterIndex, RegisterID base)
{
ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)));
}
+#if CPU(ARM)
+
+ ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
+ {
+ move(linkRegister, reg);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+ {
+ move(reg, linkRegister);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
+ {
+ loadPtr(address, linkRegister);
+ }
+#elif CPU(SH4)
+
+ ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
+ {
+ m_assembler.stspr(reg);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+ {
+ m_assembler.ldspr(reg);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
+ {
+ loadPtrLinkReg(address);
+ }
+
+#elif CPU(MIPS)
+
+ ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
+ {
+ move(returnAddressRegister, reg);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+ {
+ move(reg, returnAddressRegister);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
+ {
+ loadPtr(address, returnAddressRegister);
+ }
+
+#else // CPU(X86) || CPU(X86_64)
+
+ ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
+ {
+ pop(reg);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+ {
+ push(reg);
+ }
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
+ {
+ push(address);
+ }
+
+#endif
+
+ ALWAYS_INLINE void JSInterfaceJIT::restoreArgumentReference()
+ {
+ move(stackPointerRegister, firstArgumentRegister);
+ poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
+ }
+
} // namespace JSC
#endif // ENABLE(JIT)
diff --git a/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h b/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h
index b4f35c724..457cbb286 100644
--- a/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h
+++ b/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h
@@ -50,6 +50,13 @@ public:
{
}
+ MacroAssembler::Label sourceLabel() const
+ {
+ MacroAssembler::Label label;
+ label.m_label.m_offset = m_source;
+ return label;
+ }
+
void setDestination(MacroAssembler::Label destination)
{
m_destination = destination.m_label.m_offset;
diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
index 9c7fbce81..9a0e0a30e 100644
--- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
+++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
@@ -55,10 +55,10 @@ namespace JSC {
m_failures.append(emitLoadJSCell(src, dst));
}
- void loadJSStringArgument(JSGlobalData& globalData, int argument, RegisterID dst)
+ void loadJSStringArgument(VM& vm, int argument, RegisterID dst)
{
loadCellArgument(argument, dst);
- m_failures.append(branchPtr(NotEqual, Address(dst, JSCell::structureOffset()), TrustedImmPtr(globalData.stringStructure.get())));
+ m_failures.append(branchPtr(NotEqual, Address(dst, JSCell::structureOffset()), TrustedImmPtr(vm.stringStructure.get())));
}
void loadInt32Argument(int argument, RegisterID dst, Jump& failTarget)
@@ -130,9 +130,9 @@ namespace JSC {
ret();
}
- MacroAssemblerCodeRef finalize(JSGlobalData& globalData, MacroAssemblerCodePtr fallback, const char* thunkKind)
+ MacroAssemblerCodeRef finalize(VM& vm, MacroAssemblerCodePtr fallback, const char* thunkKind)
{
- LinkBuffer patchBuffer(globalData, this, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(vm, this, GLOBAL_THUNK_ID);
patchBuffer.link(m_failures, CodeLocationLabel(fallback));
for (unsigned i = 0; i < m_calls.size(); i++)
patchBuffer.link(m_calls[i].first, m_calls[i].second);
@@ -145,6 +145,15 @@ namespace JSC {
{
m_calls.append(std::make_pair(call(), function));
}
+
+ void callDoubleToDoublePreservingReturn(FunctionPtr function)
+ {
+ if (!isX86())
+ preserveReturnAddressAfterCall(regT3);
+ callDoubleToDouble(function);
+ if (!isX86())
+ restoreReturnAddressBeforeReturn(regT3);
+ }
private:
diff --git a/Source/JavaScriptCore/jit/ThunkGenerator.h b/Source/JavaScriptCore/jit/ThunkGenerator.h
new file mode 100644
index 000000000..a9d7e04ee
--- /dev/null
+++ b/Source/JavaScriptCore/jit/ThunkGenerator.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ThunkGenerator_h
+#define ThunkGenerator_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+namespace JSC {
+class VM;
+class MacroAssemblerCodeRef;
+
+typedef MacroAssemblerCodeRef (*ThunkGenerator)(VM*);
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // ThunkGenerator_h
+
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
index cbfc1eb0f..9684df2d0 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,18 +27,399 @@
#include "ThunkGenerators.h"
#include "CodeBlock.h"
-#include <wtf/InlineASM.h>
+#include "Operations.h"
#include "SpecializedThunkJIT.h"
+#include <wtf/InlineASM.h>
+#include <wtf/StringPrintStream.h>
#include <wtf/text/StringImpl.h>
#if ENABLE(JIT)
namespace JSC {
-static void stringCharLoad(SpecializedThunkJIT& jit, JSGlobalData* globalData)
+static JSInterfaceJIT::Call generateSlowCaseFor(VM* vm, JSInterfaceJIT& jit)
+{
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::regT2);
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT2, JSInterfaceJIT::regT2);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT2, JSStack::ScopeChain);
+
+ // Also initialize ReturnPC and CodeBlock, like a JS function would.
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3);
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT3, JSStack::ReturnPC);
+ jit.emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
+
+ jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
+ jit.restoreArgumentReference();
+ JSInterfaceJIT::Call callNotJSFunction = jit.call();
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::callFrameRegister);
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
+ jit.ret();
+
+ return callNotJSFunction;
+}
+
+static MacroAssemblerCodeRef linkForGenerator(VM* vm, FunctionPtr lazyLink, FunctionPtr notJSFunction, const char* name)
+{
+ JSInterfaceJIT jit;
+
+ JSInterfaceJIT::JumpList slowCase;
+
+#if USE(JSVALUE64)
+ slowCase.append(jit.emitJumpIfNotJSCell(JSInterfaceJIT::regT0));
+ slowCase.append(jit.emitJumpIfNotType(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1, JSFunctionType));
+#else // USE(JSVALUE64)
+ slowCase.append(jit.branch32(JSInterfaceJIT::NotEqual, JSInterfaceJIT::regT1, JSInterfaceJIT::TrustedImm32(JSValue::CellTag)));
+ slowCase.append(jit.emitJumpIfNotType(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1, JSFunctionType));
+#endif // USE(JSVALUE64)
+
+ // Finish canonical initialization before JS function call.
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfScopeChain()), JSInterfaceJIT::regT1);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ // Also initialize ReturnPC for use by lazy linking and exceptions.
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3);
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT3, JSStack::ReturnPC);
+
+ jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
+ jit.restoreArgumentReference();
+ JSInterfaceJIT::Call callLazyLink = jit.call();
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
+ jit.jump(JSInterfaceJIT::regT0);
+
+ slowCase.link(&jit);
+ JSInterfaceJIT::Call callNotJSFunction = generateSlowCaseFor(vm, jit);
+
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
+ patchBuffer.link(callLazyLink, lazyLink);
+ patchBuffer.link(callNotJSFunction, notJSFunction);
+
+ return FINALIZE_CODE(patchBuffer, ("link %s trampoline", name));
+}
+
+MacroAssemblerCodeRef linkCallGenerator(VM* vm)
+{
+ return linkForGenerator(vm, FunctionPtr(cti_vm_lazyLinkCall), FunctionPtr(cti_op_call_NotJSFunction), "call");
+}
+
+MacroAssemblerCodeRef linkConstructGenerator(VM* vm)
+{
+ return linkForGenerator(vm, FunctionPtr(cti_vm_lazyLinkConstruct), FunctionPtr(cti_op_construct_NotJSConstruct), "construct");
+}
+
+MacroAssemblerCodeRef linkClosureCallGenerator(VM* vm)
+{
+ return linkForGenerator(vm, FunctionPtr(cti_vm_lazyLinkClosureCall), FunctionPtr(cti_op_call_NotJSFunction), "closure call");
+}
+
+static MacroAssemblerCodeRef virtualForGenerator(VM* vm, FunctionPtr compile, FunctionPtr notJSFunction, const char* name, CodeSpecializationKind kind)
+{
+ JSInterfaceJIT jit;
+
+ JSInterfaceJIT::JumpList slowCase;
+
+#if USE(JSVALUE64)
+ slowCase.append(jit.emitJumpIfNotJSCell(JSInterfaceJIT::regT0));
+#else // USE(JSVALUE64)
+ slowCase.append(jit.branch32(JSInterfaceJIT::NotEqual, JSInterfaceJIT::regT1, JSInterfaceJIT::TrustedImm32(JSValue::CellTag)));
+#endif // USE(JSVALUE64)
+ slowCase.append(jit.emitJumpIfNotType(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1, JSFunctionType));
+
+ // Finish canonical initialization before JS function call.
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfScopeChain()), JSInterfaceJIT::regT1);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);
+ JSInterfaceJIT::Jump hasCodeBlock1 = jit.branch32(JSInterfaceJIT::GreaterThanOrEqual, JSInterfaceJIT::Address(JSInterfaceJIT::regT2, FunctionExecutable::offsetOfNumParametersFor(kind)), JSInterfaceJIT::TrustedImm32(0));
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3);
+ jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
+ jit.restoreArgumentReference();
+ JSInterfaceJIT::Call callCompile = jit.call();
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);
+
+ hasCodeBlock1.link(&jit);
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT2, FunctionExecutable::offsetOfJITCodeWithArityCheckFor(kind)), JSInterfaceJIT::regT0);
+ jit.jump(JSInterfaceJIT::regT0);
+
+ slowCase.link(&jit);
+ JSInterfaceJIT::Call callNotJSFunction = generateSlowCaseFor(vm, jit);
+
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
+ patchBuffer.link(callCompile, compile);
+ patchBuffer.link(callNotJSFunction, notJSFunction);
+
+ return FINALIZE_CODE(patchBuffer, ("virtual %s trampoline", name));
+}
+
+MacroAssemblerCodeRef virtualCallGenerator(VM* vm)
+{
+ return virtualForGenerator(vm, FunctionPtr(cti_op_call_jitCompile), FunctionPtr(cti_op_call_NotJSFunction), "call", CodeForCall);
+}
+
+MacroAssemblerCodeRef virtualConstructGenerator(VM* vm)
+{
+ return virtualForGenerator(vm, FunctionPtr(cti_op_construct_jitCompile), FunctionPtr(cti_op_construct_NotJSConstruct), "construct", CodeForConstruct);
+}
+
+MacroAssemblerCodeRef stringLengthTrampolineGenerator(VM* vm)
+{
+ JSInterfaceJIT jit;
+
+#if USE(JSVALUE64)
+ // Check eax is a string
+ JSInterfaceJIT::Jump failureCases1 = jit.emitJumpIfNotJSCell(JSInterfaceJIT::regT0);
+ JSInterfaceJIT::Jump failureCases2 = jit.branchPtr(
+ JSInterfaceJIT::NotEqual, JSInterfaceJIT::Address(
+ JSInterfaceJIT::regT0, JSCell::structureOffset()),
+ JSInterfaceJIT::TrustedImmPtr(vm->stringStructure.get()));
+
+ // Checks out okay! - get the length from the Ustring.
+ jit.load32(
+ JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSString::offsetOfLength()),
+ JSInterfaceJIT::regT0);
+
+ JSInterfaceJIT::Jump failureCases3 = jit.branch32(
+ JSInterfaceJIT::LessThan, JSInterfaceJIT::regT0, JSInterfaceJIT::TrustedImm32(0));
+
+ // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
+ jit.emitFastArithIntToImmNoCheck(JSInterfaceJIT::regT0, JSInterfaceJIT::regT0);
+
+#else // USE(JSVALUE64)
+ // regT0 holds payload, regT1 holds tag
+
+ JSInterfaceJIT::Jump failureCases1 = jit.branch32(
+ JSInterfaceJIT::NotEqual, JSInterfaceJIT::regT1,
+ JSInterfaceJIT::TrustedImm32(JSValue::CellTag));
+ JSInterfaceJIT::Jump failureCases2 = jit.branchPtr(
+ JSInterfaceJIT::NotEqual,
+ JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSCell::structureOffset()),
+ JSInterfaceJIT::TrustedImmPtr(vm->stringStructure.get()));
+
+ // Checks out okay! - get the length from the Ustring.
+ jit.load32(
+ JSInterfaceJIT::Address(JSInterfaceJIT::regT0, JSString::offsetOfLength()),
+ JSInterfaceJIT::regT2);
+
+ JSInterfaceJIT::Jump failureCases3 = jit.branch32(
+ JSInterfaceJIT::Above, JSInterfaceJIT::regT2, JSInterfaceJIT::TrustedImm32(INT_MAX));
+ jit.move(JSInterfaceJIT::regT2, JSInterfaceJIT::regT0);
+ jit.move(JSInterfaceJIT::TrustedImm32(JSValue::Int32Tag), JSInterfaceJIT::regT1);
+#endif // USE(JSVALUE64)
+
+ jit.ret();
+
+ JSInterfaceJIT::Call failureCases1Call = jit.makeTailRecursiveCall(failureCases1);
+ JSInterfaceJIT::Call failureCases2Call = jit.makeTailRecursiveCall(failureCases2);
+ JSInterfaceJIT::Call failureCases3Call = jit.makeTailRecursiveCall(failureCases3);
+
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
+
+ patchBuffer.link(failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail));
+ patchBuffer.link(failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail));
+ patchBuffer.link(failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
+
+ return FINALIZE_CODE(patchBuffer, ("string length trampoline"));
+}
+
+static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind kind)
+{
+ int executableOffsetToFunction = NativeExecutable::offsetOfNativeFunctionFor(kind);
+
+ JSInterfaceJIT jit;
+
+ jit.emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock);
+ jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
+
+#if CPU(X86)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::regT0);
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT0);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ jit.peek(JSInterfaceJIT::regT1);
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ReturnPC);
+
+ // Calling convention: f(ecx, edx, ...);
+ // Host function signature: f(ExecState*);
+ jit.move(JSInterfaceJIT::callFrameRegister, X86Registers::ecx);
+
+ jit.subPtr(JSInterfaceJIT::TrustedImm32(16 - sizeof(void*)), JSInterfaceJIT::stackPointerRegister); // Align stack after call.
+
+ // call the function
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::Callee, JSInterfaceJIT::regT1);
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT1, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT1);
+ jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ jit.call(JSInterfaceJIT::Address(JSInterfaceJIT::regT1, executableOffsetToFunction));
+
+ jit.addPtr(JSInterfaceJIT::TrustedImm32(16 - sizeof(void*)), JSInterfaceJIT::stackPointerRegister);
+
+#elif CPU(X86_64)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::regT0);
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT0);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ jit.peek(JSInterfaceJIT::regT1);
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ReturnPC);
+
+#if !OS(WINDOWS)
+ // Calling convention: f(edi, esi, edx, ecx, ...);
+ // Host function signature: f(ExecState*);
+ jit.move(JSInterfaceJIT::callFrameRegister, X86Registers::edi);
+
+ jit.subPtr(JSInterfaceJIT::TrustedImm32(16 - sizeof(int64_t)), JSInterfaceJIT::stackPointerRegister); // Align stack after call.
+
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::Callee, X86Registers::esi);
+ jit.loadPtr(JSInterfaceJIT::Address(X86Registers::esi, JSFunction::offsetOfExecutable()), X86Registers::r9);
+ jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ jit.call(JSInterfaceJIT::Address(X86Registers::r9, executableOffsetToFunction));
+
+ jit.addPtr(JSInterfaceJIT::TrustedImm32(16 - sizeof(int64_t)), JSInterfaceJIT::stackPointerRegister);
+#else
+ // Calling convention: f(ecx, edx, r8, r9, ...);
+ // Host function signature: f(ExecState*);
+ jit.move(JSInterfaceJIT::callFrameRegister, X86Registers::ecx);
+
+ // Leave space for the callee parameter home addresses and align the stack.
+ jit.subPtr(JSInterfaceJIT::TrustedImm32(4 * sizeof(int64_t) + 16 - sizeof(int64_t)), JSInterfaceJIT::stackPointerRegister);
+
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::Callee, X86Registers::edx);
+ jit.loadPtr(JSInterfaceJIT::Address(X86Registers::edx, JSFunction::offsetOfExecutable()), X86Registers::r9);
+ jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ jit.call(JSInterfaceJIT::Address(X86Registers::r9, executableOffsetToFunction));
+
+ jit.addPtr(JSInterfaceJIT::TrustedImm32(4 * sizeof(int64_t) + 16 - sizeof(int64_t)), JSInterfaceJIT::stackPointerRegister);
+#endif
+
+#elif CPU(ARM)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::regT2);
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT2);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3); // Callee preserved
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT3, JSStack::ReturnPC);
+
+ // Calling convention: f(r0 == regT0, r1 == regT1, ...);
+ // Host function signature: f(ExecState*);
+ jit.move(JSInterfaceJIT::callFrameRegister, ARMRegisters::r0);
+
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::Callee, ARMRegisters::r1);
+ jit.move(JSInterfaceJIT::regT2, JSInterfaceJIT::callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ jit.loadPtr(JSInterfaceJIT::Address(ARMRegisters::r1, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);
+ jit.call(JSInterfaceJIT::Address(JSInterfaceJIT::regT2, executableOffsetToFunction));
+
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
+
+#elif CPU(SH4)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::regT2);
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT2);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3); // Callee preserved
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT3, JSStack::ReturnPC);
+
+ // Calling convention: f(r0 == regT4, r1 == regT5, ...);
+ // Host function signature: f(ExecState*);
+ jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT4);
+
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::Callee, JSInterfaceJIT::regT5);
+ jit.move(JSInterfaceJIT::regT2, JSInterfaceJIT::callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::regT5, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);
+
+ jit.call(JSInterfaceJIT::Address(JSInterfaceJIT::regT2, executableOffsetToFunction), JSInterfaceJIT::regT0);
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
+
+#elif CPU(MIPS)
+ // Load caller frame's scope chain into this callframe so that whatever we call can
+ // get to its global data.
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, JSInterfaceJIT::regT0);
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, JSInterfaceJIT::regT1, JSInterfaceJIT::regT0);
+ jit.emitPutCellToCallFrameHeader(JSInterfaceJIT::regT1, JSStack::ScopeChain);
+
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT3); // Callee preserved
+ jit.emitPutToCallFrameHeader(JSInterfaceJIT::regT3, JSStack::ReturnPC);
+
+ // Calling convention: f(a0, a1, a2, a3);
+ // Host function signature: f(ExecState*);
+
+ // Allocate stack space for 16 bytes (8-byte aligned)
+ // 16 bytes (unused) for 4 arguments
+ jit.subPtr(JSInterfaceJIT::TrustedImm32(16), JSInterfaceJIT::stackPointerRegister);
+
+ // Setup arg0
+ jit.move(JSInterfaceJIT::callFrameRegister, MIPSRegisters::a0);
+
+ // Call
+ jit.emitGetFromCallFrameHeaderPtr(JSStack::Callee, MIPSRegisters::a2);
+ jit.loadPtr(JSInterfaceJIT::Address(MIPSRegisters::a2, JSFunction::offsetOfExecutable()), JSInterfaceJIT::regT2);
+ jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
+ jit.call(JSInterfaceJIT::Address(JSInterfaceJIT::regT2, executableOffsetToFunction));
+
+ // Restore stack space
+ jit.addPtr(JSInterfaceJIT::TrustedImm32(16), JSInterfaceJIT::stackPointerRegister);
+
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT3);
+#else
+#error "JIT not supported on this platform."
+ UNUSED_PARAM(executableOffsetToFunction);
+ breakpoint();
+#endif
+
+ // Check for an exception
+#if USE(JSVALUE64)
+ jit.load64(&(vm->exception), JSInterfaceJIT::regT2);
+ JSInterfaceJIT::Jump exceptionHandler = jit.branchTest64(JSInterfaceJIT::NonZero, JSInterfaceJIT::regT2);
+#else
+ JSInterfaceJIT::Jump exceptionHandler = jit.branch32(
+ JSInterfaceJIT::NotEqual,
+ JSInterfaceJIT::AbsoluteAddress(reinterpret_cast<char*>(&vm->exception) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)),
+ JSInterfaceJIT::TrustedImm32(JSValue::EmptyValueTag));
+#endif
+
+ // Return.
+ jit.ret();
+
+ // Handle an exception
+ exceptionHandler.link(&jit);
+
+ // Grab the return address.
+ jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT1);
+
+ jit.move(JSInterfaceJIT::TrustedImmPtr(&vm->exceptionLocation), JSInterfaceJIT::regT2);
+ jit.storePtr(JSInterfaceJIT::regT1, JSInterfaceJIT::regT2);
+ jit.poke(JSInterfaceJIT::callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
+
+ jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame);
+ // Set the return address.
+ jit.move(JSInterfaceJIT::TrustedImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), JSInterfaceJIT::regT1);
+ jit.restoreReturnAddressBeforeReturn(JSInterfaceJIT::regT1);
+
+ jit.ret();
+
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
+ return FINALIZE_CODE(patchBuffer, ("native %s trampoline", toCString(kind).data()));
+}
+
+MacroAssemblerCodeRef nativeCallGenerator(VM* vm)
+{
+ return nativeForGenerator(vm, CodeForCall);
+}
+
+MacroAssemblerCodeRef nativeConstructGenerator(VM* vm)
+{
+ return nativeForGenerator(vm, CodeForConstruct);
+}
+
+static void stringCharLoad(SpecializedThunkJIT& jit, VM* vm)
{
// load string
- jit.loadJSStringArgument(*globalData, SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
+ jit.loadJSStringArgument(*vm, SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
// Load string length to regT2, and start the process of loading the data pointer into regT0
jit.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringLengthOffset()), SpecializedThunkJIT::regT2);
@@ -55,9 +436,9 @@ static void stringCharLoad(SpecializedThunkJIT& jit, JSGlobalData* globalData)
SpecializedThunkJIT::JumpList is16Bit;
SpecializedThunkJIT::JumpList cont8Bit;
// Load the string flags
- jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::stringImplFlagsOffset()), SpecializedThunkJIT::regT2);
- jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::stringImplDataOffset()), SpecializedThunkJIT::regT0);
- is16Bit.append(jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT2, MacroAssembler::TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, StringImpl::flagsOffset()), SpecializedThunkJIT::regT2);
+ jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, StringImpl::dataOffset()), SpecializedThunkJIT::regT0);
+ is16Bit.append(jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT2, MacroAssembler::TrustedImm32(StringImpl::flagIs8Bit())));
jit.load8(MacroAssembler::BaseIndex(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1, MacroAssembler::TimesOne, 0), SpecializedThunkJIT::regT0);
cont8Bit.append(jit.jump());
is16Bit.link(&jit);
@@ -65,51 +446,51 @@ static void stringCharLoad(SpecializedThunkJIT& jit, JSGlobalData* globalData)
cont8Bit.link(&jit);
}
-static void charToString(SpecializedThunkJIT& jit, JSGlobalData* globalData, MacroAssembler::RegisterID src, MacroAssembler::RegisterID dst, MacroAssembler::RegisterID scratch)
+static void charToString(SpecializedThunkJIT& jit, VM* vm, MacroAssembler::RegisterID src, MacroAssembler::RegisterID dst, MacroAssembler::RegisterID scratch)
{
jit.appendFailure(jit.branch32(MacroAssembler::AboveOrEqual, src, MacroAssembler::TrustedImm32(0x100)));
- jit.move(MacroAssembler::TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), scratch);
+ jit.move(MacroAssembler::TrustedImmPtr(vm->smallStrings.singleCharacterStrings()), scratch);
jit.loadPtr(MacroAssembler::BaseIndex(scratch, src, MacroAssembler::ScalePtr, 0), dst);
jit.appendFailure(jit.branchTestPtr(MacroAssembler::Zero, dst));
}
-MacroAssemblerCodeRef charCodeAtThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef charCodeAtThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
- stringCharLoad(jit, globalData);
+ stringCharLoad(jit, vm);
jit.returnInt32(SpecializedThunkJIT::regT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charCodeAt");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "charCodeAt");
}
-MacroAssemblerCodeRef charAtThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef charAtThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
- stringCharLoad(jit, globalData);
- charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
+ stringCharLoad(jit, vm);
+ charToString(jit, vm, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
jit.returnJSCell(SpecializedThunkJIT::regT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charAt");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "charAt");
}
-MacroAssemblerCodeRef fromCharCodeThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef fromCharCodeThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
// load char code
jit.loadInt32Argument(0, SpecializedThunkJIT::regT0);
- charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
+ charToString(jit, vm, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
jit.returnJSCell(SpecializedThunkJIT::regT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "fromCharCode");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "fromCharCode");
}
-MacroAssemblerCodeRef sqrtThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef sqrtThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
if (!jit.supportsFloatingPointSqrt())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "sqrt");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "sqrt");
}
@@ -126,7 +507,7 @@ double jsRound(double d)
}
}
-
+
#if CPU(X86_64) && COMPILER(GCC) && (PLATFORM(MAC) || OS(LINUX))
#define defineUnaryDoubleOpWrapper(function) \
@@ -163,6 +544,28 @@ double jsRound(double d)
} \
static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
+#elif CPU(ARM_THUMB2) && COMPILER(GCC) && PLATFORM(IOS)
+
+#define defineUnaryDoubleOpWrapper(function) \
+ asm( \
+ ".text\n" \
+ ".align 2\n" \
+ ".globl " SYMBOL_STRING(function##Thunk) "\n" \
+ HIDE_SYMBOL(function##Thunk) "\n" \
+ ".thumb\n" \
+ ".thumb_func " THUMB_FUNC_PARAM(function##Thunk) "\n" \
+ SYMBOL_STRING(function##Thunk) ":" "\n" \
+ "push {lr}\n" \
+ "vmov r0, r1, d0\n" \
+ "blx " GLOBAL_REFERENCE(function) "\n" \
+ "vmov d0, r0, r1\n" \
+ "pop {lr}\n" \
+ "bx lr\n" \
+ ); \
+ extern "C" { \
+ MathThunkCallingConvention function##Thunk(MathThunkCallingConvention); \
+ } \
+ static MathThunk UnaryDoubleOpWrapper(function) = &function##Thunk;
#else
#define defineUnaryDoubleOpWrapper(function) \
@@ -180,12 +583,12 @@ static const double negativeHalfConstant = -0.5;
static const double zeroConstant = 0.0;
static const double halfConstant = 0.5;
-MacroAssemblerCodeRef floorThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef floorThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
MacroAssembler::Jump nonIntJump;
if (!UnaryDoubleOpWrapper(floor) || !jit.supportsFloatingPoint())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
jit.returnInt32(SpecializedThunkJIT::regT0);
nonIntJump.link(&jit);
@@ -202,40 +605,40 @@ MacroAssemblerCodeRef floorThunkGenerator(JSGlobalData* globalData)
intResult = jit.jump();
slowPath.link(&jit);
}
- jit.callDoubleToDouble(UnaryDoubleOpWrapper(floor));
+ jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(floor));
jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
if (jit.supportsFloatingPointTruncate())
intResult.link(&jit);
jit.returnInt32(SpecializedThunkJIT::regT0);
doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "floor");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "floor");
}
-MacroAssemblerCodeRef ceilThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef ceilThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
if (!UnaryDoubleOpWrapper(ceil) || !jit.supportsFloatingPoint())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
MacroAssembler::Jump nonIntJump;
jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
jit.returnInt32(SpecializedThunkJIT::regT0);
nonIntJump.link(&jit);
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
- jit.callDoubleToDouble(UnaryDoubleOpWrapper(ceil));
+ jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(ceil));
SpecializedThunkJIT::JumpList doubleResult;
jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
jit.returnInt32(SpecializedThunkJIT::regT0);
doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "ceil");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "ceil");
}
-MacroAssemblerCodeRef roundThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef roundThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
if (!UnaryDoubleOpWrapper(jsRound) || !jit.supportsFloatingPoint())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
MacroAssembler::Jump nonIntJump;
jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
jit.returnInt32(SpecializedThunkJIT::regT0);
@@ -255,47 +658,47 @@ MacroAssemblerCodeRef roundThunkGenerator(JSGlobalData* globalData)
intResult = jit.jump();
slowPath.link(&jit);
}
- jit.callDoubleToDouble(UnaryDoubleOpWrapper(jsRound));
+ jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(jsRound));
jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT1);
if (jit.supportsFloatingPointTruncate())
intResult.link(&jit);
jit.returnInt32(SpecializedThunkJIT::regT0);
doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "round");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "round");
}
-MacroAssemblerCodeRef expThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef expThunkGenerator(VM* vm)
{
if (!UnaryDoubleOpWrapper(exp))
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
SpecializedThunkJIT jit(1);
if (!jit.supportsFloatingPoint())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
- jit.callDoubleToDouble(UnaryDoubleOpWrapper(exp));
+ jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(exp));
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "exp");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "exp");
}
-MacroAssemblerCodeRef logThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef logThunkGenerator(VM* vm)
{
if (!UnaryDoubleOpWrapper(log))
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
SpecializedThunkJIT jit(1);
if (!jit.supportsFloatingPoint())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
- jit.callDoubleToDouble(UnaryDoubleOpWrapper(log));
+ jit.callDoubleToDoublePreservingReturn(UnaryDoubleOpWrapper(log));
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "log");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "log");
}
-MacroAssemblerCodeRef absThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef absThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(1);
if (!jit.supportsFloatingPointAbs())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
MacroAssembler::Jump nonIntJump;
jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntJump);
jit.rshift32(SpecializedThunkJIT::regT0, MacroAssembler::TrustedImm32(31), SpecializedThunkJIT::regT1);
@@ -308,14 +711,14 @@ MacroAssemblerCodeRef absThunkGenerator(JSGlobalData* globalData)
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
jit.absDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
jit.returnDouble(SpecializedThunkJIT::fpRegT1);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "abs");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "abs");
}
-MacroAssemblerCodeRef powThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef powThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(2);
if (!jit.supportsFloatingPoint())
- return MacroAssemblerCodeRef::createSelfManagedCodeRef(globalData->jitStubs->ctiNativeCall());
+ return MacroAssemblerCodeRef::createSelfManagedCodeRef(vm->jitStubs->ctiNativeCall(vm));
jit.loadDouble(&oneConstant, SpecializedThunkJIT::fpRegT1);
jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
@@ -360,7 +763,40 @@ MacroAssemblerCodeRef powThunkGenerator(JSGlobalData* globalData)
} else
jit.appendFailure(nonIntExponent);
- return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "pow");
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "pow");
+}
+
+MacroAssemblerCodeRef imulThunkGenerator(VM* vm)
+{
+ SpecializedThunkJIT jit(2);
+ MacroAssembler::Jump nonIntArg0Jump;
+ jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntArg0Jump);
+ SpecializedThunkJIT::Label doneLoadingArg0(&jit);
+ MacroAssembler::Jump nonIntArg1Jump;
+ jit.loadInt32Argument(1, SpecializedThunkJIT::regT1, nonIntArg1Jump);
+ SpecializedThunkJIT::Label doneLoadingArg1(&jit);
+ jit.mul32(SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT0);
+ jit.returnInt32(SpecializedThunkJIT::regT0);
+
+ if (jit.supportsFloatingPointTruncate()) {
+ nonIntArg0Jump.link(&jit);
+ jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+ jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::BranchIfTruncateSuccessful).linkTo(doneLoadingArg0, &jit);
+ jit.xor32(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0);
+ jit.jump(doneLoadingArg0);
+ } else
+ jit.appendFailure(nonIntArg0Jump);
+
+ if (jit.supportsFloatingPointTruncate()) {
+ nonIntArg1Jump.link(&jit);
+ jit.loadDoubleArgument(1, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT1);
+ jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT1, SpecializedThunkJIT::BranchIfTruncateSuccessful).linkTo(doneLoadingArg1, &jit);
+ jit.xor32(SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT1);
+ jit.jump(doneLoadingArg1);
+ } else
+ jit.appendFailure(nonIntArg1Jump);
+
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "imul");
}
}
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.h b/Source/JavaScriptCore/jit/ThunkGenerators.h
index b251f6be8..a4b0fc4b3 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.h
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,26 +26,34 @@
#ifndef ThunkGenerators_h
#define ThunkGenerators_h
+#include "ThunkGenerator.h"
+
#if ENABLE(JIT)
namespace JSC {
- class ExecutablePool;
- class JSGlobalData;
- class NativeExecutable;
- class MacroAssemblerCodeRef;
- typedef MacroAssemblerCodeRef (*ThunkGenerator)(JSGlobalData*);
- MacroAssemblerCodeRef charCodeAtThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef charAtThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef fromCharCodeThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef absThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef ceilThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef expThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef floorThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef logThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef roundThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef sqrtThunkGenerator(JSGlobalData*);
- MacroAssemblerCodeRef powThunkGenerator(JSGlobalData*);
+MacroAssemblerCodeRef linkCallGenerator(VM*);
+MacroAssemblerCodeRef linkConstructGenerator(VM*);
+MacroAssemblerCodeRef linkClosureCallGenerator(VM*);
+MacroAssemblerCodeRef virtualCallGenerator(VM*);
+MacroAssemblerCodeRef virtualConstructGenerator(VM*);
+MacroAssemblerCodeRef stringLengthTrampolineGenerator(VM*);
+MacroAssemblerCodeRef nativeCallGenerator(VM*);
+MacroAssemblerCodeRef nativeConstructGenerator(VM*);
+
+MacroAssemblerCodeRef charCodeAtThunkGenerator(VM*);
+MacroAssemblerCodeRef charAtThunkGenerator(VM*);
+MacroAssemblerCodeRef fromCharCodeThunkGenerator(VM*);
+MacroAssemblerCodeRef absThunkGenerator(VM*);
+MacroAssemblerCodeRef ceilThunkGenerator(VM*);
+MacroAssemblerCodeRef expThunkGenerator(VM*);
+MacroAssemblerCodeRef floorThunkGenerator(VM*);
+MacroAssemblerCodeRef logThunkGenerator(VM*);
+MacroAssemblerCodeRef roundThunkGenerator(VM*);
+MacroAssemblerCodeRef sqrtThunkGenerator(VM*);
+MacroAssemblerCodeRef powThunkGenerator(VM*);
+MacroAssemblerCodeRef imulThunkGenerator(VM*);
+
}
-#endif
+#endif // ENABLE(JIT)
#endif // ThunkGenerator_h
diff --git a/Source/JavaScriptCore/jit/UnusedPointer.h b/Source/JavaScriptCore/jit/UnusedPointer.h
new file mode 100644
index 000000000..af41248d6
--- /dev/null
+++ b/Source/JavaScriptCore/jit/UnusedPointer.h
@@ -0,0 +1,37 @@
+/*
+ * 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 UnusedPointer_h
+#define UnusedPointer_h
+
+namespace JSC {
+
+static const uintptr_t unusedPointer = 0xd1e7beef;
+
+} // namespace JSC
+
+using JSC::unusedPointer;
+
+#endif // UnusedPointer_h
diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp
index 9db4eba86..4404faa9e 100644
--- a/Source/JavaScriptCore/jsc.cpp
+++ b/Source/JavaScriptCore/jsc.cpp
@@ -22,6 +22,7 @@
#include "config.h"
+#include "APIShims.h"
#include "ButterflyInlines.h"
#include "BytecodeGenerator.h"
#include "Completion.h"
@@ -36,13 +37,16 @@
#include "JSLock.h"
#include "JSProxy.h"
#include "JSString.h"
+#include "Operations.h"
#include "SamplingTool.h"
+#include "StructureRareDataInlines.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
+#include <wtf/StringPrintStream.h>
#include <wtf/text/StringBuilder.h>
#if !OS(WINDOWS)
@@ -82,6 +86,14 @@
#include <arm/arch.h>
#endif
+#if PLATFORM(BLACKBERRY)
+#include <BlackBerryPlatformLog.h>
+#endif
+
+#if PLATFORM(EFL)
+#include <Ecore.h>
+#endif
+
using namespace JSC;
using namespace WTF;
@@ -126,6 +138,7 @@ public:
: m_interactive(false)
, m_dump(false)
, m_exitCode(false)
+ , m_profile(false)
{
parseArguments(argc, argv);
}
@@ -135,11 +148,13 @@ public:
bool m_exitCode;
Vector<Script> m_scripts;
Vector<String> m_arguments;
+ bool m_profile;
+ String m_profilerOutput;
void parseArguments(int, char**);
};
-static const char interactivePrompt[] = "> ";
+static const char interactivePrompt[] = ">>> ";
class StopWatch {
public:
@@ -169,17 +184,17 @@ long StopWatch::getElapsedMS()
class GlobalObject : public JSGlobalObject {
private:
- GlobalObject(JSGlobalData&, Structure*);
+ GlobalObject(VM&, Structure*);
public:
typedef JSGlobalObject Base;
- static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<String>& arguments)
+ static GlobalObject* create(VM& vm, Structure* structure, const Vector<String>& arguments)
{
- GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure);
- object->finishCreation(globalData, arguments);
- globalData.heap.addFinalizer(object, destroy);
- object->setGlobalThis(globalData, JSProxy::create(globalData, JSProxy::createStructure(globalData, object, object->prototype()), object));
+ GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure);
+ object->finishCreation(vm, arguments);
+ vm.heap.addFinalizer(object, destroy);
+ object->setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, object, object->prototype()), object));
return object;
}
@@ -188,65 +203,65 @@ public:
static const ClassInfo s_info;
static const GlobalObjectMethodTable s_globalObjectMethodTable;
- static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSValue prototype)
{
- return Structure::create(globalData, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
}
static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return true; }
protected:
- void finishCreation(JSGlobalData& globalData, const Vector<String>& arguments)
+ void finishCreation(VM& vm, const Vector<String>& arguments)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
- addFunction(globalData, "debug", functionDebug, 1);
- addFunction(globalData, "describe", functionDescribe, 1);
- addFunction(globalData, "print", functionPrint, 1);
- addFunction(globalData, "quit", functionQuit, 0);
- addFunction(globalData, "gc", functionGC, 0);
+ addFunction(vm, "debug", functionDebug, 1);
+ addFunction(vm, "describe", functionDescribe, 1);
+ addFunction(vm, "print", functionPrint, 1);
+ addFunction(vm, "quit", functionQuit, 0);
+ addFunction(vm, "gc", functionGC, 0);
#ifndef NDEBUG
- addFunction(globalData, "dumpCallFrame", functionDumpCallFrame, 0);
- addFunction(globalData, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
-#endif
- addFunction(globalData, "version", functionVersion, 1);
- addFunction(globalData, "run", functionRun, 1);
- addFunction(globalData, "load", functionLoad, 1);
- addFunction(globalData, "checkSyntax", functionCheckSyntax, 1);
- addFunction(globalData, "jscStack", functionJSCStack, 1);
- addFunction(globalData, "readline", functionReadline, 0);
- addFunction(globalData, "preciseTime", functionPreciseTime, 0);
+ addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
+ addFunction(vm, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
+#endif
+ addFunction(vm, "version", functionVersion, 1);
+ addFunction(vm, "run", functionRun, 1);
+ addFunction(vm, "load", functionLoad, 1);
+ addFunction(vm, "checkSyntax", functionCheckSyntax, 1);
+ addFunction(vm, "jscStack", functionJSCStack, 1);
+ addFunction(vm, "readline", functionReadline, 0);
+ addFunction(vm, "preciseTime", functionPreciseTime, 0);
#if ENABLE(SAMPLING_FLAGS)
- addFunction(globalData, "setSamplingFlags", functionSetSamplingFlags, 1);
- addFunction(globalData, "clearSamplingFlags", functionClearSamplingFlags, 1);
+ addFunction(vm, "setSamplingFlags", functionSetSamplingFlags, 1);
+ addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1);
#endif
- addConstructableFunction(globalData, "Uint8Array", constructJSUint8Array, 1);
- addConstructableFunction(globalData, "Uint8ClampedArray", constructJSUint8ClampedArray, 1);
- addConstructableFunction(globalData, "Uint16Array", constructJSUint16Array, 1);
- addConstructableFunction(globalData, "Uint32Array", constructJSUint32Array, 1);
- addConstructableFunction(globalData, "Int8Array", constructJSInt8Array, 1);
- addConstructableFunction(globalData, "Int16Array", constructJSInt16Array, 1);
- addConstructableFunction(globalData, "Int32Array", constructJSInt32Array, 1);
- addConstructableFunction(globalData, "Float32Array", constructJSFloat32Array, 1);
- addConstructableFunction(globalData, "Float64Array", constructJSFloat64Array, 1);
+ addConstructableFunction(vm, "Uint8Array", constructJSUint8Array, 1);
+ addConstructableFunction(vm, "Uint8ClampedArray", constructJSUint8ClampedArray, 1);
+ addConstructableFunction(vm, "Uint16Array", constructJSUint16Array, 1);
+ addConstructableFunction(vm, "Uint32Array", constructJSUint32Array, 1);
+ addConstructableFunction(vm, "Int8Array", constructJSInt8Array, 1);
+ addConstructableFunction(vm, "Int16Array", constructJSInt16Array, 1);
+ addConstructableFunction(vm, "Int32Array", constructJSInt32Array, 1);
+ addConstructableFunction(vm, "Float32Array", constructJSFloat32Array, 1);
+ addConstructableFunction(vm, "Float64Array", constructJSFloat64Array, 1);
JSArray* array = constructEmptyArray(globalExec(), 0);
for (size_t i = 0; i < arguments.size(); ++i)
array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]));
- putDirect(globalData, Identifier(globalExec(), "arguments"), array);
+ putDirect(vm, Identifier(globalExec(), "arguments"), array);
}
- void addFunction(JSGlobalData& globalData, const char* name, NativeFunction function, unsigned arguments)
+ void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
{
Identifier identifier(globalExec(), name);
- putDirect(globalData, identifier, JSFunction::create(globalExec(), this, arguments, identifier.string(), function));
+ putDirect(vm, identifier, JSFunction::create(globalExec(), this, arguments, identifier.string(), function));
}
- void addConstructableFunction(JSGlobalData& globalData, const char* name, NativeFunction function, unsigned arguments)
+ void addConstructableFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
{
Identifier identifier(globalExec(), name);
- putDirect(globalData, identifier, JSFunction::create(globalExec(), this, arguments, identifier.string(), function, NoIntrinsic, function));
+ putDirect(vm, identifier, JSFunction::create(globalExec(), this, arguments, identifier.string(), function, NoIntrinsic, function));
}
};
@@ -256,28 +271,33 @@ const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, 0, E
const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled };
-GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure)
- : JSGlobalObject(globalData, structure, &s_globalObjectMethodTable)
+GlobalObject::GlobalObject(VM& vm, Structure* structure)
+ : JSGlobalObject(vm, structure, &s_globalObjectMethodTable)
{
}
-static inline SourceCode jscSource(const char* utf8, const String& filename)
+static inline String stringFromUTF(const char* utf8)
{
// Find the the first non-ascii character, or nul.
const char* pos = utf8;
while (*pos > 0)
pos++;
size_t asciiLength = pos - utf8;
-
+
// Fast case - string is all ascii.
if (!*pos)
- return makeSource(String(utf8, asciiLength), filename);
-
+ return String(utf8, asciiLength);
+
// Slow case - contains non-ascii characters, use fromUTF8WithLatin1Fallback.
ASSERT(*pos < 0);
ASSERT(strlen(utf8) == asciiLength + strlen(pos));
- String source = String::fromUTF8WithLatin1Fallback(utf8, asciiLength + strlen(pos));
- return makeSource(source.impl(), filename);
+ return String::fromUTF8WithLatin1Fallback(utf8, asciiLength + strlen(pos));
+}
+
+static inline SourceCode jscSource(const char* utf8, const String& filename)
+{
+ String str = stringFromUTF(utf8);
+ return makeSource(str, filename);
}
EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
@@ -298,7 +318,7 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec)
{
if (!exec->callerFrame()->hasHostCallFrameFlag())
- exec->globalData().interpreter->dumpCallFrame(exec->callerFrame());
+ exec->vm().interpreter->dumpCallFrame(exec->callerFrame());
return JSValue::encode(jsUndefined());
}
#endif
@@ -311,7 +331,7 @@ EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec)
EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState* exec)
{
- fprintf(stderr, "--> %s\n", exec->argument(0).description());
+ fprintf(stderr, "--> %s\n", toCString(exec->argument(0)).data());
return JSValue::encode(jsUndefined());
}
@@ -321,7 +341,7 @@ EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec)
trace.appendLiteral("--> Stack trace:\n");
Vector<StackFrame> stackTrace;
- Interpreter::getStackTrace(&exec->globalData(), stackTrace);
+ Interpreter::getStackTrace(&exec->vm(), stackTrace);
int i = 0;
for (Vector<StackFrame>::iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) {
@@ -344,7 +364,7 @@ EncodedJSValue JSC_HOST_CALL functionGC(ExecState* exec)
EncodedJSValue JSC_HOST_CALL functionReleaseExecutableMemory(ExecState* exec)
{
JSLockHolder lock(exec);
- exec->globalData().releaseExecutableMemory();
+ exec->vm().releaseExecutableMemory();
return JSValue::encode(jsUndefined());
}
#endif
@@ -363,7 +383,7 @@ EncodedJSValue JSC_HOST_CALL functionRun(ExecState* exec)
if (!fillBufferWithContentsOfFile(fileName, script))
return JSValue::encode(throwError(exec, createError(exec, "Could not open file.")));
- GlobalObject* globalObject = GlobalObject::create(exec->globalData(), GlobalObject::createStructure(exec->globalData(), jsNull()), Vector<String>());
+ GlobalObject* globalObject = GlobalObject::create(exec->vm(), GlobalObject::createStructure(exec->vm(), jsNull()), Vector<String>());
JSValue exception;
StopWatch stopWatch;
@@ -512,11 +532,20 @@ int main(int argc, char** argv)
timeBeginPeriod(1);
#endif
+#if PLATFORM(BLACKBERRY)
+ // Write all WTF logs to the system log
+ BlackBerry::Platform::setupApplicationLogging("jsc");
+#endif
+
#if PLATFORM(QT)
QCoreApplication app(argc, argv);
#endif
- // Initialize JSC before getting JSGlobalData.
+#if PLATFORM(EFL)
+ ecore_init();
+#endif
+
+ // Initialize JSC before getting VM.
#if ENABLE(SAMPLING_REGIONS)
WTF::initializeMainThread();
#endif
@@ -530,6 +559,11 @@ int main(int argc, char** argv)
EXCEPT(res = 3)
if (Options::logHeapStatisticsAtExit())
HeapStatistics::reportSuccess();
+
+#if PLATFORM(EFL)
+ ecore_shutdown();
+#endif
+
return res;
}
@@ -542,7 +576,7 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
if (dump)
JSC::Options::dumpGeneratedBytecodes() = true;
- JSGlobalData& globalData = globalObject->globalData();
+ VM& vm = globalObject->vm();
#if ENABLE(SAMPLING_FLAGS)
SamplingFlags::start();
@@ -560,7 +594,7 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
fileName = "[Command Line]";
}
- globalData.startSampling();
+ vm.startSampling();
JSValue evaluationException;
JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(script, fileName), JSValue(), &evaluationException);
@@ -575,7 +609,7 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
printf("%s\n", stackValue.toString(globalObject->globalExec())->value(globalObject->globalExec()).utf8().data());
}
- globalData.stopSampling();
+ vm.stopSampling();
globalObject->globalExec()->clearException();
}
@@ -585,12 +619,12 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
#if ENABLE(SAMPLING_REGIONS)
SamplingRegion::dump();
#endif
- globalData.dumpSampleData(globalObject->globalExec());
+ vm.dumpSampleData(globalObject->globalExec());
#if ENABLE(SAMPLING_COUNTERS)
AbstractSamplingCounter::dump();
#endif
#if ENABLE(REGEXP_TRACING)
- globalData.dumpRegExpTrace();
+ vm.dumpRegExpTrace();
#endif
return success;
}
@@ -600,17 +634,34 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
static void runInteractive(GlobalObject* globalObject)
{
String interpreterName("Interpreter");
-
- while (true) {
+
+ bool shouldQuit = false;
+ while (!shouldQuit) {
#if HAVE(READLINE) && !RUNNING_FROM_XCODE
- char* line = readline(interactivePrompt);
- if (!line)
- break;
- if (line[0])
+ ParserError error;
+ String source;
+ do {
+ error = ParserError();
+ char* line = readline(source.isEmpty() ? interactivePrompt : "... ");
+ shouldQuit = !line;
+ if (!line)
+ break;
+ source = source + line;
+ source = source + '\n';
+ checkSyntax(globalObject->vm(), makeSource(source, interpreterName), error);
+ if (!line[0])
+ break;
add_history(line);
+ } while (error.m_syntaxErrorType == ParserError::SyntaxErrorRecoverable);
+
+ if (error.m_type != ParserError::ErrorNone) {
+ printf("%s:%d\n", error.m_message.utf8().data(), error.m_line);
+ continue;
+ }
+
+
JSValue evaluationException;
- JSValue returnValue = evaluate(globalObject->globalExec(), jscSource(line, interpreterName), JSValue(), &evaluationException);
- free(line);
+ JSValue returnValue = evaluate(globalObject->globalExec(), makeSource(source, interpreterName), JSValue(), &evaluationException);
#else
printf("%s", interactivePrompt);
Vector<char, 256> line;
@@ -649,6 +700,7 @@ static NO_RETURN void printUsageStatement(bool help = false)
#if HAVE(SIGNAL_H)
fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
#endif
+ fprintf(stderr, " -p <file> Outputs profiling data to a file\n");
fprintf(stderr, " -x Output exit code before terminating\n");
fprintf(stderr, "\n");
fprintf(stderr, " --options Dumps all JSC VM options and exits\n");
@@ -687,6 +739,13 @@ void CommandLine::parseArguments(int argc, char** argv)
m_dump = true;
continue;
}
+ if (!strcmp(arg, "-p")) {
+ if (++i == argc)
+ printUsageStatement();
+ m_profile = true;
+ m_profilerOutput = argv[i];
+ continue;
+ }
if (!strcmp(arg, "-s")) {
#if HAVE(SIGNAL_H)
signal(SIGILL, _exit);
@@ -743,14 +802,17 @@ void CommandLine::parseArguments(int argc, char** argv)
int jscmain(int argc, char** argv)
{
- // Note that the options parsing can affect JSGlobalData creation, and thus
+ // Note that the options parsing can affect VM creation, and thus
// comes first.
CommandLine options(argc, argv);
- RefPtr<JSGlobalData> globalData = JSGlobalData::create(LargeHeap);
- JSLockHolder lock(globalData.get());
+ VM* vm = VM::create(LargeHeap).leakRef();
+ APIEntryShim shim(vm);
int result;
- GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.m_arguments);
+ if (options.m_profile && !vm->m_perBytecodeProfiler)
+ vm->m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*vm));
+
+ GlobalObject* globalObject = GlobalObject::create(*vm, GlobalObject::createStructure(*vm, jsNull()), options.m_arguments);
bool success = runWithScripts(globalObject, options.m_scripts, options.m_dump);
if (options.m_interactive && success)
runInteractive(globalObject);
@@ -759,6 +821,11 @@ int jscmain(int argc, char** argv)
if (options.m_exitCode)
printf("jsc exiting %d\n", result);
+
+ if (options.m_profile) {
+ if (!vm->m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))
+ fprintf(stderr, "could not save profiler output.\n");
+ }
return result;
}
diff --git a/Source/JavaScriptCore/llint/LLIntCLoop.h b/Source/JavaScriptCore/llint/LLIntCLoop.h
index 3a9c77b6d..231e52f66 100644
--- a/Source/JavaScriptCore/llint/LLIntCLoop.h
+++ b/Source/JavaScriptCore/llint/LLIntCLoop.h
@@ -29,7 +29,7 @@
#if ENABLE(LLINT_C_LOOP)
#include "CodeSpecializationKind.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "MacroAssemblerCodeRef.h"
#include "Opcode.h"
#include "Register.h"
diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp
index 90faff2ee..079bf3cec 100644
--- a/Source/JavaScriptCore/llint/LLIntData.cpp
+++ b/Source/JavaScriptCore/llint/LLIntData.cpp
@@ -62,9 +62,9 @@ void initialize()
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#endif
-void Data::performAssertions(JSGlobalData& globalData)
+void Data::performAssertions(VM& vm)
{
- UNUSED_PARAM(globalData);
+ UNUSED_PARAM(vm);
// Assertions to match LowLevelInterpreter.asm. If you change any of this code, be
// prepared to change LowLevelInterpreter.asm as well!!
@@ -107,11 +107,6 @@ void Data::performAssertions(JSGlobalData& globalData)
ASSERT(MasqueradesAsUndefined == 1);
ASSERT(ImplementsHasInstance == 2);
ASSERT(ImplementsDefaultHasInstance == 8);
-#if USE(JSVALUE64)
- ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1);
-#else
- ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3);
-#endif
ASSERT(FirstConstantRegisterIndex == 0x40000000);
ASSERT(GlobalCode == 0);
ASSERT(EvalCode == 1);
@@ -121,11 +116,11 @@ void Data::performAssertions(JSGlobalData& globalData)
#if !ASSERT_DISABLED
Vector<int> testVector;
testVector.resize(42);
- ASSERT(bitwise_cast<size_t*>(&testVector)[0] == 42);
- ASSERT(bitwise_cast<int**>(&testVector)[1] == testVector.begin());
+ ASSERT(bitwise_cast<uint32_t*>(&testVector)[sizeof(void*)/sizeof(uint32_t) + 1] == 42);
+ ASSERT(bitwise_cast<int**>(&testVector)[0] == testVector.begin());
#endif
- ASSERT(StringImpl::s_hashFlag8BitBuffer == 64);
+ ASSERT(StringImpl::s_hashFlag8BitBuffer == 32);
}
#if COMPILER(CLANG)
#pragma clang diagnostic pop
diff --git a/Source/JavaScriptCore/llint/LLIntData.h b/Source/JavaScriptCore/llint/LLIntData.h
index 3b3b6027f..8ed2bceda 100644
--- a/Source/JavaScriptCore/llint/LLIntData.h
+++ b/Source/JavaScriptCore/llint/LLIntData.h
@@ -26,13 +26,13 @@
#ifndef LLIntData_h
#define LLIntData_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "Opcode.h"
#include <wtf/Platform.h>
namespace JSC {
-class JSGlobalData;
+class VM;
struct Instruction;
#if ENABLE(LLINT_C_LOOP)
@@ -47,7 +47,7 @@ namespace LLInt {
class Data {
public:
- static void performAssertions(JSGlobalData&);
+ static void performAssertions(VM&);
private:
static Instruction* s_exceptionInstructions;
@@ -96,7 +96,7 @@ ALWAYS_INLINE void* getCodePtr(OpcodeID id)
class Data {
public:
- static void performAssertions(JSGlobalData&) { }
+ static void performAssertions(VM&) { }
};
#if COMPILER(CLANG)
diff --git a/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp b/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
index be79134b7..c044568b5 100644
--- a/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
+++ b/Source/JavaScriptCore/llint/LLIntEntrypoints.cpp
@@ -29,7 +29,7 @@
#if ENABLE(LLINT)
#include "JITCode.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSObject.h"
#include "LLIntThunks.h"
#include "LowLevelInterpreter.h"
@@ -37,9 +37,9 @@
namespace JSC { namespace LLInt {
-void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind, JITCode& jitCode, MacroAssemblerCodePtr& arityCheck)
+void getFunctionEntrypoint(VM& vm, CodeSpecializationKind kind, JITCode& jitCode, MacroAssemblerCodePtr& arityCheck)
{
- if (!globalData.canUseJIT()) {
+ if (!vm.canUseJIT()) {
if (kind == CodeForCall) {
jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_function_for_call_prologue), JITCode::InterpreterThunk);
arityCheck = MacroAssemblerCodePtr::createLLIntCodePtr(llint_function_for_call_arity_check);
@@ -54,36 +54,36 @@ void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind
#if ENABLE(JIT)
if (kind == CodeForCall) {
- jitCode = JITCode(globalData.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk);
- arityCheck = globalData.getCTIStub(functionForCallArityCheckThunkGenerator).code();
+ jitCode = JITCode(vm.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk);
+ arityCheck = vm.getCTIStub(functionForCallArityCheckThunkGenerator).code();
return;
}
ASSERT(kind == CodeForConstruct);
- jitCode = JITCode(globalData.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk);
- arityCheck = globalData.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
+ jitCode = JITCode(vm.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk);
+ arityCheck = vm.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
#endif // ENABLE(JIT)
}
-void getEvalEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
+void getEvalEntrypoint(VM& vm, JITCode& jitCode)
{
- if (!globalData.canUseJIT()) {
+ if (!vm.canUseJIT()) {
jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_eval_prologue), JITCode::InterpreterThunk);
return;
}
#if ENABLE(JIT)
- jitCode = JITCode(globalData.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk);
+ jitCode = JITCode(vm.getCTIStub(evalEntryThunkGenerator), JITCode::InterpreterThunk);
#endif
}
-void getProgramEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
+void getProgramEntrypoint(VM& vm, JITCode& jitCode)
{
- if (!globalData.canUseJIT()) {
+ if (!vm.canUseJIT()) {
jitCode = JITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk);
return;
}
#if ENABLE(JIT)
- jitCode = JITCode(globalData.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk);
+ jitCode = JITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk);
#endif
}
diff --git a/Source/JavaScriptCore/llint/LLIntEntrypoints.h b/Source/JavaScriptCore/llint/LLIntEntrypoints.h
index dd7c27798..1cecba0a6 100644
--- a/Source/JavaScriptCore/llint/LLIntEntrypoints.h
+++ b/Source/JavaScriptCore/llint/LLIntEntrypoints.h
@@ -36,25 +36,25 @@ namespace JSC {
class EvalCodeBlock;
class JITCode;
-class JSGlobalData;
+class VM;
class MacroAssemblerCodePtr;
class MacroAssemblerCodeRef;
class ProgramCodeBlock;
namespace LLInt {
-void getFunctionEntrypoint(JSGlobalData&, CodeSpecializationKind, JITCode&, MacroAssemblerCodePtr& arityCheck);
-void getEvalEntrypoint(JSGlobalData&, JITCode&);
-void getProgramEntrypoint(JSGlobalData&, JITCode&);
+void getFunctionEntrypoint(VM&, CodeSpecializationKind, JITCode&, MacroAssemblerCodePtr& arityCheck);
+void getEvalEntrypoint(VM&, JITCode&);
+void getProgramEntrypoint(VM&, JITCode&);
-inline void getEntrypoint(JSGlobalData& globalData, EvalCodeBlock*, JITCode& jitCode)
+inline void getEntrypoint(VM& vm, EvalCodeBlock*, JITCode& jitCode)
{
- getEvalEntrypoint(globalData, jitCode);
+ getEvalEntrypoint(vm, jitCode);
}
-inline void getEntrypoint(JSGlobalData& globalData, ProgramCodeBlock*, JITCode& jitCode)
+inline void getEntrypoint(VM& vm, ProgramCodeBlock*, JITCode& jitCode)
{
- getProgramEntrypoint(globalData, jitCode);
+ getProgramEntrypoint(vm, jitCode);
}
} } // namespace JSC::LLInt
diff --git a/Source/JavaScriptCore/llint/LLIntExceptions.cpp b/Source/JavaScriptCore/llint/LLIntExceptions.cpp
index 17c15aa51..d88c16e7e 100644
--- a/Source/JavaScriptCore/llint/LLIntExceptions.cpp
+++ b/Source/JavaScriptCore/llint/LLIntExceptions.cpp
@@ -34,6 +34,7 @@
#include "JITExceptions.h"
#include "LLIntCommon.h"
#include "LowLevelInterpreter.h"
+#include "Operations.h"
namespace JSC { namespace LLInt {
@@ -47,14 +48,14 @@ static void fixupPCforExceptionIfNeeded(ExecState* exec)
void interpreterThrowInCaller(ExecState* exec, ReturnAddressPtr pc)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLog("Throwing exception ", globalData->exception, ".\n");
+ dataLog("Throwing exception ", vm->exception, ".\n");
#endif
fixupPCforExceptionIfNeeded(exec);
genericThrow(
- globalData, exec, globalData->exception,
+ vm, exec, vm->exception,
exec->codeBlock()->bytecodeOffset(exec, pc));
}
@@ -64,29 +65,31 @@ Instruction* returnToThrowForThrownException(ExecState* exec)
return LLInt::exceptionInstructions();
}
+static void doThrow(ExecState* exec, Instruction* pc)
+{
+ VM* vm = &exec->vm();
+ NativeCallFrameTracer tracer(vm, exec);
+ fixupPCforExceptionIfNeeded(exec);
+ genericThrow(vm, exec, vm->exception, pc - exec->codeBlock()->instructions().begin());
+}
+
Instruction* returnToThrow(ExecState* exec, Instruction* pc)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLog("Throwing exception ", globalData->exception, " (returnToThrow).\n");
+ VM* vm = &exec->vm();
+ dataLog("Throwing exception ", vm->exception, " (returnToThrow).\n");
#endif
- fixupPCforExceptionIfNeeded(exec);
- genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
-
+ doThrow(exec, pc);
return LLInt::exceptionInstructions();
}
void* callToThrow(ExecState* exec, Instruction* pc)
{
- JSGlobalData* globalData = &exec->globalData();
- NativeCallFrameTracer tracer(globalData, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLog("Throwing exception ", globalData->exception, " (callToThrow).\n");
+ VM* vm = &exec->vm();
+ dataLog("Throwing exception ", vm->exception, " (callToThrow).\n");
#endif
- fixupPCforExceptionIfNeeded(exec);
- genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
-
+ doThrow(exec, pc);
return LLInt::getCodePtr(llint_throw_during_call_trampoline);
}
diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
index 157521373..bad62ddf8 100644
--- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
+++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
@@ -35,10 +35,13 @@
#if ENABLE(LLINT_C_LOOP)
#define OFFLINE_ASM_C_LOOP 1
#define OFFLINE_ASM_X86 0
+#define OFFLINE_ASM_ARM 0
#define OFFLINE_ASM_ARMv7 0
+#define OFFLINE_ASM_ARMv7_TRADITIONAL 0
#define OFFLINE_ASM_X86_64 0
#define OFFLINE_ASM_ARMv7s 0
#define OFFLINE_ASM_MIPS 0
+#define OFFLINE_ASM_SH4 0
#else // !ENABLE(LLINT_C_LOOP)
@@ -62,6 +65,19 @@
#define OFFLINE_ASM_ARMv7 0
#endif
+#if CPU(ARM_TRADITIONAL)
+#if WTF_ARM_ARCH_AT_LEAST(7)
+#define OFFLINE_ASM_ARMv7_TRADITIONAL 1
+#define OFFLINE_ASM_ARM 0
+#else
+#define OFFLINE_ASM_ARM 1
+#define OFFLINE_ASM_ARMv7_TRADITIONAL 0
+#endif
+#else
+#define OFFLINE_ASM_ARMv7_TRADITIONAL 0
+#define OFFLINE_ASM_ARM 0
+#endif
+
#if CPU(X86_64)
#define OFFLINE_ASM_X86_64 1
#else
@@ -74,6 +90,12 @@
#define OFFLINE_ASM_MIPS 0
#endif
+#if CPU(SH4)
+#define OFFLINE_ASM_SH4 1
+#else
+#define OFFLINE_ASM_SH4 0
+#endif
+
#endif // !ENABLE(LLINT_C_LOOP)
#if USE(JSVALUE64)
diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
index 0087fe5ff..0cd2f68a1 100644
--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
@@ -34,7 +34,7 @@
#include "JSArray.h"
#include "JSCell.h"
#include "JSFunction.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "JSPropertyNameIterator.h"
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 0bd19d46f..36a43f586 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,22 +38,25 @@
#include "JIT.h"
#include "JITDriver.h"
#include "JSActivation.h"
+#include "JSCJSValue.h"
#include "JSGlobalObjectFunctions.h"
#include "JSNameScope.h"
#include "JSPropertyNameIterator.h"
#include "JSString.h"
-#include "JSValue.h"
#include "JSWithScope.h"
#include "LLIntCommon.h"
#include "LLIntExceptions.h"
#include "LowLevelInterpreter.h"
+#include "ObjectConstructor.h"
#include "Operations.h"
+#include "StructureRareDataInlines.h"
+#include <wtf/StringPrintStream.h>
namespace JSC { namespace LLInt {
#define LLINT_BEGIN_NO_SET_PC() \
- JSGlobalData& globalData = exec->globalData(); \
- NativeCallFrameTracer tracer(&globalData, exec)
+ VM& vm = exec->vm(); \
+ NativeCallFrameTracer tracer(&vm, exec)
#ifndef NDEBUG
#define LLINT_SET_PC_FOR_STUBS() do { \
@@ -80,13 +83,13 @@ namespace JSC { namespace LLInt {
#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
#define LLINT_THROW(exceptionToThrow) do { \
- globalData.exception = (exceptionToThrow); \
+ vm.exception = (exceptionToThrow); \
pc = returnToThrow(exec, pc); \
LLINT_END_IMPL(); \
} while (false)
#define LLINT_CHECK_EXCEPTION() do { \
- if (UNLIKELY(globalData.exception)) { \
+ if (UNLIKELY(vm.exception)) { \
pc = returnToThrow(exec, pc); \
LLINT_END_IMPL(); \
} \
@@ -140,14 +143,14 @@ namespace JSC { namespace LLInt {
#define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
ExecState* __ct_exec = (exec); \
Instruction* __ct_pc = (pc); \
- globalData.exception = (exceptionToThrow); \
+ vm.exception = (exceptionToThrow); \
LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
} while (false)
#define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
ExecState* __cce_exec = (exec); \
Instruction* __cce_pc = (pc); \
- if (UNLIKELY(globalData.exception)) \
+ if (UNLIKELY(vm.exception)) \
LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
} while (false)
@@ -166,7 +169,7 @@ extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction*
exec->codeBlock(),
exec,
static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
- exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
+ exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
fromWhere,
operand,
pc[operand].u.operand);
@@ -184,17 +187,18 @@ extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc
EncodedJSValue asValue;
} u;
u.asValue = JSValue::encode(value);
- dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
- exec->codeBlock(),
- exec,
- static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
- exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
- fromWhere,
- operand,
- pc[operand].u.operand,
- u.bits.tag,
- u.bits.payload,
- value.description());
+ dataLogF(
+ "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
+ exec->codeBlock(),
+ exec,
+ static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
+ exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
+ fromWhere,
+ operand,
+ pc[operand].u.operand,
+ u.bits.tag,
+ u.bits.payload,
+ toCString(value).data());
LLINT_END_IMPL();
}
@@ -245,9 +249,9 @@ LLINT_SLOW_PATH_DECL(trace)
exec->codeBlock(),
exec,
static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
- opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)],
+ opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
exec->scope());
- if (exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
+ if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
dataLogF("Will be returning to %p\n", exec->returnPC().value());
dataLogF("The new cfr will be %p\n", exec->callerFrame());
}
@@ -260,7 +264,7 @@ LLINT_SLOW_PATH_DECL(special_trace)
exec->codeBlock(),
exec,
static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
- exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
+ exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
exec->returnPC().value());
LLINT_END_IMPL();
}
@@ -269,7 +273,7 @@ LLINT_SLOW_PATH_DECL(special_trace)
inline bool shouldJIT(ExecState* exec)
{
// You can modify this to turn off JITting without rebuilding the world.
- return exec->globalData().canUseJIT();
+ return exec->vm().canUseJIT();
}
// Returns true if we should try to OSR.
@@ -305,7 +309,7 @@ inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
codeBlock->jitSoon();
return true;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
@@ -313,8 +317,7 @@ enum EntryKind { Prologue, ArityCheck };
static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
{
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("%p: Entered %s with executeCounter = %s\n", codeBlock, name,
- codeBlock->llintExecuteCounter().status());
+ dataLog(*codeBlock, ": Entered ", name, " with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
#else
UNUSED_PARAM(name);
#endif
@@ -362,8 +365,7 @@ LLINT_SLOW_PATH_DECL(loop_osr)
CodeBlock* codeBlock = exec->codeBlock();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("%p: Entered loop_osr with executeCounter = %s\n", codeBlock,
- codeBlock->llintExecuteCounter().status());
+ dataLog(*codeBlock, ": Entered loop_osr with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
#endif
if (!shouldJIT(exec)) {
@@ -378,7 +380,7 @@ LLINT_SLOW_PATH_DECL(loop_osr)
Vector<BytecodeAndMachineOffset> map;
codeBlock->jitCodeMap()->decode(map);
- BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(map.begin(), map.size(), pc - codeBlock->instructions().begin());
+ BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
ASSERT(mapping);
ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
@@ -393,8 +395,7 @@ LLINT_SLOW_PATH_DECL(replace)
CodeBlock* codeBlock = exec->codeBlock();
#if ENABLE(JIT_VERBOSE_OSR)
- dataLogF("%p: Entered replace with executeCounter = %s\n", codeBlock,
- codeBlock->llintExecuteCounter().status());
+ dataLog(*codeBlock, ": Entered replace with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
#endif
if (shouldJIT(exec))
@@ -413,13 +414,13 @@ LLINT_SLOW_PATH_DECL(stack_check)
dataLogF("CodeBlock = %p.\n", exec->codeBlock());
dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
- dataLogF("Current end is at %p.\n", exec->globalData().interpreter->stack().end());
+ dataLogF("Current end is at %p.\n", exec->vm().interpreter->stack().end());
#endif
- ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->stack().end());
- if (UNLIKELY(!globalData.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
+ ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->vm().interpreter->stack().end());
+ if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
- globalData.exception = createStackOverflowError(exec);
+ vm.exception = createStackOverflowError(exec);
interpreterThrowInCaller(exec, returnPC);
pc = returnToThrowForThrownException(exec);
}
@@ -429,11 +430,11 @@ LLINT_SLOW_PATH_DECL(stack_check)
LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
{
LLINT_BEGIN();
- ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForCall);
+ ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall);
if (!newExec) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
- globalData.exception = createStackOverflowError(exec);
+ vm.exception = createStackOverflowError(exec);
interpreterThrowInCaller(exec, returnPC);
LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
}
@@ -443,11 +444,11 @@ LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck)
{
LLINT_BEGIN();
- ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForConstruct);
+ ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct);
if (!newExec) {
ReturnAddressPtr returnPC = exec->returnPC();
exec = exec->callerFrame();
- globalData.exception = createStackOverflowError(exec);
+ vm.exception = createStackOverflowError(exec);
interpreterThrowInCaller(exec, returnPC);
LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
}
@@ -460,7 +461,7 @@ LLINT_SLOW_PATH_DECL(slow_path_create_activation)
#if LLINT_SLOW_PATH_TRACING
dataLogF("Creating an activation, exec = %p!\n", exec);
#endif
- JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock());
+ JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
exec->setScope(activation);
LLINT_RETURN(JSValue(activation));
}
@@ -468,7 +469,7 @@ LLINT_SLOW_PATH_DECL(slow_path_create_activation)
LLINT_SLOW_PATH_DECL(slow_path_create_arguments)
{
LLINT_BEGIN();
- JSValue arguments = JSValue(Arguments::create(globalData, exec));
+ JSValue arguments = JSValue(Arguments::create(vm, exec));
LLINT_CHECK_EXCEPTION();
exec->uncheckedR(pc[1].u.operand) = arguments;
exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
@@ -484,8 +485,9 @@ LLINT_SLOW_PATH_DECL(slow_path_create_this)
ConstructData constructData;
ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
#endif
-
- Structure* structure = constructor->cachedInheritorID(exec);
+
+ size_t inlineCapacity = pc[3].u.operand;
+ Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure();
LLINT_RETURN(constructEmptyObject(exec, structure));
}
@@ -504,7 +506,7 @@ LLINT_SLOW_PATH_DECL(slow_path_convert_this)
LLINT_SLOW_PATH_DECL(slow_path_new_object)
{
LLINT_BEGIN();
- LLINT_RETURN(constructEmptyObject(exec));
+ LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
}
LLINT_SLOW_PATH_DECL(slow_path_new_array)
@@ -531,7 +533,7 @@ LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
if (!regExp->isValid())
LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
- LLINT_RETURN(RegExpObject::create(globalData, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
+ LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
}
LLINT_SLOW_PATH_DECL(slow_path_not)
@@ -600,23 +602,7 @@ LLINT_SLOW_PATH_DECL(slow_path_pre_dec)
LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
}
-LLINT_SLOW_PATH_DECL(slow_path_post_inc)
-{
- LLINT_BEGIN();
- double result = LLINT_OP(2).jsValue().toNumber(exec);
- LLINT_OP(2) = jsNumber(result + 1);
- LLINT_RETURN(jsNumber(result));
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_post_dec)
-{
- LLINT_BEGIN();
- double result = LLINT_OP(2).jsValue().toNumber(exec);
- LLINT_OP(2) = jsNumber(result - 1);
- LLINT_RETURN(jsNumber(result));
-}
-
-LLINT_SLOW_PATH_DECL(slow_path_to_jsnumber)
+LLINT_SLOW_PATH_DECL(slow_path_to_number)
{
LLINT_BEGIN();
LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
@@ -745,7 +731,7 @@ LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
}
}
- LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
+ LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
}
LLINT_SLOW_PATH_DECL(slow_path_instanceof)
@@ -785,10 +771,12 @@ LLINT_SLOW_PATH_DECL(slow_path_resolve)
{
LLINT_BEGIN();
Identifier ident = exec->codeBlock()->identifier(pc[2].u.operand);
- ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[3].u.operand);
+ ResolveOperations* operations = pc[3].u.resolveOperations;
JSValue result = JSScope::resolve(exec, ident, operations);
ASSERT(operations->size());
- ASSERT(operations == exec->codeBlock()->resolveOperations(pc[3].u.operand));
+ if (operations->isEmpty())
+ LLINT_RETURN_PROFILED(op_resolve, result);
+
switch (operations->data()[0].m_operation) {
case ResolveOperation::GetAndReturnGlobalProperty:
pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_property);
@@ -818,7 +806,7 @@ LLINT_SLOW_PATH_DECL(slow_path_resolve)
LLINT_SLOW_PATH_DECL(slow_path_put_to_base)
{
LLINT_BEGIN();
- PutToBaseOperation* operation = exec->codeBlock()->putToBaseOperation(pc[4].u.operand);
+ PutToBaseOperation* operation = pc[4].u.putToBaseOperation;
JSScope::resolvePut(exec, LLINT_OP_C(1).jsValue(), exec->codeBlock()->identifier(pc[2].u.operand), LLINT_OP_C(3).jsValue(), operation);
switch (operation->m_kind) {
case PutToBaseOperation::VariablePut:
@@ -835,15 +823,21 @@ LLINT_SLOW_PATH_DECL(slow_path_resolve_base)
{
LLINT_BEGIN();
Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
- ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand);
+ ResolveOperations* operations = pc[4].u.resolveOperations;
JSValue result;
if (pc[3].u.operand) {
- result = JSScope::resolveBase(exec, ident, true, operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand));
+ result = JSScope::resolveBase(exec, ident, true, operations, pc[5].u.putToBaseOperation);
if (!result)
- LLINT_THROW(globalData.exception);
+ LLINT_THROW(vm.exception);
} else
- result = JSScope::resolveBase(exec, ident, false, operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand));
+ result = JSScope::resolveBase(exec, ident, false, operations, pc[5].u.putToBaseOperation);
+
ASSERT(operations->size());
+ if (operations->isEmpty()) {
+ LLINT_PROFILE_VALUE(op_resolve_base, result);
+ LLINT_RETURN(result);
+ }
+
switch (operations->data()[0].m_operation) {
case ResolveOperation::ReturnGlobalObjectAsBase:
pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_global);
@@ -864,22 +858,11 @@ LLINT_SLOW_PATH_DECL(slow_path_resolve_base)
LLINT_RETURN(result);
}
-LLINT_SLOW_PATH_DECL(slow_path_ensure_property_exists)
-{
- LLINT_BEGIN();
- JSObject* object = asObject(LLINT_OP(1).jsValue());
- PropertySlot slot(object);
- Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
- if (!object->getPropertySlot(exec, ident, slot))
- LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.string()));
- LLINT_END();
-}
-
LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base)
{
LLINT_BEGIN();
- ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand);
- JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand));
+ ResolveOperations* operations = pc[4].u.resolveOperations;
+ JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations, pc[5].u.putToBaseOperation);
LLINT_CHECK_EXCEPTION();
LLINT_OP(2) = result;
LLINT_PROFILE_VALUE(op_resolve_with_base, result);
@@ -889,7 +872,7 @@ LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base)
LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this)
{
LLINT_BEGIN();
- ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand);
+ ResolveOperations* operations = pc[4].u.resolveOperations;
JSValue result = JSScope::resolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations);
LLINT_CHECK_EXCEPTION();
LLINT_OP(2) = result;
@@ -929,7 +912,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
if (!structure->isUncacheableDictionary()
&& !structure->typeInfo().prohibitsPropertyCaching()) {
pc[4].u.structure.set(
- globalData, codeBlock->ownerExecutable(), structure);
+ vm, codeBlock->ownerExecutable(), structure);
if (isInlineOffset(slot.cachedOffset())) {
pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
@@ -976,7 +959,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
JSValue baseValue = LLINT_OP_C(1).jsValue();
PutPropertySlot slot(codeBlock->isStrictMode());
if (pc[8].u.operand)
- asObject(baseValue)->putDirect(globalData, ident, LLINT_OP_C(3).jsValue(), slot);
+ asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
else
baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
LLINT_CHECK_EXCEPTION();
@@ -1003,17 +986,17 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
ASSERT(structure->previousID()->isObject());
pc[4].u.structure.set(
- globalData, codeBlock->ownerExecutable(), structure->previousID());
+ vm, codeBlock->ownerExecutable(), structure->previousID());
if (isInlineOffset(slot.cachedOffset()))
pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
else
pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
pc[6].u.structure.set(
- globalData, codeBlock->ownerExecutable(), structure);
+ vm, codeBlock->ownerExecutable(), structure);
StructureChain* chain = structure->prototypeChain(exec);
ASSERT(chain);
pc[7].u.structureChain.set(
- globalData, codeBlock->ownerExecutable(), chain);
+ vm, codeBlock->ownerExecutable(), chain);
if (pc[8].u.operand) {
if (isInlineOffset(slot.cachedOffset()))
@@ -1030,7 +1013,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
}
} else {
pc[4].u.structure.set(
- globalData, codeBlock->ownerExecutable(), structure);
+ vm, codeBlock->ownerExecutable(), structure);
if (isInlineOffset(slot.cachedOffset())) {
pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
@@ -1090,7 +1073,7 @@ LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
LLINT_BEGIN();
JSValue arguments = LLINT_OP(2).jsValue();
if (!arguments) {
- arguments = Arguments::create(globalData, exec);
+ arguments = Arguments::create(vm, exec);
LLINT_CHECK_EXCEPTION();
LLINT_OP(2) = arguments;
exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
@@ -1118,7 +1101,7 @@ LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
if (baseValue.isObject()) {
JSObject* object = asObject(baseValue);
if (object->canSetIndexQuickly(i))
- object->setIndexQuickly(globalData, i, value);
+ object->setIndexQuickly(vm, i, value);
else
object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
LLINT_END();
@@ -1193,9 +1176,9 @@ LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
ASSERT(getter.isObject() || setter.isObject());
if (!getter.isUndefined())
- accessor->setGetter(globalData, asObject(getter));
+ accessor->setGetter(vm, asObject(getter));
if (!setter.isUndefined())
- accessor->setSetter(globalData, asObject(setter));
+ accessor->setSetter(vm, asObject(setter));
baseObj->putDirectAccessor(
exec,
exec->codeBlock()->identifier(pc[2].u.operand),
@@ -1203,18 +1186,6 @@ LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
LLINT_END();
}
-LLINT_SLOW_PATH_DECL(slow_path_jmp_scopes)
-{
- LLINT_BEGIN();
- unsigned count = pc[1].u.operand;
- JSScope* tmp = exec->scope();
- while (count--)
- tmp = tmp->next();
- exec->setScope(tmp);
- pc += pc[2].u.operand;
- LLINT_END();
-}
-
LLINT_SLOW_PATH_DECL(slow_path_jtrue)
{
LLINT_BEGIN();
@@ -1345,7 +1316,7 @@ LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
execCallee->setScope(exec->scope());
execCallee->setCodeBlock(0);
@@ -1358,9 +1329,9 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
ASSERT(callType != CallTypeJS);
if (callType == CallTypeHost) {
- NativeCallFrameTracer tracer(&globalData, execCallee);
+ NativeCallFrameTracer tracer(&vm, execCallee);
execCallee->setCallee(asObject(callee));
- globalData.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
+ vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
}
@@ -1381,9 +1352,9 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
ASSERT(constructType != ConstructTypeJS);
if (constructType == ConstructTypeHost) {
- NativeCallFrameTracer tracer(&globalData, execCallee);
+ NativeCallFrameTracer tracer(&vm, execCallee);
execCallee->setCallee(asObject(callee));
- globalData.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
+ vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
}
@@ -1408,7 +1379,7 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
JSScope* scope = callee->scopeUnchecked();
- JSGlobalData& globalData = *scope->globalData();
+ VM& vm = *scope->vm();
execCallee->setScope(scope);
ExecutableBase* executable = callee->executable();
@@ -1429,12 +1400,12 @@ inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, Code
codePtr = functionExecutable->jsCodeEntryFor(kind);
}
- if (callLinkInfo) {
+ if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
if (callLinkInfo->isOnList())
callLinkInfo->remove();
ExecState* execCaller = execCallee->callerFrame();
- callLinkInfo->callee.set(globalData, execCaller->codeBlock()->ownerExecutable(), callee);
- callLinkInfo->lastSeenCallee.set(globalData, execCaller->codeBlock()->ownerExecutable(), callee);
+ callLinkInfo->callee.set(vm, execCaller->codeBlock()->ownerExecutable(), callee);
+ callLinkInfo->lastSeenCallee.set(vm, execCaller->codeBlock()->ownerExecutable(), callee);
callLinkInfo->machineCodeTarget = codePtr;
if (codeBlock)
codeBlock->linkIncomingCall(callLinkInfo);
@@ -1486,7 +1457,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
ExecState* execCallee = loadVarargs(
- exec, &globalData.interpreter->stack(),
+ exec, &vm.interpreter->stack(),
LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
LLINT_CALL_CHECK_EXCEPTION(exec, pc);
@@ -1515,7 +1486,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval)
if (!isHostFunction(calleeAsValue, globalFuncEval))
return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
- globalData.hostCallReturnValue = eval(execCallee);
+ vm.hostCallReturnValue = eval(execCallee);
LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
}
@@ -1523,7 +1494,7 @@ LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
{
LLINT_BEGIN();
ASSERT(exec->codeBlock()->needsFullScopeChain());
- jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(globalData);
+ jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
LLINT_END();
}
@@ -1625,9 +1596,17 @@ LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
{
LLINT_BEGIN();
if (pc[2].u.operand)
- LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
+ LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
else
- LLINT_THROW(createTypeError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
+ LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
+}
+
+LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
+{
+ LLINT_BEGIN_NO_SET_PC();
+ if (UNLIKELY(vm.watchdog.didFire(exec)))
+ LLINT_THROW(createTerminatedExecutionException(&vm));
+ LLINT_RETURN_TWO(0, exec);
}
LLINT_SLOW_PATH_DECL(slow_path_debug)
@@ -1638,7 +1617,7 @@ LLINT_SLOW_PATH_DECL(slow_path_debug)
int lastLine = pc[3].u.operand;
int column = pc[4].u.operand;
- globalData.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
+ vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
LLINT_END();
}
@@ -1646,7 +1625,7 @@ LLINT_SLOW_PATH_DECL(slow_path_debug)
LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
{
LLINT_BEGIN();
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->willExecute(exec, LLINT_OP(1).jsValue());
LLINT_END();
}
@@ -1654,7 +1633,7 @@ LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
{
LLINT_BEGIN();
- if (Profiler* profiler = globalData.enabledProfiler())
+ if (LegacyProfiler* profiler = vm.enabledProfiler())
profiler->didExecute(exec, LLINT_OP(1).jsValue());
LLINT_END();
}
@@ -1662,7 +1641,7 @@ LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
LLINT_SLOW_PATH_DECL(throw_from_native_call)
{
LLINT_BEGIN();
- ASSERT(globalData.exception);
+ ASSERT(vm.exception);
LLINT_END();
}
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.h b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
index 99fbaccfa..dbf68b2f9 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
@@ -135,9 +135,7 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_greater);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_greatereq);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pre_inc);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pre_dec);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_post_inc);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_post_dec);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_jsnumber);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_to_number);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_negate);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_add);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_mul);
@@ -159,7 +157,6 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_in);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_base);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_base);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_ensure_property_exists);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_with_base);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_resolve_with_this);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_init_global_const_check);
@@ -174,7 +171,6 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_val);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_by_index);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_getter_setter);
-LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_jmp_scopes);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_jtrue);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_jfalse);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_jless);
@@ -205,6 +201,7 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pop_scope);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_name_scope);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_static_error);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_handle_watchdog_timer);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_debug);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_will_call);
LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_did_call);
diff --git a/Source/JavaScriptCore/llint/LLIntThunks.cpp b/Source/JavaScriptCore/llint/LLIntThunks.cpp
index ef19c766d..fe57aa374 100644
--- a/Source/JavaScriptCore/llint/LLIntThunks.cpp
+++ b/Source/JavaScriptCore/llint/LLIntThunks.cpp
@@ -38,7 +38,7 @@ namespace JSC { namespace LLInt {
#if !ENABLE(LLINT_C_LOOP)
-static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, void (*target)(), const char *thunkKind)
+static MacroAssemblerCodeRef generateThunkWithJumpTo(VM* vm, void (*target)(), const char *thunkKind)
{
JSInterfaceJIT jit;
@@ -46,38 +46,38 @@ static MacroAssemblerCodeRef generateThunkWithJumpTo(JSGlobalData* globalData, v
jit.move(JSInterfaceJIT::TrustedImmPtr(bitwise_cast<void*>(target)), JSInterfaceJIT::regT0);
jit.jump(JSInterfaceJIT::regT0);
- LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
+ LinkBuffer patchBuffer(*vm, &jit, GLOBAL_THUNK_ID);
return FINALIZE_CODE(patchBuffer, ("LLInt %s prologue thunk", thunkKind));
}
-MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef functionForCallEntryThunkGenerator(VM* vm)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_call_prologue, "function for call");
+ return generateThunkWithJumpTo(vm, llint_function_for_call_prologue, "function for call");
}
-MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(VM* vm)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_construct_prologue, "function for construct");
+ return generateThunkWithJumpTo(vm, llint_function_for_construct_prologue, "function for construct");
}
-MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(VM* vm)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_call_arity_check, "function for call with arity check");
+ return generateThunkWithJumpTo(vm, llint_function_for_call_arity_check, "function for call with arity check");
}
-MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(VM* vm)
{
- return generateThunkWithJumpTo(globalData, llint_function_for_construct_arity_check, "function for construct with arity check");
+ return generateThunkWithJumpTo(vm, llint_function_for_construct_arity_check, "function for construct with arity check");
}
-MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef evalEntryThunkGenerator(VM* vm)
{
- return generateThunkWithJumpTo(globalData, llint_eval_prologue, "eval");
+ return generateThunkWithJumpTo(vm, llint_eval_prologue, "eval");
}
-MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData* globalData)
+MacroAssemblerCodeRef programEntryThunkGenerator(VM* vm)
{
- return generateThunkWithJumpTo(globalData, llint_program_prologue, "program");
+ return generateThunkWithJumpTo(vm, llint_program_prologue, "program");
}
#endif // !ENABLE(LLINT_C_LOOP)
diff --git a/Source/JavaScriptCore/llint/LLIntThunks.h b/Source/JavaScriptCore/llint/LLIntThunks.h
index ee119e0b9..b46cc00e7 100644
--- a/Source/JavaScriptCore/llint/LLIntThunks.h
+++ b/Source/JavaScriptCore/llint/LLIntThunks.h
@@ -34,16 +34,16 @@
namespace JSC {
-class JSGlobalData;
+class VM;
namespace LLInt {
-MacroAssemblerCodeRef functionForCallEntryThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef evalEntryThunkGenerator(JSGlobalData*);
-MacroAssemblerCodeRef programEntryThunkGenerator(JSGlobalData*);
+MacroAssemblerCodeRef functionForCallEntryThunkGenerator(VM*);
+MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(VM*);
+MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(VM*);
+MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(VM*);
+MacroAssemblerCodeRef evalEntryThunkGenerator(VM*);
+MacroAssemblerCodeRef programEntryThunkGenerator(VM*);
} } // namespace JSC::LLInt
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 9de48f1f6..85917a512 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -118,7 +118,7 @@ const FunctionCode = 2
const LLIntReturnPC = ArgumentCount + TagOffset
# String flags.
-const HashFlags8BitBuffer = 64
+const HashFlags8BitBuffer = 32
# Copied from PropertyOffset.h
const firstOutOfLineOffset = 100
@@ -154,11 +154,11 @@ else
end
# This must match wtf/Vector.h
-const VectorSizeOffset = 0
+const VectorBufferOffset = 0
if JSVALUE64
- const VectorBufferOffset = 8
+ const VectorSizeOffset = 12
else
- const VectorBufferOffset = 4
+ const VectorSizeOffset = 8
end
@@ -182,9 +182,11 @@ macro assert(assertion)
end
macro preserveReturnAddressAfterCall(destinationRegister)
- if C_LOOP or ARMv7 or MIPS
+ if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
# In C_LOOP case, we're only preserving the bytecode vPC.
move lr, destinationRegister
+ elsif SH4
+ stspr destinationRegister
elsif X86 or X86_64
pop destinationRegister
else
@@ -193,9 +195,11 @@ macro preserveReturnAddressAfterCall(destinationRegister)
end
macro restoreReturnAddressBeforeReturn(sourceRegister)
- if C_LOOP or ARMv7 or MIPS
+ if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
# In C_LOOP case, we're only restoring the bytecode vPC.
move sourceRegister, lr
+ elsif SH4
+ ldspr sourceRegister
elsif X86 or X86_64
push sourceRegister
else
@@ -358,8 +362,8 @@ macro functionInitialization(profileArgSkip)
# Check stack height.
loadi CodeBlock::m_numCalleeRegisters[t1], t0
- loadp CodeBlock::m_globalData[t1], t2
- loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the JSStack from the JITStackFrame
+ loadp CodeBlock::m_vm[t1], t2
+ loadp VM::interpreter[t2], t2 # FIXME: Can get to the JSStack from the JITStackFrame
lshifti 3, t0
addp t0, cfr, t0
bpaeq Interpreter::m_stack + JSStack::m_end[t2], t0, .stackHeightOK
@@ -369,32 +373,21 @@ macro functionInitialization(profileArgSkip)
.stackHeightOK:
end
-macro allocateBasicJSObject(sizeClassIndex, structure, result, scratch1, scratch2, slowCase)
+macro allocateJSObject(allocator, structure, result, scratch1, slowCase)
if ALWAYS_ALLOCATE_SLOW
jmp slowCase
else
- const offsetOfMySizeClass =
- JSGlobalData::heap +
- Heap::m_objectSpace +
- MarkedSpace::m_normalSpace +
- MarkedSpace::Subspace::preciseAllocators +
- sizeClassIndex * sizeof MarkedAllocator
-
const offsetOfFirstFreeCell =
MarkedAllocator::m_freeList +
MarkedBlock::FreeList::head
- # FIXME: we can get the global data in one load from the stack.
- loadp CodeBlock[cfr], scratch1
- loadp CodeBlock::m_globalData[scratch1], scratch1
-
# Get the object from the free list.
- loadp offsetOfMySizeClass + offsetOfFirstFreeCell[scratch1], result
+ loadp offsetOfFirstFreeCell[allocator], result
btpz result, slowCase
# Remove the object from the free list.
- loadp [result], scratch2
- storep scratch2, offsetOfMySizeClass + offsetOfFirstFreeCell[scratch1]
+ loadp [result], scratch1
+ storep scratch1, offsetOfFirstFreeCell[allocator]
# Initialize the object.
storep structure, JSCell::m_structure[result]
@@ -536,11 +529,8 @@ _llint_op_in:
dispatch(4)
macro getPutToBaseOperationField(scratch, scratch1, fieldOffset, fieldGetter)
- loadisFromInstruction(4, scratch)
- mulp sizeof PutToBaseOperation, scratch, scratch
- loadp CodeBlock[cfr], scratch1
- loadp VectorBufferOffset + CodeBlock::m_putToBaseOperations[scratch1], scratch1
- fieldGetter(fieldOffset[scratch1, scratch, 1])
+ loadpFromInstruction(4, scratch)
+ fieldGetter(fieldOffset[scratch])
end
macro moveJSValueFromRegisterWithoutProfiling(value, destBuffer, destOffsetReg)
@@ -588,12 +578,9 @@ _llint_op_put_to_base:
callSlowPath(_llint_slow_path_put_to_base)
dispatch(5)
-macro getResolveOperation(resolveOperationIndex, dest, scratch)
- loadisFromInstruction(resolveOperationIndex, dest)
- mulp sizeof ResolveOperations, dest, dest
- loadp CodeBlock[cfr], scratch
- loadp VectorBufferOffset + CodeBlock::m_resolveOperations[scratch], scratch
- loadp VectorBufferOffset[scratch, dest, 1], dest
+macro getResolveOperation(resolveOperationIndex, dest)
+ loadpFromInstruction(resolveOperationIndex, dest)
+ loadp VectorBufferOffset[dest], dest
end
macro getScope(loadInitialScope, scopeCount, dest, scratch)
@@ -656,7 +643,7 @@ end
_llint_op_resolve_global_property:
traceExecution()
- getResolveOperation(3, t0, t1)
+ getResolveOperation(3, t0)
loadp CodeBlock[cfr], t1
loadp CodeBlock::m_globalObject[t1], t1
loadp ResolveOperation::m_structure[t0], t2
@@ -675,7 +662,7 @@ _llint_op_resolve_global_property:
_llint_op_resolve_global_var:
traceExecution()
- getResolveOperation(3, t0, t1)
+ getResolveOperation(3, t0)
loadp ResolveOperation::m_registerAddress[t0], t0
loadisFromInstruction(1, t1)
moveJSValueFromSlot(t0, cfr, t1, 4, t3)
@@ -697,13 +684,13 @@ end
_llint_op_resolve_scoped_var:
traceExecution()
- getResolveOperation(3, t0, t1)
+ getResolveOperation(3, t0)
resolveScopedVarBody(t0)
dispatch(5)
_llint_op_resolve_scoped_var_on_top_scope:
traceExecution()
- getResolveOperation(3, t0, t1)
+ getResolveOperation(3, t0)
# Load destination index
loadisFromInstruction(1, t3)
@@ -720,7 +707,7 @@ _llint_op_resolve_scoped_var_on_top_scope:
_llint_op_resolve_scoped_var_with_top_scope_check:
traceExecution()
- getResolveOperation(3, t0, t1)
+ getResolveOperation(3, t0)
# First ResolveOperation tells us what register to check
loadis ResolveOperation::m_activationRegister[t0], t1
@@ -747,7 +734,7 @@ _llint_op_resolve_scoped_var_with_top_scope_check:
_llint_op_resolve:
.llint_op_resolve_local:
traceExecution()
- getResolveOperation(3, t0, t1)
+ getResolveOperation(3, t0)
btpz t0, .noInstructions
loadis ResolveOperation::m_operation[t0], t1
bineq t1, ResolveOperationSkipScopes, .notSkipScopes
@@ -783,7 +770,7 @@ _llint_op_resolve_base_to_global_dynamic:
_llint_op_resolve_base_to_scope:
traceExecution()
- getResolveOperation(4, t0, t1)
+ getResolveOperation(4, t0)
# First ResolveOperation is to skip scope chain nodes
getScope(macro(dest)
loadp ScopeChain + PayloadOffset[cfr], dest
@@ -800,7 +787,7 @@ _llint_op_resolve_base_to_scope:
_llint_op_resolve_base_to_scope_with_top_scope_check:
traceExecution()
- getResolveOperation(4, t0, t1)
+ getResolveOperation(4, t0)
# First ResolveOperation tells us what register to check
loadis ResolveOperation::m_activationRegister[t0], t1
@@ -831,14 +818,9 @@ _llint_op_resolve_base:
callSlowPath(_llint_slow_path_resolve_base)
dispatch(7)
-_llint_op_ensure_property_exists:
- traceExecution()
- callSlowPath(_llint_slow_path_ensure_property_exists)
- dispatch(3)
-
macro interpretResolveWithBase(opcodeLength, slowPath)
traceExecution()
- getResolveOperation(4, t0, t1)
+ getResolveOperation(4, t0)
btpz t0, .slowPath
loadp ScopeChain[cfr], t3
@@ -990,19 +972,6 @@ _llint_op_put_getter_setter:
dispatch(5)
-_llint_op_jmp_scopes:
- traceExecution()
- callSlowPath(_llint_slow_path_jmp_scopes)
- dispatch(0)
-
-
-_llint_op_loop_if_true:
- traceExecution()
- jumpTrueOrFalse(
- macro (value, target) btinz value, target end,
- _llint_slow_path_jtrue)
-
-
_llint_op_jtrue:
traceExecution()
jumpTrueOrFalse(
@@ -1010,13 +979,6 @@ _llint_op_jtrue:
_llint_slow_path_jtrue)
-_llint_op_loop_if_false:
- traceExecution()
- jumpTrueOrFalse(
- macro (value, target) btiz value, target end,
- _llint_slow_path_jfalse)
-
-
_llint_op_jfalse:
traceExecution()
jumpTrueOrFalse(
@@ -1024,14 +986,6 @@ _llint_op_jfalse:
_llint_slow_path_jfalse)
-_llint_op_loop_if_less:
- traceExecution()
- compare(
- macro (left, right, target) bilt left, right, target end,
- macro (left, right, target) bdlt left, right, target end,
- _llint_slow_path_jless)
-
-
_llint_op_jless:
traceExecution()
compare(
@@ -1048,14 +1002,6 @@ _llint_op_jnless:
_llint_slow_path_jnless)
-_llint_op_loop_if_greater:
- traceExecution()
- compare(
- macro (left, right, target) bigt left, right, target end,
- macro (left, right, target) bdgt left, right, target end,
- _llint_slow_path_jgreater)
-
-
_llint_op_jgreater:
traceExecution()
compare(
@@ -1072,14 +1018,6 @@ _llint_op_jngreater:
_llint_slow_path_jngreater)
-_llint_op_loop_if_lesseq:
- traceExecution()
- compare(
- macro (left, right, target) bilteq left, right, target end,
- macro (left, right, target) bdlteq left, right, target end,
- _llint_slow_path_jlesseq)
-
-
_llint_op_jlesseq:
traceExecution()
compare(
@@ -1096,14 +1034,6 @@ _llint_op_jnlesseq:
_llint_slow_path_jnlesseq)
-_llint_op_loop_if_greatereq:
- traceExecution()
- compare(
- macro (left, right, target) bigteq left, right, target end,
- macro (left, right, target) bdgteq left, right, target end,
- _llint_slow_path_jgreatereq)
-
-
_llint_op_jgreatereq:
traceExecution()
compare(
@@ -1122,9 +1052,17 @@ _llint_op_jngreatereq:
_llint_op_loop_hint:
traceExecution()
+ loadp JITStackFrame::vm[sp], t1
+ loadb VM::watchdog+Watchdog::m_timerDidFire[t1], t0
+ btbnz t0, .handleWatchdogTimer
+.afterWatchdogTimerCheck:
checkSwitchToJITForLoop()
dispatch(1)
-
+.handleWatchdogTimer:
+ callWatchdogTimerHandler(.throwHandler)
+ jmp .afterWatchdogTimerCheck
+.throwHandler:
+ jmp _llint_throw_from_slow_path_trampoline
_llint_op_switch_string:
traceExecution()
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
index b2ce2483e..a616ce9f0 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
@@ -35,6 +35,7 @@
#include "CodeBlock.h"
#include "LLIntCLoop.h"
#include "LLIntSlowPaths.h"
+#include "Operations.h"
#include "VMInspector.h"
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
@@ -264,7 +265,7 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
return JSValue();
}
- ASSERT(callFrame->globalData().topCallFrame == callFrame);
+ ASSERT(callFrame->vm().topCallFrame == callFrame);
// Define the pseudo registers used by the LLINT C Loop backend:
ASSERT(sizeof(CLoopRegister) == sizeof(intptr_t));
@@ -307,12 +308,10 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
CLoopRegister rRetVPC;
CLoopDoubleRegister d0, d1;
-#if COMPILER(MSVC)
// Keep the compiler happy. We don't really need this, but the compiler
// will complain. This makes the warning go away.
t0.i = 0;
t1.i = 0;
-#endif
// Instantiate the pseudo JIT stack frame used by the LLINT C Loop backend:
JITStackFrame jitStackFrame;
@@ -320,10 +319,10 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
// The llint expects the native stack pointer, sp, to be pointing to the
// jitStackFrame (which is the simulation of the native stack frame):
JITStackFrame* const sp = &jitStackFrame;
- sp->globalData = &callFrame->globalData();
+ sp->vm = &callFrame->vm();
- // Set up an alias for the globalData ptr in the JITStackFrame:
- JSGlobalData* &globalData = sp->globalData;
+ // Set up an alias for the vm ptr in the JITStackFrame:
+ VM* &vm = sp->vm;
CodeBlock* codeBlock = callFrame->codeBlock();
Instruction* vPC;
@@ -424,7 +423,7 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
callFrame = callFrame->callerFrame();
// The part in getHostCallReturnValueWithExecState():
- JSValue result = globalData->hostCallReturnValue;
+ JSValue result = vm->hostCallReturnValue;
#if USE(JSVALUE32_64)
t1.i = result.tag();
t0.i = result.payload();
@@ -436,7 +435,7 @@ JSValue CLoop::execute(CallFrame* callFrame, OpcodeID bootstrapOpcodeId,
OFFLINE_ASM_GLUE_LABEL(ctiOpThrowNotCaught)
{
- return globalData->exception;
+ return vm->exception;
}
#if !ENABLE(COMPUTED_GOTO_OPCODES)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 9a17985bc..b9b457034 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -105,7 +105,7 @@ macro dispatchAfterCall()
end
macro cCall2(function, arg1, arg2)
- if ARMv7
+ if ARM or ARMv7 or ARMv7_TRADITIONAL
move arg1, t0
move arg2, t1
call function
@@ -113,7 +113,7 @@ macro cCall2(function, arg1, arg2)
poke arg1, 0
poke arg2, 1
call function
- elsif MIPS
+ elsif MIPS or SH4
move arg1, a0
move arg2, a1
call function
@@ -126,7 +126,7 @@ end
# This barely works. arg3 and arg4 should probably be immediates.
macro cCall4(function, arg1, arg2, arg3, arg4)
- if ARMv7
+ if ARM or ARMv7 or ARMv7_TRADITIONAL
move arg1, t0
move arg2, t1
move arg3, t2
@@ -138,7 +138,7 @@ macro cCall4(function, arg1, arg2, arg3, arg4)
poke arg3, 2
poke arg4, 3
call function
- elsif MIPS
+ elsif MIPS or SH4
move arg1, a0
move arg2, a1
move arg3, a2
@@ -185,6 +185,14 @@ macro callCallSlowPath(advance, slowPath, action)
action(t0)
end
+macro callWatchdogTimerHandler(throwHandler)
+ storei PC, ArgumentCount + TagOffset[cfr]
+ cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
+ move t1, cfr
+ btpnz t0, throwHandler
+ loadi ArgumentCount + TagOffset[cfr], PC
+end
+
macro checkSwitchToJITForLoop()
checkSwitchToJIT(
1,
@@ -302,9 +310,9 @@ macro functionArityCheck(doneLabel, slow_path)
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]
+ loadp JITStackFrame::vm[sp], t1
+ loadp VM::callFrameForThrow[t1], t0
+ jmp VM::targetMachinePCForThrow[t1]
.continue:
# Reload CodeBlock and PC, since the slow_path clobbered it.
loadp CodeBlock[cfr], t1
@@ -361,17 +369,18 @@ _llint_op_create_this:
traceExecution()
loadi 8[PC], t0
loadp PayloadOffset[cfr, t0, 8], t0
- loadp JSFunction::m_cachedInheritorID[t0], t2
- btpz t2, .opCreateThisSlow
- allocateBasicJSObject(JSFinalObjectSizeClassIndex, t2, t0, t1, t3, .opCreateThisSlow)
+ loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_allocator[t0], t1
+ loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_structure[t0], t2
+ btpz t1, .opCreateThisSlow
+ allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
loadi 4[PC], t1
storei CellTag, TagOffset[cfr, t1, 8]
storei t0, PayloadOffset[cfr, t1, 8]
- dispatch(3)
+ dispatch(4)
.opCreateThisSlow:
callSlowPath(_llint_slow_path_create_this)
- dispatch(3)
+ dispatch(4)
_llint_op_get_callee:
@@ -403,18 +412,18 @@ _llint_op_convert_this:
_llint_op_new_object:
traceExecution()
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
- loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
- allocateBasicJSObject(JSFinalObjectSizeClassIndex, t1, t0, t2, t3, .opNewObjectSlow)
+ loadpFromInstruction(3, t0)
+ loadp ObjectAllocationProfile::m_allocator[t0], t1
+ loadp ObjectAllocationProfile::m_structure[t0], t2
+ allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)
loadi 4[PC], t1
storei CellTag, TagOffset[cfr, t1, 8]
storei t0, PayloadOffset[cfr, t1, 8]
- dispatch(2)
+ dispatch(4)
.opNewObjectSlow:
callSlowPath(_llint_slow_path_new_object)
- dispatch(2)
+ dispatch(4)
_llint_op_mov:
@@ -571,88 +580,48 @@ _llint_op_nstricteq:
strictEq(macro (left, right, result) cineq left, right, result end, _llint_slow_path_nstricteq)
-_llint_op_pre_inc:
+_llint_op_inc:
traceExecution()
loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreIncSlow
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opIncSlow
loadi PayloadOffset[cfr, t0, 8], t1
- baddio 1, t1, .opPreIncSlow
+ baddio 1, t1, .opIncSlow
storei t1, PayloadOffset[cfr, t0, 8]
dispatch(2)
-.opPreIncSlow:
+.opIncSlow:
callSlowPath(_llint_slow_path_pre_inc)
dispatch(2)
-_llint_op_pre_dec:
+_llint_op_dec:
traceExecution()
loadi 4[PC], t0
- bineq TagOffset[cfr, t0, 8], Int32Tag, .opPreDecSlow
+ bineq TagOffset[cfr, t0, 8], Int32Tag, .opDecSlow
loadi PayloadOffset[cfr, t0, 8], t1
- bsubio 1, t1, .opPreDecSlow
+ bsubio 1, t1, .opDecSlow
storei t1, PayloadOffset[cfr, t0, 8]
dispatch(2)
-.opPreDecSlow:
+.opDecSlow:
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:
+_llint_op_to_number:
traceExecution()
loadi 8[PC], t0
loadi 4[PC], t1
loadConstantOrVariable(t0, t2, t3)
- bieq t2, Int32Tag, .opToJsnumberIsInt
- biaeq t2, EmptyValueTag, .opToJsnumberSlow
-.opToJsnumberIsInt:
+ bieq t2, Int32Tag, .opToNumberIsInt
+ biaeq t2, LowestTag, .opToNumberSlow
+.opToNumberIsInt:
storei t2, TagOffset[cfr, t1, 8]
storei t3, PayloadOffset[cfr, t1, 8]
dispatch(3)
-.opToJsnumberSlow:
- callSlowPath(_llint_slow_path_to_jsnumber)
+.opToNumberSlow:
+ callSlowPath(_llint_slow_path_to_number)
dispatch(3)
@@ -1076,7 +1045,7 @@ _llint_op_get_array_length:
loadi 4[PC], t1
loadp 32[PC], t2
loadp JSObject::m_butterfly[t3], t0
- loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
+ loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
valueProfile(Int32Tag, t0, t2)
storep t0, PayloadOffset[cfr, t1, 8]
@@ -1211,14 +1180,14 @@ _llint_op_get_by_val:
bineq t2, ContiguousShape, .opGetByValNotContiguous
.opGetByValIsContiguous:
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadi TagOffset[t3, t1, 8], t2
loadi PayloadOffset[t3, t1, 8], t1
jmp .opGetByValDone
.opGetByValNotContiguous:
bineq t2, DoubleShape, .opGetByValNotDouble
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadd [t3, t1, 8], ft0
bdnequn ft0, ft0, .opGetByValSlow
# FIXME: This could be massively optimized.
@@ -1229,13 +1198,13 @@ _llint_op_get_by_val:
.opGetByValNotDouble:
subi ArrayStorageShape, t2
bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
.opGetByValDone:
loadi 4[PC], t0
- bieq t2, EmptyValueTag, .opGetByValSlow
+ bieq t2, EmptyValueTag, .opGetByValOutOfBounds
.opGetByValNotEmpty:
storei t2, TagOffset[cfr, t0, 8]
storei t1, PayloadOffset[cfr, t0, 8]
@@ -1243,6 +1212,11 @@ _llint_op_get_by_val:
valueProfile(t2, t1, t0)
dispatch(6)
+.opGetByValOutOfBounds:
+ if VALUE_PROFILER
+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
+ end
.opGetByValSlow:
callSlowPath(_llint_slow_path_get_by_val)
dispatch(6)
@@ -1306,20 +1280,20 @@ _llint_op_get_by_pname:
macro contiguousPutByVal(storeCallback)
- biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
.storeResult:
loadi 12[PC], t2
storeCallback(t2, t1, t0, t3)
dispatch(5)
.outOfBounds:
- biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
if VALUE_PROFILER
loadp 16[PC], t2
storeb 1, ArrayProfile::m_mayStoreToHole[t2]
end
addi 1, t3, t2
- storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
+ storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .storeResult
end
@@ -1373,7 +1347,7 @@ _llint_op_put_by_val:
.opPutByValNotContiguous:
bineq t2, ArrayStorageShape, .opPutByValSlow
- biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
bieq ArrayStorage::m_vector + TagOffset[t0, t3, 8], EmptyValueTag, .opPutByValArrayStorageEmpty
.opPutByValArrayStorageStoreResult:
loadi 12[PC], t2
@@ -1389,21 +1363,21 @@ _llint_op_put_by_val:
storeb 1, ArrayProfile::m_mayStoreToHole[t1]
end
addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
+ bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
addi 1, t3, t1
- storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
+ storei t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .opPutByValArrayStorageStoreResult
+.opPutByValOutOfBounds:
+ if VALUE_PROFILER
+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
+ end
.opPutByValSlow:
callSlowPath(_llint_slow_path_put_by_val)
dispatch(5)
-_llint_op_loop:
- traceExecution()
- dispatchBranch(4[PC])
-
-
_llint_op_jmp:
traceExecution()
dispatchBranch(4[PC])
@@ -1475,7 +1449,7 @@ _llint_op_jneq_ptr:
loadp CodeBlock[cfr], t2
loadp CodeBlock::m_globalObject[t2], t2
bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch
- loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
+ loadp JSGlobalObject::m_specialPointers[t2, t1, 4], t1
bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough
.opJneqPtrBranch:
dispatchBranch(12[PC])
@@ -1755,14 +1729,14 @@ _llint_op_catch:
# 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.
+ # set VM::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]
+ loadp JITStackFrame::vm[sp], t3
+ loadi VM::targetInterpreterPCForThrow[t3], PC
+ loadi VM::exception + PayloadOffset[t3], t0
+ loadi VM::exception + TagOffset[t3], t1
+ storei 0, VM::exception + PayloadOffset[t3]
+ storei EmptyValueTag, VM::exception + TagOffset[t3]
loadi 4[PC], t2
storei t0, PayloadOffset[cfr, t2, 8]
storei t1, TagOffset[cfr, t2, 8]
@@ -1770,6 +1744,71 @@ _llint_op_catch:
dispatch(2)
+# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
+# scopes as they are traversed. scopeCheck() is called with two arguments: the register
+# holding the scope, and a register that can be used for scratch. Note that this does not
+# use t3, so you can hold stuff in t3 if need be.
+macro getDeBruijnScope(deBruijinIndexOperand, scopeCheck)
+ loadp ScopeChain + PayloadOffset[cfr], t0
+ loadi deBruijinIndexOperand, t2
+
+ btiz t2, .done
+
+ loadp CodeBlock[cfr], t1
+ bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
+ btbz CodeBlock::m_needsActivation[t1], .loop
+
+ loadi CodeBlock::m_activationRegister[t1], t1
+
+ # Need to conditionally skip over one scope.
+ bieq TagOffset[cfr, t1, 8], EmptyValueTag, .noActivation
+ scopeCheck(t0, t1)
+ loadp JSScope::m_next[t0], t0
+.noActivation:
+ subi 1, t2
+
+ btiz t2, .done
+.loop:
+ scopeCheck(t0, t1)
+ loadp JSScope::m_next[t0], t0
+ subi 1, t2
+ btinz t2, .loop
+
+.done:
+
+end
+
+_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.
+ getDeBruijnScope(12[PC], macro (scope, scratch) end)
+ loadi 4[PC], t1
+ loadi 8[PC], t2
+ 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()
+ getDeBruijnScope(8[PC], macro (scope, scratch) end)
+ loadi 12[PC], t1
+ loadConstantOrVariable(t1, t3, t2)
+ loadi 4[PC], t1
+ writeBarrier(t3, t2)
+ loadp JSVariableObject::m_registers[t0], t0
+ storei t3, TagOffset[t0, t1, 8]
+ storei t2, PayloadOffset[t0, t1, 8]
+ dispatch(4)
+
_llint_op_end:
traceExecution()
checkSwitchToJITForEpilogue()
@@ -1784,16 +1823,16 @@ _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]
+ loadp JITStackFrame::vm[sp], t1
+ loadp VM::callFrameForThrow[t1], t0
+ jmp VM::targetMachinePCForThrow[t1]
_llint_throw_during_call_trampoline:
preserveReturnAddressAfterCall(t2)
- loadp JITStackFrame::globalData[sp], t1
- loadp JSGlobalData::callFrameForThrow[t1], t0
- jmp JSGlobalData::targetMachinePCForThrow[t1]
+ loadp JITStackFrame::vm[sp], t1
+ loadp VM::callFrameForThrow[t1], t0
+ jmp VM::targetMachinePCForThrow[t1]
macro nativeCallTrampoline(executableOffsetToFunction)
@@ -1803,8 +1842,8 @@ macro nativeCallTrampoline(executableOffsetToFunction)
storei CellTag, ScopeChain + TagOffset[cfr]
storei t1, ScopeChain + PayloadOffset[cfr]
if X86
- loadp JITStackFrame::globalData + 4[sp], t3 # Additional offset for return address
- storep cfr, JSGlobalData::topCallFrame[t3]
+ loadp JITStackFrame::vm + 4[sp], t3 # Additional offset for return address
+ storep cfr, VM::topCallFrame[t3]
peek 0, t1
storep t1, ReturnPC[cfr]
move cfr, t2 # t2 = ecx
@@ -1814,10 +1853,10 @@ macro nativeCallTrampoline(executableOffsetToFunction)
move t0, cfr
call executableOffsetToFunction[t1]
addp 16 - 4, sp
- loadp JITStackFrame::globalData + 4[sp], t3
- elsif ARMv7
- loadp JITStackFrame::globalData[sp], t3
- storep cfr, JSGlobalData::topCallFrame[t3]
+ loadp JITStackFrame::vm + 4[sp], t3
+ elsif ARM or ARMv7 or ARMv7_TRADITIONAL
+ loadp JITStackFrame::vm[sp], t3
+ storep cfr, VM::topCallFrame[t3]
move t0, t2
preserveReturnAddressAfterCall(t3)
storep t3, ReturnPC[cfr]
@@ -1827,10 +1866,10 @@ macro nativeCallTrampoline(executableOffsetToFunction)
move t2, cfr
call executableOffsetToFunction[t1]
restoreReturnAddressBeforeReturn(t3)
- loadp JITStackFrame::globalData[sp], t3
+ loadp JITStackFrame::vm[sp], t3
elsif MIPS
- loadp JITStackFrame::globalData[sp], t3
- storep cfr, JSGlobalData::topCallFrame[t3]
+ loadp JITStackFrame::vm[sp], t3
+ storep cfr, VM::topCallFrame[t3]
move t0, t2
preserveReturnAddressAfterCall(t3)
storep t3, ReturnPC[cfr]
@@ -1841,10 +1880,23 @@ macro nativeCallTrampoline(executableOffsetToFunction)
move t0, a0
call executableOffsetToFunction[t1]
restoreReturnAddressBeforeReturn(t3)
- loadp JITStackFrame::globalData[sp], t3
+ loadp JITStackFrame::vm[sp], t3
+ elsif SH4
+ loadp JITStackFrame::vm[sp], t3
+ storep cfr, VM::topCallFrame[t3]
+ 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::vm[sp], t3
elsif C_LOOP
- loadp JITStackFrame::globalData[sp], t3
- storep cfr, JSGlobalData::topCallFrame[t3]
+ loadp JITStackFrame::vm[sp], t3
+ storep cfr, VM::topCallFrame[t3]
move t0, t2
preserveReturnAddressAfterCall(t3)
storep t3, ReturnPC[cfr]
@@ -1854,11 +1906,11 @@ macro nativeCallTrampoline(executableOffsetToFunction)
move t2, cfr
cloopCallNative executableOffsetToFunction[t1]
restoreReturnAddressBeforeReturn(t3)
- loadp JITStackFrame::globalData[sp], t3
+ loadp JITStackFrame::vm[sp], t3
else
error
end
- bineq JSGlobalData::exception + TagOffset[t3], EmptyValueTag, .exception
+ bineq VM::exception + TagOffset[t3], EmptyValueTag, .exception
ret
.exception:
preserveReturnAddressAfterCall(t1) # This is really only needed on X86
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index ed6799ef3..741963573 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -126,6 +126,16 @@ macro callCallSlowPath(advance, slowPath, action)
action(t0)
end
+macro callWatchdogTimerHandler(throwHandler)
+ storei PC, ArgumentCount + TagOffset[cfr]
+ prepareStateForCCall()
+ cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
+ move t1, cfr
+ btpnz t0, throwHandler
+ move t3, PB
+ loadi ArgumentCount + TagOffset[cfr], PC
+end
+
macro checkSwitchToJITForLoop()
checkSwitchToJIT(
1,
@@ -186,9 +196,9 @@ macro functionArityCheck(doneLabel, slow_path)
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]
+ loadp JITStackFrame::vm[sp], t1
+ loadp VM::callFrameForThrow[t1], t0
+ jmp VM::targetMachinePCForThrow[t1]
.continue:
# Reload CodeBlock and reset PC, since the slow_path clobbered them.
loadp CodeBlock[cfr], t1
@@ -243,16 +253,17 @@ _llint_op_create_this:
traceExecution()
loadisFromInstruction(2, t0)
loadp [cfr, t0, 8], t0
- loadp JSFunction::m_cachedInheritorID[t0], t2
- btpz t2, .opCreateThisSlow
- allocateBasicJSObject(JSFinalObjectSizeClassIndex, t2, t0, t1, t3, .opCreateThisSlow)
+ loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_allocator[t0], t1
+ loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_structure[t0], t2
+ btpz t1, .opCreateThisSlow
+ allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
loadisFromInstruction(1, t1)
storeq t0, [cfr, t1, 8]
- dispatch(3)
+ dispatch(4)
.opCreateThisSlow:
callSlowPath(_llint_slow_path_create_this)
- dispatch(3)
+ dispatch(4)
_llint_op_get_callee:
@@ -283,17 +294,17 @@ _llint_op_convert_this:
_llint_op_new_object:
traceExecution()
- loadp CodeBlock[cfr], t0
- loadp CodeBlock::m_globalObject[t0], t0
- loadp JSGlobalObject::m_emptyObjectStructure[t0], t1
- allocateBasicJSObject(JSFinalObjectSizeClassIndex, t1, t0, t2, t3, .opNewObjectSlow)
+ loadpFromInstruction(3, t0)
+ loadp ObjectAllocationProfile::m_allocator[t0], t1
+ loadp ObjectAllocationProfile::m_structure[t0], t2
+ allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)
loadisFromInstruction(1, t1)
storeq t0, [cfr, t1, 8]
- dispatch(2)
+ dispatch(4)
.opNewObjectSlow:
callSlowPath(_llint_slow_path_new_object)
- dispatch(2)
+ dispatch(4)
_llint_op_mov:
@@ -440,63 +451,31 @@ macro preOp(arithmeticOperation, slowPath)
dispatch(2)
end
-_llint_op_pre_inc:
+_llint_op_inc:
preOp(
macro (value, slow) baddio 1, value, slow end,
_llint_slow_path_pre_inc)
-_llint_op_pre_dec:
+_llint_op_dec:
preOp(
macro (value, slow) bsubio 1, value, slow end,
_llint_slow_path_pre_dec)
-macro postOp(arithmeticOperation, slowPath)
- traceExecution()
- loadisFromInstruction(2, t0)
- loadisFromInstruction(1, t1)
- loadq [cfr, t0, 8], t2
- bieq t0, t1, .done
- bqb t2, tagTypeNumber, .slow
- move t2, t3
- arithmeticOperation(t3, .slow)
- orq tagTypeNumber, t3
- storeq t2, [cfr, t1, 8]
- storeq 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:
+_llint_op_to_number:
traceExecution()
loadisFromInstruction(2, t0)
loadisFromInstruction(1, t1)
loadConstantOrVariable(t0, t2)
- bqaeq t2, tagTypeNumber, .opToJsnumberIsImmediate
- btqz t2, tagTypeNumber, .opToJsnumberSlow
-.opToJsnumberIsImmediate:
+ bqaeq t2, tagTypeNumber, .opToNumberIsImmediate
+ btqz t2, tagTypeNumber, .opToNumberSlow
+.opToNumberIsImmediate:
storeq t2, [cfr, t1, 8]
dispatch(3)
-.opToJsnumberSlow:
- callSlowPath(_llint_slow_path_to_jsnumber)
+.opToNumberSlow:
+ callSlowPath(_llint_slow_path_to_number)
dispatch(3)
@@ -907,7 +886,7 @@ _llint_op_get_array_length:
loadisFromInstruction(1, t1)
loadpFromInstruction(8, t2)
loadp JSObject::m_butterfly[t3], t0
- loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
+ loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
orq tagTypeNumber, t0
valueProfile(t0, t2)
@@ -1040,18 +1019,18 @@ _llint_op_get_by_val:
bineq t2, ContiguousShape, .opGetByValNotContiguous
.opGetByValIsContiguous:
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadisFromInstruction(1, t0)
loadq [t3, t1, 8], t2
- btqz t2, .opGetByValSlow
+ btqz t2, .opGetByValOutOfBounds
jmp .opGetByValDone
.opGetByValNotContiguous:
bineq t2, DoubleShape, .opGetByValNotDouble
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadis 8[PB, PC, 8], t0
loadd [t3, t1, 8], ft0
- bdnequn ft0, ft0, .opGetByValSlow
+ bdnequn ft0, ft0, .opGetByValOutOfBounds
fd2q ft0, t2
subq tagTypeNumber, t2
jmp .opGetByValDone
@@ -1059,10 +1038,10 @@ _llint_op_get_by_val:
.opGetByValNotDouble:
subi ArrayStorageShape, t2
bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
loadisFromInstruction(1, t0)
loadq ArrayStorage::m_vector[t3, t1, 8], t2
- btqz t2, .opGetByValSlow
+ btqz t2, .opGetByValOutOfBounds
.opGetByValDone:
storeq t2, [cfr, t0, 8]
@@ -1070,6 +1049,11 @@ _llint_op_get_by_val:
valueProfile(t2, t0)
dispatch(6)
+.opGetByValOutOfBounds:
+ if VALUE_PROFILER
+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
+ end
.opGetByValSlow:
callSlowPath(_llint_slow_path_get_by_val)
dispatch(6)
@@ -1089,7 +1073,7 @@ _llint_op_get_argument_by_val:
negi t2
sxi2q t2, t2
loadisFromInstruction(1, t3)
- loadpFromInstruction(4, t1)
+ loadpFromInstruction(5, t1)
loadq ThisArgumentOffset[cfr, t2, 8], t0
storeq t0, [cfr, t3, 8]
valueProfile(t0, t1)
@@ -1133,20 +1117,20 @@ _llint_op_get_by_pname:
macro contiguousPutByVal(storeCallback)
- biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
.storeResult:
loadisFromInstruction(3, t2)
storeCallback(t2, t1, [t0, t3, 8])
dispatch(5)
.outOfBounds:
- biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
if VALUE_PROFILER
loadp 32[PB, PC, 8], t2
storeb 1, ArrayProfile::m_mayStoreToHole[t2]
end
addi 1, t3, t2
- storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
+ storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .storeResult
end
@@ -1197,7 +1181,7 @@ _llint_op_put_by_val:
.opPutByValNotContiguous:
bineq t2, ArrayStorageShape, .opPutByValSlow
- biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
+ biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
btqz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty
.opPutByValArrayStorageStoreResult:
loadisFromInstruction(3, t2)
@@ -1212,21 +1196,21 @@ _llint_op_put_by_val:
storeb 1, ArrayProfile::m_mayStoreToHole[t1]
end
addi 1, ArrayStorage::m_numValuesInVector[t0]
- bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
+ bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
addi 1, t3, t1
- storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
+ storei t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .opPutByValArrayStorageStoreResult
+.opPutByValOutOfBounds:
+ if VALUE_PROFILER
+ loadpFromInstruction(4, t0)
+ storeb 1, ArrayProfile::m_outOfBounds[t0]
+ end
.opPutByValSlow:
callSlowPath(_llint_slow_path_put_by_val)
dispatch(5)
-_llint_op_loop:
- traceExecution()
- dispatchIntIndirect(1)
-
-
_llint_op_jmp:
traceExecution()
dispatchIntIndirect(1)
@@ -1581,16 +1565,16 @@ _llint_op_catch:
# 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.
+ # set VM::targetInterpreterPCForThrow.
move t0, cfr
loadp CodeBlock[cfr], PB
loadp CodeBlock::m_instructions[PB], PB
- loadp JITStackFrame::globalData[sp], t3
- loadp JSGlobalData::targetInterpreterPCForThrow[t3], PC
+ loadp JITStackFrame::vm[sp], t3
+ loadp VM::targetInterpreterPCForThrow[t3], PC
subp PB, PC
rshiftp 3, PC
- loadq JSGlobalData::exception[t3], t0
- storeq 0, JSGlobalData::exception[t3]
+ loadq VM::exception[t3], t0
+ storeq 0, VM::exception[t3]
loadisFromInstruction(1, t2)
storeq t0, [cfr, t2, 8]
traceExecution()
@@ -1610,23 +1594,84 @@ _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]
+ loadp JITStackFrame::vm[sp], t1
+ loadp VM::callFrameForThrow[t1], t0
+ jmp VM::targetMachinePCForThrow[t1]
_llint_throw_during_call_trampoline:
preserveReturnAddressAfterCall(t2)
- loadp JITStackFrame::globalData[sp], t1
- loadp JSGlobalData::callFrameForThrow[t1], t0
- jmp JSGlobalData::targetMachinePCForThrow[t1]
+ loadp JITStackFrame::vm[sp], t1
+ loadp VM::callFrameForThrow[t1], t0
+ jmp VM::targetMachinePCForThrow[t1]
+
+# Gives you the scope in t0, while allowing you to optionally perform additional checks on the
+# scopes as they are traversed. scopeCheck() is called with two arguments: the register
+# holding the scope, and a register that can be used for scratch. Note that this does not
+# use t3, so you can hold stuff in t3 if need be.
+macro getDeBruijnScope(deBruijinIndexOperand, scopeCheck)
+ loadp ScopeChain[cfr], t0
+ loadis deBruijinIndexOperand, t2
+
+ btiz t2, .done
+ loadp CodeBlock[cfr], t1
+ bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
+ btbz CodeBlock::m_needsActivation[t1], .loop
+
+ loadis CodeBlock::m_activationRegister[t1], t1
+
+ # Need to conditionally skip over one scope.
+ btpz [cfr, t1, 8], .noActivation
+ scopeCheck(t0, t1)
+ loadp JSScope::m_next[t0], t0
+.noActivation:
+ subi 1, t2
+
+ btiz t2, .done
+.loop:
+ scopeCheck(t0, t1)
+ loadp JSScope::m_next[t0], t0
+ subi 1, t2
+ btinz t2, .loop
+
+.done:
+end
+
+_llint_op_get_scoped_var:
+ traceExecution()
+ # Operands are as follows:
+ # pc[1]: Destination for the load
+ # pc[2]: Index of register in the scope
+ # 24[PB, PC, 8] De Bruijin index.
+ getDeBruijnScope(24[PB, PC, 8], macro (scope, scratch) end)
+ loadisFromInstruction(1, t1)
+ loadisFromInstruction(2, t2)
+
+ 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()
+ getDeBruijnScope(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 JSVariableObject::m_registers[t0], t0
+ storep t3, [t0, t1, 8]
+ dispatch(4)
macro nativeCallTrampoline(executableOffsetToFunction)
storep 0, CodeBlock[cfr]
if X86_64
- loadp JITStackFrame::globalData + 8[sp], t0
- storep cfr, JSGlobalData::topCallFrame[t0]
+ loadp JITStackFrame::vm + 8[sp], t0
+ storep cfr, VM::topCallFrame[t0]
loadp CallerFrame[cfr], t0
loadq ScopeChain[t0], t1
storeq t1, ScopeChain[cfr]
@@ -1639,15 +1684,15 @@ macro nativeCallTrampoline(executableOffsetToFunction)
move t0, cfr # Restore cfr to avoid loading from stack
call executableOffsetToFunction[t1]
addp 16 - 8, sp
- loadp JITStackFrame::globalData + 8[sp], t3
+ loadp JITStackFrame::vm + 8[sp], t3
elsif C_LOOP
loadp CallerFrame[cfr], t0
loadp ScopeChain[t0], t1
storep t1, ScopeChain[cfr]
- loadp JITStackFrame::globalData[sp], t3
- storep cfr, JSGlobalData::topCallFrame[t3]
+ loadp JITStackFrame::vm[sp], t3
+ storep cfr, VM::topCallFrame[t3]
move t0, t2
preserveReturnAddressAfterCall(t3)
@@ -1659,20 +1704,20 @@ macro nativeCallTrampoline(executableOffsetToFunction)
cloopCallNative executableOffsetToFunction[t1]
restoreReturnAddressBeforeReturn(t3)
- loadp JITStackFrame::globalData[sp], t3
+ loadp JITStackFrame::vm[sp], t3
else
error
end
- btqnz JSGlobalData::exception[t3], .exception
+ btqnz VM::exception[t3], .exception
ret
.exception:
preserveReturnAddressAfterCall(t1)
loadi ArgumentCount + TagOffset[cfr], PC
loadp CodeBlock[cfr], PB
loadp CodeBlock::m_instructions[PB], PB
- loadp JITStackFrame::globalData[sp], t0
- storep cfr, JSGlobalData::topCallFrame[t0]
+ loadp JITStackFrame::vm[sp], t0
+ storep cfr, VM::topCallFrame[t0]
callSlowPath(_llint_throw_from_native_call)
jmp _llint_throw_from_slow_path_trampoline
end
diff --git a/Source/JavaScriptCore/offlineasm/arm.rb b/Source/JavaScriptCore/offlineasm/arm.rb
new file mode 100644
index 000000000..498333ba2
--- /dev/null
+++ b/Source/JavaScriptCore/offlineasm/arm.rb
@@ -0,0 +1,587 @@
+# Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+# Copyright (C) 2013 University of Szeged. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+require "config"
+require "ast"
+require "opt"
+require "risc"
+
+def isARMv7
+ case $activeBackend
+ when "ARMv7"
+ true
+ when "ARMv7_TRADITIONAL", "ARM"
+ false
+ else
+ raise "bad value for $activeBackend: #{$activeBackend}"
+ end
+end
+
+def isARMv7Traditional
+ case $activeBackend
+ when "ARMv7_TRADITIONAL"
+ true
+ when "ARMv7", "ARM"
+ false
+ else
+ raise "bad value for $activeBackend: #{$activeBackend}"
+ end
+end
+
+class Node
+ def armSingle
+ doubleOperand = armOperand
+ raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^d/
+ "s" + ($~.post_match.to_i * 2).to_s
+ end
+end
+
+class SpecialRegister
+ def armOperand
+ @name
+ end
+end
+
+ARM_EXTRA_GPRS = [SpecialRegister.new("r9"), SpecialRegister.new("r8"), SpecialRegister.new("r3")]
+ARM_EXTRA_FPRS = [SpecialRegister.new("d7")]
+ARM_SCRATCH_FPR = SpecialRegister.new("d6")
+
+def armMoveImmediate(value, register)
+ # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
+ if value >= 0 && value < 256
+ $asm.puts "mov #{register.armOperand}, \##{value}"
+ elsif (~value) >= 0 && (~value) < 256
+ $asm.puts "mvn #{register.armOperand}, \##{~value}"
+ elsif isARMv7 or isARMv7Traditional
+ $asm.puts "movw #{register.armOperand}, \##{value & 0xffff}"
+ if (value & 0xffff0000) != 0
+ $asm.puts "movt #{register.armOperand}, \##{(value >> 16) & 0xffff}"
+ end
+ else
+ $asm.puts "ldr #{register.armOperand}, =#{value}"
+ end
+end
+
+class RegisterID
+ def armOperand
+ case name
+ when "t0", "a0", "r0"
+ "r0"
+ when "t1", "a1", "r1"
+ "r1"
+ when "t2", "a2"
+ "r2"
+ when "a3"
+ "r3"
+ when "t3"
+ "r4"
+ when "t4"
+ "r10"
+ when "cfr"
+ "r5"
+ when "lr"
+ "lr"
+ when "sp"
+ "sp"
+ else
+ raise "Bad register #{name} for ARM at #{codeOriginString}"
+ end
+ end
+end
+
+class FPRegisterID
+ def armOperand
+ case name
+ when "ft0", "fr"
+ "d0"
+ when "ft1"
+ "d1"
+ when "ft2"
+ "d2"
+ when "ft3"
+ "d3"
+ when "ft4"
+ "d4"
+ when "ft5"
+ "d5"
+ else
+ raise "Bad register #{name} for ARM at #{codeOriginString}"
+ end
+ end
+end
+
+class Immediate
+ def armOperand
+ raise "Invalid immediate #{value} at #{codeOriginString}" if value < 0 or value > 255
+ "\##{value}"
+ end
+end
+
+class Address
+ def armOperand
+ raise "Bad offset at #{codeOriginString}" if offset.value < -0xff or offset.value > 0xfff
+ "[#{base.armOperand}, \##{offset.value}]"
+ end
+end
+
+class BaseIndex
+ def armOperand
+ raise "Bad offset at #{codeOriginString}" if offset.value != 0
+ "[#{base.armOperand}, #{index.armOperand}, lsl \##{scaleShift}]"
+ end
+end
+
+class AbsoluteAddress
+ def armOperand
+ raise "Unconverted absolute address at #{codeOriginString}"
+ end
+end
+
+#
+# Lea support.
+#
+
+class Address
+ def armEmitLea(destination)
+ if destination == base
+ $asm.puts "adds #{destination.armOperand}, \##{offset.value}"
+ else
+ $asm.puts "adds #{destination.armOperand}, #{base.armOperand}, \##{offset.value}"
+ end
+ end
+end
+
+class BaseIndex
+ def armEmitLea(destination)
+ raise "Malformed BaseIndex, offset should be zero at #{codeOriginString}" unless offset.value == 0
+ $asm.puts "add #{destination.armOperand}, #{base.armOperand}, #{index.armOperand}, lsl \##{scaleShift}"
+ end
+end
+
+# FIXME: we could support AbsoluteAddress for lea, but we don't.
+
+#
+# Actual lowering code follows.
+#
+
+class Sequence
+ def getModifiedListARM
+ raise unless $activeBackend == "ARM"
+ getModifiedListARMCommon
+ end
+
+ def getModifiedListARMv7
+ raise unless $activeBackend == "ARMv7"
+ getModifiedListARMCommon
+ end
+
+ def getModifiedListARMv7_TRADITIONAL
+ raise unless $activeBackend == "ARMv7_TRADITIONAL"
+ getModifiedListARMCommon
+ end
+
+ def getModifiedListARMCommon
+ result = @list
+ result = riscLowerSimpleBranchOps(result)
+ result = riscLowerHardBranchOps(result)
+ result = riscLowerShiftOps(result)
+ result = riscLowerMalformedAddresses(result) {
+ | node, address |
+ if address.is_a? BaseIndex
+ address.offset.value == 0
+ elsif address.is_a? Address
+ (-0xff..0xfff).include? address.offset.value
+ else
+ false
+ end
+ }
+ result = riscLowerMalformedAddressesDouble(result)
+ result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep"])
+ result = riscLowerMalformedImmediates(result, 0..0xff)
+ result = riscLowerMisplacedAddresses(result)
+ result = riscLowerRegisterReuse(result)
+ result = assignRegistersToTemporaries(result, :gpr, ARM_EXTRA_GPRS)
+ result = assignRegistersToTemporaries(result, :fpr, ARM_EXTRA_FPRS)
+ return result
+ end
+end
+
+def armOperands(operands)
+ operands.map{|v| v.armOperand}.join(", ")
+end
+
+def armFlippedOperands(operands)
+ armOperands([operands[-1]] + operands[0..-2])
+end
+
+def emitArmCompact(opcode2, opcode3, operands)
+ if operands.size == 3
+ $asm.puts "#{opcode3} #{armFlippedOperands(operands)}"
+ else
+ raise unless operands.size == 2
+ raise unless operands[1].register?
+ if operands[0].immediate?
+ $asm.puts "#{opcode3} #{operands[1].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
+ else
+ $asm.puts "#{opcode2} #{armFlippedOperands(operands)}"
+ end
+ end
+end
+
+def emitArm(opcode, operands)
+ if operands.size == 3
+ $asm.puts "#{opcode} #{armFlippedOperands(operands)}"
+ else
+ raise unless operands.size == 2
+ $asm.puts "#{opcode} #{operands[1].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
+ end
+end
+
+def emitArmDoubleBranch(branchOpcode, operands)
+ $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
+ $asm.puts "vmrs apsr_nzcv, fpscr"
+ $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
+end
+
+def emitArmTest(operands)
+ value = operands[0]
+ case operands.size
+ when 2
+ mask = Immediate.new(codeOrigin, -1)
+ when 3
+ mask = operands[1]
+ else
+ raise "Expected 2 or 3 operands but got #{operands.size} at #{codeOriginString}"
+ end
+
+ if mask.immediate? and mask.value == -1
+ $asm.puts "tst #{value.armOperand}, #{value.armOperand}"
+ else
+ $asm.puts "tst #{value.armOperand}, #{mask.armOperand}"
+ end
+end
+
+def emitArmCompare(operands, code)
+ $asm.puts "movs #{operands[2].armOperand}, \#0"
+ $asm.puts "cmp #{operands[0].armOperand}, #{operands[1].armOperand}"
+ $asm.puts "it #{code}"
+ $asm.puts "mov#{code} #{operands[2].armOperand}, \#1"
+end
+
+def emitArmTestSet(operands, code)
+ $asm.puts "movs #{operands[-1].armOperand}, \#0"
+ emitArmTest(operands)
+ $asm.puts "it #{code}"
+ $asm.puts "mov#{code} #{operands[-1].armOperand}, \#1"
+end
+
+class Instruction
+ def lowerARM
+ raise unless $activeBackend == "ARM"
+ lowerARMCommon
+ end
+
+ def lowerARMv7
+ raise unless $activeBackend == "ARMv7"
+ lowerARMCommon
+ end
+
+ def lowerARMv7_TRADITIONAL
+ raise unless $activeBackend == "ARMv7_TRADITIONAL"
+ lowerARMCommon
+ end
+
+ def lowerARMCommon
+ $asm.codeOrigin codeOriginString if $enableCodeOriginComments
+ $asm.annotation annotation if $enableInstrAnnotations
+
+ case opcode
+ when "addi", "addp", "addis", "addps"
+ if opcode == "addis" or opcode == "addps"
+ suffix = "s"
+ else
+ suffix = ""
+ end
+ if operands.size == 3 and operands[0].immediate?
+ raise unless operands[1].register?
+ raise unless operands[2].register?
+ if operands[0].value == 0 and suffix.empty?
+ unless operands[1] == operands[2]
+ $asm.puts "mov #{operands[2].armOperand}, #{operands[1].armOperand}"
+ end
+ else
+ $asm.puts "adds #{operands[2].armOperand}, #{operands[1].armOperand}, #{operands[0].armOperand}"
+ end
+ elsif operands.size == 3 and operands[0].immediate?
+ raise unless operands[1].register?
+ raise unless operands[2].register?
+ $asm.puts "adds #{armFlippedOperands(operands)}"
+ else
+ if operands[0].immediate?
+ unless Immediate.new(nil, 0) == operands[0]
+ $asm.puts "adds #{armFlippedOperands(operands)}"
+ end
+ else
+ $asm.puts "add#{suffix} #{armFlippedOperands(operands)}"
+ end
+ end
+ when "andi", "andp"
+ emitArmCompact("ands", "and", operands)
+ when "ori", "orp"
+ emitArmCompact("orrs", "orr", operands)
+ when "oris"
+ emitArmCompact("orrs", "orrs", operands)
+ when "xori", "xorp"
+ emitArmCompact("eors", "eor", operands)
+ when "lshifti", "lshiftp"
+ emitArmCompact("lsls", "lsls", operands)
+ when "rshifti", "rshiftp"
+ emitArmCompact("asrs", "asrs", operands)
+ when "urshifti", "urshiftp"
+ emitArmCompact("lsrs", "lsrs", operands)
+ when "muli", "mulp"
+ emitArm("mul", operands)
+ when "subi", "subp", "subis"
+ emitArmCompact("subs", "subs", operands)
+ when "negi", "negp"
+ $asm.puts "rsbs #{operands[0].armOperand}, #{operands[0].armOperand}, \#0"
+ when "noti"
+ $asm.puts "mvns #{operands[0].armOperand}, #{operands[0].armOperand}"
+ when "loadi", "loadis", "loadp"
+ $asm.puts "ldr #{armFlippedOperands(operands)}"
+ when "storei", "storep"
+ $asm.puts "str #{armOperands(operands)}"
+ when "loadb"
+ $asm.puts "ldrb #{armFlippedOperands(operands)}"
+ when "loadbs"
+ $asm.puts "ldrsb.w #{armFlippedOperands(operands)}"
+ when "storeb"
+ $asm.puts "strb #{armOperands(operands)}"
+ when "loadh"
+ $asm.puts "ldrh #{armFlippedOperands(operands)}"
+ when "loadhs"
+ $asm.puts "ldrsh.w #{armFlippedOperands(operands)}"
+ when "storeh"
+ $asm.puts "strh #{armOperands(operands)}"
+ when "loadd"
+ $asm.puts "vldr.64 #{armFlippedOperands(operands)}"
+ when "stored"
+ $asm.puts "vstr.64 #{armOperands(operands)}"
+ when "addd"
+ emitArm("vadd.f64", operands)
+ when "divd"
+ emitArm("vdiv.f64", operands)
+ when "subd"
+ emitArm("vsub.f64", operands)
+ when "muld"
+ emitArm("vmul.f64", operands)
+ when "sqrtd"
+ $asm.puts "vsqrt.f64 #{armFlippedOperands(operands)}"
+ when "ci2d"
+ $asm.puts "vmov #{operands[1].armSingle}, #{operands[0].armOperand}"
+ $asm.puts "vcvt.f64.s32 #{operands[1].armOperand}, #{operands[1].armSingle}"
+ when "bdeq"
+ emitArmDoubleBranch("beq", operands)
+ when "bdneq"
+ $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
+ $asm.puts "vmrs apsr_nzcv, fpscr"
+ isUnordered = LocalLabel.unique("bdneq")
+ $asm.puts "bvs #{LocalLabelReference.new(codeOrigin, isUnordered).asmLabel}"
+ $asm.puts "bne #{operands[2].asmLabel}"
+ isUnordered.lower("ARM")
+ when "bdgt"
+ emitArmDoubleBranch("bgt", operands)
+ when "bdgteq"
+ emitArmDoubleBranch("bge", operands)
+ when "bdlt"
+ emitArmDoubleBranch("bmi", operands)
+ when "bdlteq"
+ emitArmDoubleBranch("bls", operands)
+ when "bdequn"
+ $asm.puts "vcmpe.f64 #{armOperands(operands[0..1])}"
+ $asm.puts "vmrs apsr_nzcv, fpscr"
+ $asm.puts "bvs #{operands[2].asmLabel}"
+ $asm.puts "beq #{operands[2].asmLabel}"
+ when "bdnequn"
+ emitArmDoubleBranch("bne", operands)
+ when "bdgtun"
+ emitArmDoubleBranch("bhi", operands)
+ when "bdgtequn"
+ emitArmDoubleBranch("bpl", operands)
+ when "bdltun"
+ emitArmDoubleBranch("blt", operands)
+ when "bdltequn"
+ emitArmDoubleBranch("ble", operands)
+ when "btd2i"
+ # FIXME: may be a good idea to just get rid of this instruction, since the interpreter
+ # currently does not use it.
+ raise "ARM does not support this opcode yet, #{codeOrigin}"
+ when "td2i"
+ $asm.puts "vcvt.s32.f64 #{ARM_SCRATCH_FPR.armSingle}, #{operands[0].armOperand}"
+ $asm.puts "vmov #{operands[1].armOperand}, #{ARM_SCRATCH_FPR.armSingle}"
+ when "bcd2i"
+ $asm.puts "vcvt.s32.f64 #{ARM_SCRATCH_FPR.armSingle}, #{operands[0].armOperand}"
+ $asm.puts "vmov #{operands[1].armOperand}, #{ARM_SCRATCH_FPR.armSingle}"
+ $asm.puts "vcvt.f64.s32 #{ARM_SCRATCH_FPR.armOperand}, #{ARM_SCRATCH_FPR.armSingle}"
+ emitArmDoubleBranch("bne", [ARM_SCRATCH_FPR, operands[0], operands[2]])
+ $asm.puts "tst #{operands[1].armOperand}, #{operands[1].armOperand}"
+ $asm.puts "beq #{operands[2].asmLabel}"
+ when "movdz"
+ # FIXME: either support this or remove it.
+ raise "ARM does not support this opcode yet, #{codeOrigin}"
+ when "pop"
+ $asm.puts "pop #{operands[0].armOperand}"
+ when "push"
+ $asm.puts "push #{operands[0].armOperand}"
+ when "move"
+ if operands[0].immediate?
+ armMoveImmediate(operands[0].value, operands[1])
+ else
+ $asm.puts "mov #{armFlippedOperands(operands)}"
+ end
+ when "nop"
+ $asm.puts "nop"
+ when "bieq", "bpeq", "bbeq"
+ if Immediate.new(nil, 0) == operands[0]
+ $asm.puts "tst #{operands[1].armOperand}, #{operands[1].armOperand}"
+ elsif Immediate.new(nil, 0) == operands[1]
+ $asm.puts "tst #{operands[0].armOperand}, #{operands[0].armOperand}"
+ else
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ end
+ $asm.puts "beq #{operands[2].asmLabel}"
+ when "bineq", "bpneq", "bbneq"
+ if Immediate.new(nil, 0) == operands[0]
+ $asm.puts "tst #{operands[1].armOperand}, #{operands[1].armOperand}"
+ elsif Immediate.new(nil, 0) == operands[1]
+ $asm.puts "tst #{operands[0].armOperand}, #{operands[0].armOperand}"
+ else
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ end
+ $asm.puts "bne #{operands[2].asmLabel}"
+ when "bia", "bpa", "bba"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "bhi #{operands[2].asmLabel}"
+ when "biaeq", "bpaeq", "bbaeq"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "bhs #{operands[2].asmLabel}"
+ when "bib", "bpb", "bbb"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "blo #{operands[2].asmLabel}"
+ when "bibeq", "bpbeq", "bbbeq"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "bls #{operands[2].asmLabel}"
+ when "bigt", "bpgt", "bbgt"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "bgt #{operands[2].asmLabel}"
+ when "bigteq", "bpgteq", "bbgteq"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "bge #{operands[2].asmLabel}"
+ when "bilt", "bplt", "bblt"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "blt #{operands[2].asmLabel}"
+ when "bilteq", "bplteq", "bblteq"
+ $asm.puts "cmp #{armOperands(operands[0..1])}"
+ $asm.puts "ble #{operands[2].asmLabel}"
+ when "btiz", "btpz", "btbz"
+ emitArmTest(operands)
+ $asm.puts "beq #{operands[-1].asmLabel}"
+ when "btinz", "btpnz", "btbnz"
+ emitArmTest(operands)
+ $asm.puts "bne #{operands[-1].asmLabel}"
+ when "btis", "btps", "btbs"
+ emitArmTest(operands)
+ $asm.puts "bmi #{operands[-1].asmLabel}"
+ when "jmp"
+ if operands[0].label?
+ $asm.puts "b #{operands[0].asmLabel}"
+ else
+ $asm.puts "mov pc, #{operands[0].armOperand}"
+ end
+ if not isARMv7 and not isARMv7Traditional
+ $asm.puts ".ltorg"
+ end
+ when "call"
+ if operands[0].label?
+ $asm.puts "blx #{operands[0].asmLabel}"
+ else
+ $asm.puts "blx #{operands[0].armOperand}"
+ end
+ when "break"
+ $asm.puts "bkpt #0"
+ when "ret"
+ $asm.puts "bx lr"
+ when "cieq", "cpeq", "cbeq"
+ emitArmCompare(operands, "eq")
+ when "cineq", "cpneq", "cbneq"
+ emitArmCompare(operands, "ne")
+ when "cia", "cpa", "cba"
+ emitArmCompare(operands, "hi")
+ when "ciaeq", "cpaeq", "cbaeq"
+ emitArmCompare(operands, "hs")
+ when "cib", "cpb", "cbb"
+ emitArmCompare(operands, "lo")
+ when "cibeq", "cpbeq", "cbbeq"
+ emitArmCompare(operands, "ls")
+ when "cigt", "cpgt", "cbgt"
+ emitArmCompare(operands, "gt")
+ when "cigteq", "cpgteq", "cbgteq"
+ emitArmCompare(operands, "ge")
+ when "cilt", "cplt", "cblt"
+ emitArmCompare(operands, "lt")
+ when "cilteq", "cplteq", "cblteq"
+ emitArmCompare(operands, "le")
+ when "tis", "tbs", "tps"
+ emitArmTestSet(operands, "mi")
+ when "tiz", "tbz", "tpz"
+ emitArmTestSet(operands, "eq")
+ when "tinz", "tbnz", "tpnz"
+ emitArmTestSet(operands, "ne")
+ when "peek"
+ $asm.puts "ldr #{operands[1].armOperand}, [sp, \##{operands[0].value * 4}]"
+ when "poke"
+ $asm.puts "str #{operands[1].armOperand}, [sp, \##{operands[0].value * 4}]"
+ when "fii2d"
+ $asm.puts "vmov #{operands[2].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
+ when "fd2ii"
+ $asm.puts "vmov #{operands[1].armOperand}, #{operands[2].armOperand}, #{operands[0].armOperand}"
+ when "bo"
+ $asm.puts "bvs #{operands[0].asmLabel}"
+ when "bs"
+ $asm.puts "bmi #{operands[0].asmLabel}"
+ when "bz"
+ $asm.puts "beq #{operands[0].asmLabel}"
+ when "bnz"
+ $asm.puts "bne #{operands[0].asmLabel}"
+ when "leai", "leap"
+ operands[0].armEmitLea(operands[1])
+ when "smulli"
+ raise "Wrong number of arguments to smull in #{self.inspect} at #{codeOriginString}" unless operands.length == 4
+ $asm.puts "smull #{operands[2].armOperand}, #{operands[3].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}"
+ else
+ lowerDefault
+ end
+ end
+end
+
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb
deleted file mode 100644
index 078be8c0f..000000000
--- a/Source/JavaScriptCore/offlineasm/armv7.rb
+++ /dev/null
@@ -1,531 +0,0 @@
-# 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.
-
-require "config"
-require "ast"
-require "opt"
-require "risc"
-
-class Node
- def armV7Single
- doubleOperand = armV7Operand
- raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^d/
- "s" + ($~.post_match.to_i * 2).to_s
- end
-end
-
-class SpecialRegister
- def armV7Operand
- @name
- end
-end
-
-ARMv7_EXTRA_GPRS = [SpecialRegister.new("r9"), SpecialRegister.new("r8"), SpecialRegister.new("r3")]
-ARMv7_EXTRA_FPRS = [SpecialRegister.new("d7")]
-ARMv7_SCRATCH_FPR = SpecialRegister.new("d8")
-
-def armV7MoveImmediate(value, register)
- # Currently we only handle the simple cases, and fall back to mov/movt for the complex ones.
- if value >= 0 && value < 256
- $asm.puts "movw #{register.armV7Operand}, \##{value}"
- elsif (~value) >= 0 && (~value) < 256
- $asm.puts "mvn #{register.armV7Operand}, \##{~value}"
- else
- $asm.puts "movw #{register.armV7Operand}, \##{value & 0xffff}"
- if (value & 0xffff0000) != 0
- $asm.puts "movt #{register.armV7Operand}, \##{(value >> 16) & 0xffff}"
- end
- end
-end
-
-class RegisterID
- def armV7Operand
- case name
- when "t0", "a0", "r0"
- "r0"
- when "t1", "a1", "r1"
- "r1"
- when "t2", "a2"
- "r2"
- when "a3"
- "r3"
- when "t3"
- "r4"
- when "t4"
- "r10"
- when "cfr"
- "r5"
- when "lr"
- "lr"
- when "sp"
- "sp"
- else
- raise "Bad register #{name} for ARMv7 at #{codeOriginString}"
- end
- end
-end
-
-class FPRegisterID
- def armV7Operand
- case name
- when "ft0", "fr"
- "d0"
- when "ft1"
- "d1"
- when "ft2"
- "d2"
- when "ft3"
- "d3"
- when "ft4"
- "d4"
- when "ft5"
- "d5"
- else
- raise "Bad register #{name} for ARMv7 at #{codeOriginString}"
- end
- end
-end
-
-class Immediate
- def armV7Operand
- raise "Invalid immediate #{value} at #{codeOriginString}" if value < 0 or value > 255
- "\##{value}"
- end
-end
-
-class Address
- def armV7Operand
- raise "Bad offset at #{codeOriginString}" if offset.value < -0xff or offset.value > 0xfff
- "[#{base.armV7Operand}, \##{offset.value}]"
- end
-end
-
-class BaseIndex
- def armV7Operand
- raise "Bad offset at #{codeOriginString}" if offset.value != 0
- "[#{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scaleShift}]"
- end
-end
-
-class AbsoluteAddress
- def armV7Operand
- raise "Unconverted absolute address at #{codeOriginString}"
- end
-end
-
-#
-# Lea support.
-#
-
-class Address
- def armV7EmitLea(destination)
- if destination == base
- $asm.puts "adds #{destination.armV7Operand}, \##{offset.value}"
- else
- $asm.puts "adds #{destination.armV7Operand}, #{base.armV7Operand}, \##{offset.value}"
- end
- end
-end
-
-class BaseIndex
- def armV7EmitLea(destination)
- raise "Malformed BaseIndex, offset should be zero at #{codeOriginString}" unless offset.value == 0
- $asm.puts "add.w #{destination.armV7Operand}, #{base.armV7Operand}, #{index.armV7Operand}, lsl \##{scaleShift}"
- end
-end
-
-# FIXME: we could support AbsoluteAddress for lea, but we don't.
-
-#
-# Actual lowering code follows.
-#
-
-class Sequence
- def getModifiedListARMv7
- result = @list
- result = riscLowerSimpleBranchOps(result)
- result = riscLowerHardBranchOps(result)
- result = riscLowerShiftOps(result)
- result = riscLowerMalformedAddresses(result) {
- | node, address |
- if address.is_a? BaseIndex
- address.offset.value == 0
- elsif address.is_a? Address
- (-0xff..0xfff).include? address.offset.value
- else
- false
- end
- }
- result = riscLowerMalformedAddressesDouble(result)
- result = riscLowerMisplacedImmediates(result)
- result = riscLowerMalformedImmediates(result, 0..0xff)
- result = riscLowerMisplacedAddresses(result)
- result = riscLowerRegisterReuse(result)
- result = assignRegistersToTemporaries(result, :gpr, ARMv7_EXTRA_GPRS)
- result = assignRegistersToTemporaries(result, :fpr, ARMv7_EXTRA_FPRS)
- return result
- end
-end
-
-def armV7Operands(operands)
- operands.map{|v| v.armV7Operand}.join(", ")
-end
-
-def armV7FlippedOperands(operands)
- armV7Operands([operands[-1]] + operands[0..-2])
-end
-
-def emitArmV7Compact(opcode2, opcode3, operands)
- if operands.size == 3
- $asm.puts "#{opcode3} #{armV7FlippedOperands(operands)}"
- else
- raise unless operands.size == 2
- raise unless operands[1].register?
- if operands[0].is_a? Immediate
- $asm.puts "#{opcode3} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
- else
- $asm.puts "#{opcode2} #{armV7FlippedOperands(operands)}"
- end
- end
-end
-
-def emitArmV7(opcode, operands)
- if operands.size == 3
- $asm.puts "#{opcode} #{armV7FlippedOperands(operands)}"
- else
- raise unless operands.size == 2
- $asm.puts "#{opcode} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
- end
-end
-
-def emitArmV7DoubleBranch(branchOpcode, operands)
- $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
- $asm.puts "vmrs apsr_nzcv, fpscr"
- $asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
-end
-
-def emitArmV7Test(operands)
- value = operands[0]
- case operands.size
- when 2
- mask = Immediate.new(codeOrigin, -1)
- when 3
- mask = operands[1]
- else
- raise "Expected 2 or 3 operands but got #{operands.size} at #{codeOriginString}"
- end
-
- if mask.is_a? Immediate and mask.value == -1
- $asm.puts "tst #{value.armV7Operand}, #{value.armV7Operand}"
- elsif mask.is_a? Immediate
- $asm.puts "tst.w #{value.armV7Operand}, #{mask.armV7Operand}"
- else
- $asm.puts "tst #{value.armV7Operand}, #{mask.armV7Operand}"
- end
-end
-
-def emitArmV7Compare(operands, code)
- $asm.puts "movs #{operands[2].armV7Operand}, \#0"
- $asm.puts "cmp #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
- $asm.puts "it #{code}"
- $asm.puts "mov#{code} #{operands[2].armV7Operand}, \#1"
-end
-
-def emitArmV7TestSet(operands, code)
- $asm.puts "movs #{operands[-1].armV7Operand}, \#0"
- emitArmV7Test(operands)
- $asm.puts "it #{code}"
- $asm.puts "mov#{code} #{operands[-1].armV7Operand}, \#1"
-end
-
-class Instruction
- def lowerARMv7
- $asm.codeOrigin codeOriginString if $enableCodeOriginComments
- $asm.annotation annotation if $enableInstrAnnotations
-
- case opcode
- when "addi", "addp", "addis", "addps"
- if opcode == "addis" or opcode == "addps"
- suffix = "s"
- else
- suffix = ""
- end
- 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 and suffix.empty?
- unless operands[1] == operands[2]
- $asm.puts "mov #{operands[2].armV7Operand}, #{operands[1].armV7Operand}"
- end
- else
- $asm.puts "adds #{operands[2].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
- 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 "adds #{armV7FlippedOperands(operands)}"
- else
- if operands[0].is_a? Immediate
- unless Immediate.new(nil, 0) == operands[0]
- $asm.puts "adds #{armV7FlippedOperands(operands)}"
- end
- else
- $asm.puts "add#{suffix} #{armV7FlippedOperands(operands)}"
- end
- end
- when "andi", "andp"
- emitArmV7Compact("ands", "and", operands)
- when "ori", "orp"
- emitArmV7Compact("orrs", "orr", operands)
- when "oris"
- emitArmV7Compact("orrs", "orrs", operands)
- when "xori", "xorp"
- emitArmV7Compact("eors", "eor", operands)
- when "lshifti", "lshiftp"
- emitArmV7Compact("lsls", "lsls", operands)
- when "rshifti", "rshiftp"
- emitArmV7Compact("asrs", "asrs", operands)
- when "urshifti", "urshiftp"
- emitArmV7Compact("lsrs", "lsrs", operands)
- when "muli", "mulp"
- emitArmV7("mul", operands)
- when "subi", "subp", "subis"
- emitArmV7Compact("subs", "subs", operands)
- 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", "loadis", "loadp"
- $asm.puts "ldr #{armV7FlippedOperands(operands)}"
- when "storei", "storep"
- $asm.puts "str #{armV7Operands(operands)}"
- when "loadb"
- $asm.puts "ldrb #{armV7FlippedOperands(operands)}"
- when "loadbs"
- $asm.puts "ldrsb.w #{armV7FlippedOperands(operands)}"
- when "storeb"
- $asm.puts "strb #{armV7Operands(operands)}"
- when "loadh"
- $asm.puts "ldrh #{armV7FlippedOperands(operands)}"
- when "loadhs"
- $asm.puts "ldrsh.w #{armV7FlippedOperands(operands)}"
- when "storeh"
- $asm.puts "strh #{armV7Operands(operands)}"
- when "loadd"
- $asm.puts "vldr.64 #{armV7FlippedOperands(operands)}"
- when "stored"
- $asm.puts "vstr.64 #{armV7Operands(operands)}"
- when "addd"
- emitArmV7("vadd.f64", operands)
- when "divd"
- emitArmV7("vdiv.f64", operands)
- when "subd"
- emitArmV7("vsub.f64", operands)
- when "muld"
- emitArmV7("vmul.f64", operands)
- when "sqrtd"
- $asm.puts "vsqrt.f64 #{armV7FlippedOperands(operands)}"
- when "ci2d"
- $asm.puts "vmov #{operands[1].armV7Single}, #{operands[0].armV7Operand}"
- $asm.puts "vcvt.f64.s32 #{operands[1].armV7Operand}, #{operands[1].armV7Single}"
- when "bdeq"
- emitArmV7DoubleBranch("beq", operands)
- when "bdneq"
- $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
- $asm.puts "vmrs apsr_nzcv, fpscr"
- isUnordered = LocalLabel.unique("bdneq")
- $asm.puts "bvs #{LocalLabelReference.new(codeOrigin, isUnordered).asmLabel}"
- $asm.puts "bne #{operands[2].asmLabel}"
- isUnordered.lower("ARMv7")
- when "bdgt"
- emitArmV7DoubleBranch("bgt", operands)
- when "bdgteq"
- emitArmV7DoubleBranch("bge", operands)
- when "bdlt"
- emitArmV7DoubleBranch("bmi", operands)
- when "bdlteq"
- emitArmV7DoubleBranch("bls", operands)
- when "bdequn"
- $asm.puts "vcmpe.f64 #{armV7Operands(operands[0..1])}"
- $asm.puts "vmrs apsr_nzcv, fpscr"
- $asm.puts "bvs #{operands[2].asmLabel}"
- $asm.puts "beq #{operands[2].asmLabel}"
- when "bdnequn"
- emitArmV7DoubleBranch("bne", operands)
- when "bdgtun"
- emitArmV7DoubleBranch("bhi", operands)
- when "bdgtequn"
- emitArmV7DoubleBranch("bpl", operands)
- when "bdltun"
- emitArmV7DoubleBranch("blt", operands)
- when "bdltequn"
- emitArmV7DoubleBranch("ble", operands)
- when "btd2i"
- # FIXME: may be a good idea to just get rid of this instruction, since the interpreter
- # currently does not use it.
- raise "ARMv7 does not support this opcode yet, #{codeOrigin}"
- when "td2i"
- $asm.puts "vcvt.s32.f64 #{ARMv7_SCRATCH_FPR.armV7Single}, #{operands[0].armV7Operand}"
- $asm.puts "vmov #{operands[1].armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
- when "bcd2i"
- $asm.puts "vcvt.s32.f64 #{ARMv7_SCRATCH_FPR.armV7Single}, #{operands[0].armV7Operand}"
- $asm.puts "vmov #{operands[1].armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
- $asm.puts "vcvt.f64.s32 #{ARMv7_SCRATCH_FPR.armV7Operand}, #{ARMv7_SCRATCH_FPR.armV7Single}"
- emitArmV7DoubleBranch("bne", [ARMv7_SCRATCH_FPR, operands[0], operands[2]])
- $asm.puts "tst #{operands[1].armV7Operand}, #{operands[1].armV7Operand}"
- $asm.puts "beq #{operands[2].asmLabel}"
- when "movdz"
- # FIXME: either support this or remove it.
- raise "ARMv7 does not support this opcode yet, #{codeOrigin}"
- when "pop"
- $asm.puts "pop #{operands[0].armV7Operand}"
- when "push"
- $asm.puts "push #{operands[0].armV7Operand}"
- when "move"
- if operands[0].is_a? Immediate
- armV7MoveImmediate(operands[0].value, operands[1])
- else
- $asm.puts "mov #{armV7FlippedOperands(operands)}"
- end
- when "nop"
- $asm.puts "nop"
- when "bieq", "bpeq", "bbeq"
- if Immediate.new(nil, 0) == operands[0]
- $asm.puts "tst #{operands[1].armV7Operand}, #{operands[1].armV7Operand}"
- elsif Immediate.new(nil, 0) == operands[1]
- $asm.puts "tst #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
- else
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- end
- $asm.puts "beq #{operands[2].asmLabel}"
- when "bineq", "bpneq", "bbneq"
- if Immediate.new(nil, 0) == operands[0]
- $asm.puts "tst #{operands[1].armV7Operand}, #{operands[1].armV7Operand}"
- elsif Immediate.new(nil, 0) == operands[1]
- $asm.puts "tst #{operands[0].armV7Operand}, #{operands[0].armV7Operand}"
- else
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- end
- $asm.puts "bne #{operands[2].asmLabel}"
- when "bia", "bpa", "bba"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "bhi #{operands[2].asmLabel}"
- when "biaeq", "bpaeq", "bbaeq"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "bhs #{operands[2].asmLabel}"
- when "bib", "bpb", "bbb"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "blo #{operands[2].asmLabel}"
- when "bibeq", "bpbeq", "bbbeq"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "bls #{operands[2].asmLabel}"
- when "bigt", "bpgt", "bbgt"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "bgt #{operands[2].asmLabel}"
- when "bigteq", "bpgteq", "bbgteq"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "bge #{operands[2].asmLabel}"
- when "bilt", "bplt", "bblt"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "blt #{operands[2].asmLabel}"
- when "bilteq", "bplteq", "bblteq"
- $asm.puts "cmp #{armV7Operands(operands[0..1])}"
- $asm.puts "ble #{operands[2].asmLabel}"
- when "btiz", "btpz", "btbz"
- emitArmV7Test(operands)
- $asm.puts "beq #{operands[-1].asmLabel}"
- when "btinz", "btpnz", "btbnz"
- emitArmV7Test(operands)
- $asm.puts "bne #{operands[-1].asmLabel}"
- when "btis", "btps", "btbs"
- emitArmV7Test(operands)
- $asm.puts "bmi #{operands[-1].asmLabel}"
- when "jmp"
- if operands[0].label?
- $asm.puts "b #{operands[0].asmLabel}"
- else
- $asm.puts "mov pc, #{operands[0].armV7Operand}"
- end
- when "call"
- if operands[0].label?
- $asm.puts "blx #{operands[0].asmLabel}"
- else
- $asm.puts "blx #{operands[0].armV7Operand}"
- end
- when "break"
- $asm.puts "bkpt #0"
- when "ret"
- $asm.puts "bx lr"
- when "cieq", "cpeq", "cbeq"
- emitArmV7Compare(operands, "eq")
- when "cineq", "cpneq", "cbneq"
- emitArmV7Compare(operands, "ne")
- when "cia", "cpa", "cba"
- emitArmV7Compare(operands, "hi")
- when "ciaeq", "cpaeq", "cbaeq"
- emitArmV7Compare(operands, "hs")
- when "cib", "cpb", "cbb"
- emitArmV7Compare(operands, "lo")
- when "cibeq", "cpbeq", "cbbeq"
- emitArmV7Compare(operands, "ls")
- when "cigt", "cpgt", "cbgt"
- emitArmV7Compare(operands, "gt")
- when "cigteq", "cpgteq", "cbgteq"
- emitArmV7Compare(operands, "ge")
- when "cilt", "cplt", "cblt"
- emitArmV7Compare(operands, "lt")
- when "cilteq", "cplteq", "cblteq"
- emitArmV7Compare(operands, "le")
- when "tis", "tbs", "tps"
- emitArmV7TestSet(operands, "mi")
- when "tiz", "tbz", "tpz"
- emitArmV7TestSet(operands, "eq")
- when "tinz", "tbnz", "tpnz"
- emitArmV7TestSet(operands, "ne")
- when "peek"
- $asm.puts "ldr #{operands[1].armV7Operand}, [sp, \##{operands[0].value * 4}]"
- when "poke"
- $asm.puts "str #{operands[1].armV7Operand}, [sp, \##{operands[0].value * 4}]"
- when "fii2d"
- $asm.puts "vmov #{operands[2].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
- when "fd2ii"
- $asm.puts "vmov #{operands[1].armV7Operand}, #{operands[2].armV7Operand}, #{operands[0].armV7Operand}"
- when "bo"
- $asm.puts "bvs #{operands[0].asmLabel}"
- when "bs"
- $asm.puts "bmi #{operands[0].asmLabel}"
- when "bz"
- $asm.puts "beq #{operands[0].asmLabel}"
- when "bnz"
- $asm.puts "bne #{operands[0].asmLabel}"
- when "leai", "leap"
- operands[0].armV7EmitLea(operands[1])
- when "smulli"
- raise "Wrong number of arguments to smull in #{self.inspect} at #{codeOriginString}" unless operands.length == 4
- $asm.puts "smull #{operands[2].armV7Operand}, #{operands[3].armV7Operand}, #{operands[0].armV7Operand}, #{operands[1].armV7Operand}"
- else
- lowerDefault
- end
- end
-end
-
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index 4f0c3fd88..74bccff56 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -671,6 +671,10 @@ class Address < Node
raise "Bad offset for address #{offset.inspect} at #{codeOriginString}" unless offset.is_a? Variable or offset.immediate?
end
+ def withOffset(extraOffset)
+ Address.new(codeOrigin, @base, Immediate.new(codeOrigin, @offset.value + extraOffset))
+ end
+
def children
[@base, @offset]
end
@@ -727,6 +731,10 @@ class BaseIndex < Node
end
end
+ def withOffset(extraOffset)
+ BaseIndex.new(codeOrigin, @base, @index, @scale, Immediate.new(codeOrigin, @offset.value + extraOffset))
+ end
+
def children
[@base, @index, @offset]
end
@@ -764,6 +772,10 @@ class AbsoluteAddress < NoChildren
@address = address
end
+ def withOffset(extraOffset)
+ AbsoluteAddress.new(codeOrigin, Immediate.new(codeOrigin, @address.value + extraOffset))
+ end
+
def dump
"#{address.dump}[]"
end
diff --git a/Source/JavaScriptCore/offlineasm/backends.rb b/Source/JavaScriptCore/offlineasm/backends.rb
index ef9358c0b..902a764af 100644
--- a/Source/JavaScriptCore/offlineasm/backends.rb
+++ b/Source/JavaScriptCore/offlineasm/backends.rb
@@ -22,18 +22,22 @@
# THE POSSIBILITY OF SUCH DAMAGE.
require "config"
-require "armv7"
+require "arm"
require "ast"
require "x86"
require "mips"
+require "sh4"
require "cloop"
BACKENDS =
[
"X86",
"X86_64",
+ "ARM",
"ARMv7",
+ "ARMv7_TRADITIONAL",
"MIPS",
+ "SH4",
"C_LOOP"
]
@@ -46,8 +50,11 @@ WORKING_BACKENDS =
[
"X86",
"X86_64",
+ "ARM",
"ARMv7",
+ "ARMv7_TRADITIONAL",
"MIPS",
+ "SH4",
"C_LOOP"
]
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index 8d0838ebd..6f35b2ffd 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -55,7 +55,7 @@ end
class SpecialRegister < NoChildren
- def dump
+ def clDump
@name
end
def clValue(type=:int)
@@ -63,10 +63,10 @@ class SpecialRegister < NoChildren
end
end
-C_LOOP_SCRATCH_FPR = SpecialRegister.new("d8")
+C_LOOP_SCRATCH_FPR = SpecialRegister.new("d6")
class RegisterID
- def dump
+ def clDump
case name
when "t0"
"t0"
@@ -95,12 +95,12 @@ class RegisterID
end
end
def clValue(type=:int)
- dump + cloopMapType(type)
+ clDump + cloopMapType(type)
end
end
class FPRegisterID
- def dump
+ def clDump
case name
when "ft0", "fr"
"d0"
@@ -119,12 +119,12 @@ class FPRegisterID
end
end
def clValue(type=:int)
- dump + cloopMapType(type)
+ clDump + cloopMapType(type)
end
end
class Immediate
- def dump
+ def clDump
"#{value}"
end
def clValue(type=:int)
@@ -156,8 +156,8 @@ class Immediate
end
class Address
- def dump
- "[#{base.dump}, #{offset.value}]"
+ def clDump
+ "[#{base.clDump}, #{offset.value}]"
end
def clValue(type=:int)
case type
@@ -178,7 +178,7 @@ class Address
def pointerExpr
if base.is_a? RegisterID and base.name == "sp"
offsetValue = "#{offset.value}"
- "(ASSERT(#{offsetValue} == offsetof(JITStackFrame, globalData)), &sp->globalData)"
+ "(ASSERT(#{offsetValue} == offsetof(JITStackFrame, vm)), &sp->vm)"
elsif offset.value == 0
"#{base.clValue(:int8Ptr)}"
elsif offset.value > 0
@@ -229,8 +229,8 @@ class Address
end
class BaseIndex
- def dump
- "[#{base.dump}, #{offset.dump}, #{index.dump} << #{scaleShift}]"
+ def clDump
+ "[#{base.clDump}, #{offset.clDump}, #{index.clDump} << #{scaleShift}]"
end
def clValue(type=:int)
case type
@@ -250,7 +250,7 @@ class BaseIndex
def pointerExpr
if base.is_a? RegisterID and base.name == "sp"
offsetValue = "(#{index.clValue} << #{scaleShift}) + #{offset.clValue})"
- "(ASSERT(#{offsetValue} == offsetof(JITStackFrame, globalData)), &sp->globalData)"
+ "(ASSERT(#{offsetValue} == offsetof(JITStackFrame, vm)), &sp->vm)"
else
"#{base.clValue(:int8Ptr)} + (#{index.clValue} << #{scaleShift}) + #{offset.clValue}"
end
@@ -294,11 +294,11 @@ class BaseIndex
end
class AbsoluteAddress
- def dump
+ def clDump
"#{codeOriginString}"
end
def clValue
- dump
+ clDump
end
end
@@ -348,7 +348,7 @@ class Sequence
end
def clOperands(operands)
- operands.map{|v| v.dump}.join(", ")
+ operands.map{|v| v.clDump}.join(", ")
end
@@ -358,14 +358,14 @@ def cloopEmitOperation(operands, type, operator)
if operands.size == 3
$asm.putc "#{operands[2].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};"
if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32)
- $asm.putc "#{operands[2].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
+ $asm.putc "#{operands[2].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
end
else
raise unless operands.size == 2
raise unless not operands[1].is_a? Immediate
$asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};"
if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32)
- $asm.putc "#{operands[1].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
+ $asm.putc "#{operands[1].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
end
end
end
@@ -375,14 +375,14 @@ def cloopEmitShiftOperation(operands, type, operator)
if operands.size == 3
$asm.putc "#{operands[2].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);"
if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32)
- $asm.putc "#{operands[2].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
+ $asm.putc "#{operands[2].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
end
else
raise unless operands.size == 2
raise unless not operands[1].is_a? Immediate
$asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);"
if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32)
- $asm.putc "#{operands[1].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
+ $asm.putc "#{operands[1].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
end
end
end
@@ -393,12 +393,12 @@ def cloopEmitUnaryOperation(operands, type, operator)
raise unless not operands[0].is_a? Immediate
$asm.putc "#{operands[0].clValue(type)} = #{operator}#{operands[0].clValue(type)};"
if operands[0].is_a? RegisterID and (type == :int32 or type == :uint32)
- $asm.putc "#{operands[0].dump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
+ $asm.putc "#{operands[0].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
end
end
def cloopEmitCompareDoubleWithNaNCheckAndBranch(operands, condition)
- $asm.putc "if (isnan(#{operands[0].clValue(:double)}) || isnan(#{operands[1].clValue(:double)})"
+ $asm.putc "if (std::isnan(#{operands[0].clValue(:double)}) || isnan(#{operands[1].clValue(:double)})"
$asm.putc " || (#{operands[0].clValue(:double)} #{condition} #{operands[1].clValue(:double)}))"
$asm.putc " goto #{operands[2].cLabel};"
end
@@ -465,9 +465,9 @@ def cloopEmitOpAndBranch(operands, operator, type, conditionTest)
$asm.putc "{"
$asm.putc " #{tempType} temp = #{op2} #{operator} #{op1};"
+ $asm.putc " #{op2} = temp;"
$asm.putc " if (temp #{conditionTest})"
$asm.putc " goto #{operands[2].cLabel};"
- $asm.putc " #{op2} = temp;"
$asm.putc "}"
end
@@ -533,10 +533,10 @@ def cloopEmitOpAndBranchIfOverflow(operands, operator, type)
raise "Unimplemented opeartor"
end
- $asm.putc " if #{overflowTest} {"
- $asm.putc " goto #{operands[2].cLabel};"
- $asm.putc " }"
+ $asm.putc " bool didOverflow = #{overflowTest};"
$asm.putc " #{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};"
+ $asm.putc " if (didOverflow)"
+ $asm.putc " goto #{operands[2].cLabel};"
$asm.putc "}"
end
@@ -703,16 +703,16 @@ class Instruction
when "td2i"
$asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:double)};"
- $asm.putc "#{operands[1].dump}.clearHighWord();"
+ $asm.putc "#{operands[1].clDump}.clearHighWord();"
when "bcd2i" # operands: srcDbl dstInt slowPath
$asm.putc "{"
$asm.putc " double d = #{operands[0].clValue(:double)};"
$asm.putc " const int32_t asInt32 = int32_t(d);"
- $asm.putc " if (asInt32 != d || (!asInt32 && signbit(d))) // true for -0.0"
+ $asm.putc " if (asInt32 != d || (!asInt32 && std::signbit(d))) // true for -0.0"
$asm.putc " goto #{operands[2].cLabel};"
$asm.putc " #{operands[1].clValue} = asInt32;"
- $asm.putc " #{operands[1].dump}.clearHighWord();"
+ $asm.putc " #{operands[1].clDump}.clearHighWord();"
$asm.putc "}"
when "move"
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index 4e70625c2..eb394afab 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -257,7 +257,7 @@ X86_INSTRUCTIONS =
"idivi"
]
-ARMv7_INSTRUCTIONS =
+ARM_INSTRUCTIONS =
[
"smulli",
"addis",
@@ -275,6 +275,21 @@ MIPS_INSTRUCTIONS =
"pichdrra"
]
+SH4_INSTRUCTIONS =
+ [
+ "shllx",
+ "shlrx",
+ "shld",
+ "shad",
+ "bdnan",
+ "loaddReversedAndIncrementAddress",
+ "storedReversedAndDecrementAddress",
+ "ldspr",
+ "stspr",
+ "callf",
+ "jmpf"
+ ]
+
CXX_INSTRUCTIONS =
[
"cloopCrash", # no operands
@@ -291,7 +306,7 @@ CXX_INSTRUCTIONS =
"cloopDo", # no operands
]
-INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARMv7_INSTRUCTIONS + MIPS_INSTRUCTIONS + CXX_INSTRUCTIONS
+INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
diff --git a/Source/JavaScriptCore/offlineasm/mips.rb b/Source/JavaScriptCore/offlineasm/mips.rb
index c6daa3c7d..3ec7022ee 100644
--- a/Source/JavaScriptCore/offlineasm/mips.rb
+++ b/Source/JavaScriptCore/offlineasm/mips.rb
@@ -566,7 +566,7 @@ class Sequence
end
}
result = riscLowerMalformedAddressesDouble(result)
- result = riscLowerMisplacedImmediates(result)
+ result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep"])
result = mipsLowerMisplacedImmediates(result)
result = riscLowerMalformedImmediates(result, -0xffff..0xffff)
result = mipsLowerMisplacedAddresses(result)
diff --git a/Source/JavaScriptCore/offlineasm/parser.rb b/Source/JavaScriptCore/offlineasm/parser.rb
index 76eea522f..3b9c67bed 100644
--- a/Source/JavaScriptCore/offlineasm/parser.rb
+++ b/Source/JavaScriptCore/offlineasm/parser.rb
@@ -114,7 +114,7 @@ def lex(str, fileName)
end
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
lineNumber += 1
- when /\A[a-zA-Z]([a-zA-Z0-9_]*)/
+ when /\A[a-zA-Z]([a-zA-Z0-9_.]*)/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A\.([a-zA-Z0-9_]*)/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
@@ -163,7 +163,7 @@ def isKeyword(token)
end
def isIdentifier(token)
- token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
+ token =~ /\A[a-zA-Z]([a-zA-Z0-9_.]*)\Z/ and not isKeyword(token)
end
def isLabel(token)
@@ -223,8 +223,9 @@ class Parser
def parsePredicateAtom
if @tokens[@idx] == "not"
+ codeOrigin = @tokens[@idx].codeOrigin
@idx += 1
- parsePredicateAtom
+ Not.new(codeOrigin, parsePredicateAtom)
elsif @tokens[@idx] == "("
@idx += 1
skipNewLine
diff --git a/Source/JavaScriptCore/offlineasm/risc.rb b/Source/JavaScriptCore/offlineasm/risc.rb
index 7408253af..1696a0c5c 100644
--- a/Source/JavaScriptCore/offlineasm/risc.rb
+++ b/Source/JavaScriptCore/offlineasm/risc.rb
@@ -172,7 +172,7 @@ end
# end
# }
#
-# See armv7.rb for a different example, in which we lower all BaseIndex addresses
+# See arm.rb for a different example, in which we lower all BaseIndex addresses
# that have non-zero offset, all Address addresses that have large offsets, and
# all other addresses (like AbsoluteAddress).
#
@@ -272,7 +272,7 @@ def riscLowerMalformedAddressesDouble(list)
end
#
-# Lowering of misplaced immediates. For example:
+# Lowering of misplaced immediates for opcodes in opcodeList. For example, if storei is in opcodeList:
#
# storei 0, [foo]
#
@@ -282,13 +282,12 @@ end
# storei tmp, [foo]
#
-def riscLowerMisplacedImmediates(list)
+def riscLowerMisplacedImmediates(list, opcodeList)
newList = []
list.each {
| node |
if node.is_a? Instruction
- case node.opcode
- when "storeb", "storei", "storep"
+ if opcodeList.include? node.opcode
operands = node.operands
newOperands = []
operands.each {
diff --git a/Source/JavaScriptCore/offlineasm/sh4.rb b/Source/JavaScriptCore/offlineasm/sh4.rb
new file mode 100644
index 000000000..57223c826
--- /dev/null
+++ b/Source/JavaScriptCore/offlineasm/sh4.rb
@@ -0,0 +1,778 @@
+# Copyright (C) 2013 Apple Inc. All rights reserved.
+# Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS, INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CISCO SYSTEMS, INC. OR ITS
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+require 'risc'
+
+class Node
+ def sh4SingleHi
+ doubleOperand = sh4Operand
+ raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^dr/
+ "fr" + ($~.post_match.to_i).to_s
+ end
+ def sh4SingleLo
+ doubleOperand = sh4Operand
+ raise "Bogus register name #{doubleOperand}" unless doubleOperand =~ /^dr/
+ "fr" + ($~.post_match.to_i + 1).to_s
+ end
+end
+
+class SpecialRegister < NoChildren
+ def sh4Operand
+ @name
+ end
+
+ def dump
+ @name
+ end
+
+ def register?
+ true
+ end
+end
+
+SH4_TMP_GPRS = [ SpecialRegister.new("r3"), SpecialRegister.new("r11"), SpecialRegister.new("r13") ]
+SH4_TMP_FPRS = [ SpecialRegister.new("dr10") ]
+
+class RegisterID
+ def sh4Operand
+ case name
+ when "a0"
+ "r4"
+ when "a1"
+ "r5"
+ when "t0"
+ "r0"
+ when "t1"
+ "r1"
+ when "t2"
+ "r2"
+ when "t3"
+ "r10"
+ when "t4"
+ "r6"
+ when "cfr"
+ "r14"
+ when "sp"
+ "r15"
+ when "lr"
+ "pr"
+ else
+ raise "Bad register #{name} for SH4 at #{codeOriginString}"
+ end
+ end
+end
+
+class FPRegisterID
+ def sh4Operand
+ case name
+ when "ft0", "fr"
+ "dr0"
+ when "ft1"
+ "dr2"
+ when "ft2"
+ "dr4"
+ when "ft3"
+ "dr6"
+ when "ft4"
+ "dr8"
+ when "fa0"
+ "dr12"
+ else
+ raise "Bad register #{name} for SH4 at #{codeOriginString}"
+ end
+ end
+end
+
+class Immediate
+ def sh4Operand
+ raise "Invalid immediate #{value} at #{codeOriginString}" if value < -128 or value > 127
+ "##{value}"
+ end
+end
+
+class Address
+ def sh4Operand
+ raise "Bad offset #{offset.value} at #{codeOriginString}" if offset.value < 0 or offset.value > 60
+ if offset.value == 0
+ "@#{base.sh4Operand}"
+ else
+ "@(#{offset.value}, #{base.sh4Operand})"
+ end
+ end
+
+ def sh4OperandPostInc
+ raise "Bad offset #{offset.value} for post inc at #{codeOriginString}" unless offset.value == 0
+ "@#{base.sh4Operand}+"
+ end
+
+ def sh4OperandPreDec
+ raise "Bad offset #{offset.value} for pre dec at #{codeOriginString}" unless offset.value == 0
+ "@-#{base.sh4Operand}"
+ end
+end
+
+class BaseIndex
+ def sh4Operand
+ raise "Unconverted base index at #{codeOriginString}"
+ end
+end
+
+class AbsoluteAddress
+ def sh4Operand
+ raise "Unconverted absolute address at #{codeOriginString}"
+ end
+end
+
+
+#
+# Lowering of shift ops for SH4. For example:
+#
+# rshifti foo, bar
+#
+# becomes:
+#
+# negi foo, tmp
+# shad tmp, bar
+#
+
+def sh4LowerShiftOps(list)
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ case node.opcode
+ when "ulshifti", "ulshiftp", "urshifti", "urshiftp", "lshifti", "lshiftp", "rshifti", "rshiftp"
+ if node.opcode[0, 1] == "u"
+ type = "l"
+ direction = node.opcode[1, 1]
+ else
+ type = "a"
+ direction = node.opcode[0, 1]
+ end
+ if node.operands[0].is_a? Immediate
+ maskedImm = Immediate.new(node.operands[0].codeOrigin, node.operands[0].value & 31)
+ if maskedImm.value == 0
+ # There is nothing to do here.
+ elsif maskedImm.value == 1 or (type == "l" and [2, 8, 16].include? maskedImm.value)
+ newList << Instruction.new(node.codeOrigin, "sh#{type}#{direction}x", [maskedImm, node.operands[1]])
+ else
+ tmp = Tmp.new(node.codeOrigin, :gpr)
+ if direction == "l"
+ newList << Instruction.new(node.codeOrigin, "move", [maskedImm, tmp])
+ else
+ newList << Instruction.new(node.codeOrigin, "move", [Immediate.new(node.operands[0].codeOrigin, -1 * maskedImm.value), tmp])
+ end
+ newList << Instruction.new(node.codeOrigin, "sh#{type}d", [tmp, node.operands[1]])
+ end
+ else
+ tmp = Tmp.new(node.codeOrigin, :gpr)
+ newList << Instruction.new(node.codeOrigin, "move", [Immediate.new(node.operands[0].codeOrigin, 31), tmp])
+ newList << Instruction.new(node.codeOrigin, "andi", [node.operands[0], tmp])
+ if direction == "r"
+ newList << Instruction.new(node.codeOrigin, "negi", [tmp, tmp])
+ end
+ newList << Instruction.new(node.codeOrigin, "sh#{type}d", [tmp, node.operands[1]])
+ end
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ }
+ newList
+end
+
+
+#
+# Lowering of simple branch ops for SH4. For example:
+#
+# baddis foo, bar, baz
+#
+# will become:
+#
+# addi foo, bar
+# bs bar, baz
+#
+
+def sh4LowerSimpleBranchOps(list)
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ annotation = node.annotation
+ case node.opcode
+ when /^b(addi|subi|ori|addp)/
+ op = $1
+ bc = $~.post_match
+
+ case op
+ when "addi", "addp"
+ op = "addi"
+ when "subi", "subp"
+ op = "subi"
+ when "ori", "orp"
+ op = "ori"
+ end
+
+ if bc == "s"
+ raise "Invalid operands number (#{node.operands.size})" unless node.operands.size == 3
+ if node.operands[1].is_a? RegisterID or node.operands[1].is_a? SpecialRegister
+ newList << Instruction.new(node.codeOrigin, op, node.operands[0..1])
+ newList << Instruction.new(node.codeOrigin, "bs", node.operands[1..2])
+ else
+ tmpVal = Tmp.new(node.codeOrigin, :gpr)
+ tmpPtr = Tmp.new(node.codeOrigin, :gpr)
+ addr = Address.new(node.codeOrigin, tmpPtr, Immediate.new(node.codeOrigin, 0))
+ newList << Instruction.new(node.codeOrigin, "leap", [node.operands[1], tmpPtr])
+ newList << Instruction.new(node.codeOrigin, "loadi", [addr, tmpVal])
+ newList << Instruction.new(node.codeOrigin, op, [node.operands[0], tmpVal])
+ newList << Instruction.new(node.codeOrigin, "storei", [tmpVal, addr])
+ newList << Instruction.new(node.codeOrigin, "bs", [tmpVal, node.operands[2]])
+ end
+ elsif bc == "nz"
+ raise "Invalid operands number (#{node.operands.size})" unless node.operands.size == 3
+ newList << Instruction.new(node.codeOrigin, op, node.operands[0..1])
+ newList << Instruction.new(node.codeOrigin, "btinz", node.operands[1..2])
+ else
+ newList << node
+ end
+ when "bmulio", "bmulpo"
+ raise "Invalid operands number (#{node.operands.size})" unless node.operands.size == 3
+ tmp1 = Tmp.new(node.codeOrigin, :gpr)
+ tmp2 = Tmp.new(node.codeOrigin, :gpr)
+ newList << Instruction.new(node.codeOrigin, node.opcode, [tmp1, tmp2].concat(node.operands))
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ }
+ newList
+end
+
+
+#
+# Lowering of double accesses for SH4. For example:
+#
+# loadd [foo, bar, 8], baz
+#
+# becomes:
+#
+# leap [foo, bar, 8], tmp
+# loaddReversedAndIncrementAddress [tmp], baz
+#
+
+def sh4LowerDoubleAccesses(list)
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ case node.opcode
+ when "loadd"
+ tmp = Tmp.new(codeOrigin, :gpr)
+ addr = Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
+ newList << Instruction.new(codeOrigin, "leap", [node.operands[0], tmp])
+ newList << Instruction.new(node.codeOrigin, "loaddReversedAndIncrementAddress", [addr, node.operands[1]], node.annotation)
+ when "stored"
+ tmp = Tmp.new(codeOrigin, :gpr)
+ addr = Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))
+ newList << Instruction.new(codeOrigin, "leap", [node.operands[1].withOffset(8), tmp])
+ newList << Instruction.new(node.codeOrigin, "storedReversedAndDecrementAddress", [node.operands[0], addr], node.annotation)
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ }
+ newList
+end
+
+
+#
+# Lowering of double specials for SH4.
+#
+
+def sh4LowerDoubleSpecials(list)
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ case node.opcode
+ when "bdltun", "bdgtun"
+ # Handle specific floating point unordered opcodes.
+ newList << Instruction.new(codeOrigin, "bdnan", [node.operands[0], node.operands[2]])
+ newList << Instruction.new(codeOrigin, "bdnan", [node.operands[1], node.operands[2]])
+ newList << Instruction.new(codeOrigin, node.opcode[0..-3], node.operands)
+ when "bdnequn", "bdgtequn", "bdltequn"
+ newList << Instruction.new(codeOrigin, node.opcode[0..-3], node.operands)
+ when "bdneq", "bdgteq", "bdlteq"
+ # Handle specific floating point ordered opcodes.
+ outlabel = LocalLabel.unique("out_#{node.opcode}")
+ outref = LocalLabelReference.new(codeOrigin, outlabel)
+ newList << Instruction.new(codeOrigin, "bdnan", [node.operands[0], outref])
+ newList << Instruction.new(codeOrigin, "bdnan", [node.operands[1], outref])
+ newList << Instruction.new(codeOrigin, node.opcode, node.operands)
+ newList << outlabel
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ }
+ newList
+end
+
+
+#
+# Lowering of misplaced labels for SH4.
+#
+
+def sh4LowerMisplacedLabels(list)
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ case node.opcode
+ when "jmp"
+ if node.operands[0].is_a? LabelReference
+ tmp = Tmp.new(codeOrigin, :gpr)
+ newList << Instruction.new(codeOrigin, "jmpf", [tmp, node.operands[0]])
+ else
+ newList << node
+ end
+ when "call"
+ if node.operands[0].is_a? LabelReference
+ tmp1 = Tmp.new(codeOrigin, :gpr)
+ tmp2 = Tmp.new(codeOrigin, :gpr)
+ newList << Instruction.new(codeOrigin, "callf", [tmp1, tmp2, node.operands[0]])
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ }
+ newList
+end
+
+
+class Sequence
+ def getModifiedListSH4
+ result = @list
+
+ # Verify that we will only see instructions and labels.
+ result.each {
+ | node |
+ unless node.is_a? Instruction or
+ node.is_a? Label or
+ node.is_a? LocalLabel or
+ node.is_a? Skip
+ raise "Unexpected #{node.inspect} at #{node.codeOrigin}"
+ end
+ }
+
+ result = sh4LowerShiftOps(result)
+ result = sh4LowerSimpleBranchOps(result)
+ result = riscLowerMalformedAddresses(result) {
+ | node, address |
+ if address.is_a? Address
+ case node.opcode
+ when "btbz", "btbnz", "cbeq", "bbeq", "bbneq", "bbb", "loadb", "storeb"
+ (0..15).include? address.offset.value and
+ ((node.operands[0].is_a? RegisterID and node.operands[0].sh4Operand == "r0") or
+ (node.operands[1].is_a? RegisterID and node.operands[1].sh4Operand == "r0"))
+ when "loadh"
+ (0..30).include? address.offset.value and
+ ((node.operands[0].is_a? RegisterID and node.operands[0].sh4Operand == "r0") or
+ (node.operands[1].is_a? RegisterID and node.operands[1].sh4Operand == "r0"))
+ else
+ (0..60).include? address.offset.value
+ end
+ else
+ false
+ end
+ }
+ result = sh4LowerDoubleAccesses(result)
+ result = sh4LowerDoubleSpecials(result)
+ result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep", "muli", "mulp", "andi", "ori", "xori",
+ "cbeq", "cieq", "cpeq", "cineq", "cpneq", "cib", "baddio", "bsubio", "bmulio", "baddis",
+ "bbeq", "bbneq", "bbb", "bieq", "bpeq", "bineq", "bpneq", "bia", "bpa", "biaeq", "bpaeq", "bib", "bpb",
+ "bigteq", "bpgteq", "bilt", "bplt", "bigt", "bpgt", "bilteq", "bplteq", "btiz", "btpz", "btinz", "btpnz", "btbz", "btbnz"])
+ result = riscLowerMalformedImmediates(result, -128..127)
+ result = sh4LowerMisplacedLabels(result)
+ result = riscLowerMisplacedAddresses(result)
+
+ result = assignRegistersToTemporaries(result, :gpr, SH4_TMP_GPRS)
+ result = assignRegistersToTemporaries(result, :gpr, SH4_TMP_FPRS)
+
+ return result
+ end
+end
+
+def sh4Operands(operands)
+ operands.map{|v| v.sh4Operand}.join(", ")
+end
+
+def emitSH4Load32AndJump(constant, scratch)
+ $asm.puts "mov.l 2f, #{scratch.sh4Operand}"
+ $asm.puts "braf #{scratch.sh4Operand}"
+ $asm.puts "nop"
+ $asm.puts "1: .balign 4"
+ $asm.puts "2: .long #{constant}-1b"
+end
+
+def emitSH4LoadImm(operands)
+ if operands[0].value == 0x40000000
+ # FirstConstantRegisterIndex const is often used (0x40000000).
+ # It's more efficient to "build" the value with 3 opcodes without branch.
+ $asm.puts "mov #64, #{operands[1].sh4Operand}"
+ $asm.puts "shll16 #{operands[1].sh4Operand}"
+ $asm.puts "shll8 #{operands[1].sh4Operand}"
+ elsif (-128..127).include? operands[0].value
+ $asm.puts "mov #{sh4Operands(operands)}"
+ elsif (-32768..32767).include? operands[0].value
+ constlabel = LocalLabel.unique("loadconstant")
+ $asm.puts "mov.w @(6, PC), #{operands[1].sh4Operand}"
+ $asm.puts "bra #{LocalLabelReference.new(codeOrigin, constlabel).asmLabel}"
+ $asm.puts "nop"
+ $asm.puts ".word #{operands[0].value}"
+ constlabel.lower("SH4")
+ else
+ outlabel = LocalLabel.unique("load32out")
+ constlabel = LocalLabel.unique("load32const")
+ $asm.puts "mov.l #{LocalLabelReference.new(codeOrigin, constlabel).asmLabel}, #{operands[1].sh4Operand}"
+ $asm.puts "bra #{LocalLabelReference.new(codeOrigin, outlabel).asmLabel}"
+ $asm.puts "nop"
+ $asm.puts ".balign 4"
+ constlabel.lower("SH4")
+ $asm.puts ".long #{operands[0].value}"
+ outlabel.lower("SH4")
+ end
+end
+
+def emitSH4Branch(sh4opcode, operand)
+ $asm.puts "#{sh4opcode} @#{operand.sh4Operand}"
+ $asm.puts "nop"
+end
+
+def emitSH4ShiftImm(val, operand, direction)
+ tmp = val
+ while tmp > 0
+ if tmp >= 16
+ $asm.puts "shl#{direction}16 #{operand.sh4Operand}"
+ tmp -= 16
+ elsif tmp >= 8
+ $asm.puts "shl#{direction}8 #{operand.sh4Operand}"
+ tmp -= 8
+ elsif tmp >= 2
+ $asm.puts "shl#{direction}2 #{operand.sh4Operand}"
+ tmp -= 2
+ else
+ $asm.puts "shl#{direction} #{operand.sh4Operand}"
+ tmp -= 1
+ end
+ end
+end
+
+def emitSH4BranchIfT(label, neg)
+ outlabel = LocalLabel.unique("branchIfT")
+ sh4opcode = neg ? "bt" : "bf"
+ $asm.puts "#{sh4opcode} #{LocalLabelReference.new(codeOrigin, outlabel).asmLabel}"
+ if label.is_a? LocalLabelReference
+ $asm.puts "bra #{label.asmLabel}"
+ $asm.puts "nop"
+ else
+ emitSH4Load32AndJump(label.asmLabel, SH4_TMP_GPRS[0])
+ end
+ outlabel.lower("SH4")
+end
+
+def emitSH4IntCompare(cmpOpcode, operands)
+ $asm.puts "cmp/#{cmpOpcode} #{sh4Operands([operands[1], operands[0]])}"
+end
+
+def emitSH4CondBranch(cmpOpcode, neg, operands)
+ emitSH4IntCompare(cmpOpcode, operands)
+ emitSH4BranchIfT(operands[2], neg)
+end
+
+def emitSH4CompareSet(cmpOpcode, neg, operands)
+ emitSH4IntCompare(cmpOpcode, operands)
+ if !neg
+ $asm.puts "movt #{operands[2].sh4Operand}"
+ else
+ outlabel = LocalLabel.unique("compareSet")
+ $asm.puts "mov #0, #{operands[2].sh4Operand}"
+ $asm.puts "bt #{LocalLabelReference.new(codeOrigin, outlabel).asmLabel}"
+ $asm.puts "mov #1, #{operands[2].sh4Operand}"
+ outlabel.lower("SH4")
+ end
+end
+
+def emitSH4BranchIfNaN(operands)
+ raise "Invalid operands number (#{operands.size})" unless operands.size == 2
+ $asm.puts "fcmp/eq #{sh4Operands([operands[0], operands[0]])}"
+ $asm.puts "bf #{operands[1].asmLabel}"
+end
+
+def emitSH4DoubleCondBranch(cmpOpcode, neg, operands)
+ if cmpOpcode == "lt"
+ $asm.puts "fcmp/gt #{sh4Operands([operands[0], operands[1]])}"
+ else
+ $asm.puts "fcmp/#{cmpOpcode} #{sh4Operands([operands[1], operands[0]])}"
+ end
+ emitSH4BranchIfT(operands[2], neg)
+end
+
+class Instruction
+ def lowerSH4
+ $asm.comment codeOriginString
+ case opcode
+ when "addi", "addp"
+ if operands.size == 3
+ if operands[0].sh4Operand == operands[2].sh4Operand
+ $asm.puts "add #{sh4Operands([operands[1], operands[2]])}"
+ elsif operands[1].sh4Operand == operands[2].sh4Operand
+ $asm.puts "add #{sh4Operands([operands[0], operands[2]])}"
+ else
+ $asm.puts "mov #{sh4Operands([operands[0], operands[2]])}"
+ $asm.puts "add #{sh4Operands([operands[1], operands[2]])}"
+ end
+ else
+ $asm.puts "add #{sh4Operands(operands)}"
+ end
+ when "subi", "subp"
+ raise "#{opcode} with #{operands.size} operands is not handled yet" unless operands.size == 2
+ if operands[0].is_a? Immediate
+ $asm.puts "add #{sh4Operands([Immediate.new(codeOrigin, -1 * operands[0].value), operands[1]])}"
+ else
+ $asm.puts "sub #{sh4Operands(operands)}"
+ end
+ when "muli", "mulp"
+ $asm.puts "mul.l #{sh4Operands(operands[0..1])}"
+ $asm.puts "sts macl, #{operands[-1].sh4Operand}"
+ when "negi", "negp"
+ if operands.size == 2
+ $asm.puts "neg #{sh4Operands(operands)}"
+ else
+ $asm.puts "neg #{sh4Operands([operands[0], operands[0]])}"
+ end
+ when "andi", "andp", "ori", "orp", "xori", "xorp"
+ raise "#{opcode} with #{operands.size} operands is not handled yet" unless operands.size == 2
+ sh4opcode = opcode[0..-2]
+ $asm.puts "#{sh4opcode} #{sh4Operands(operands)}"
+ when "shllx", "shlrx"
+ raise "Unhandled parameters for opcode #{opcode}" unless operands[0].is_a? Immediate
+ if operands[0].value == 1
+ $asm.puts "shl#{opcode[3, 1]} #{operands[1].sh4Operand}"
+ else
+ $asm.puts "shl#{opcode[3, 1]}#{operands[0].value} #{operands[1].sh4Operand}"
+ end
+ when "shld", "shad"
+ $asm.puts "#{opcode} #{sh4Operands(operands)}"
+ when "loaddReversedAndIncrementAddress"
+ # As we are little endian, we don't use "fmov @Rm, DRn" here.
+ $asm.puts "fmov.s #{operands[0].sh4OperandPostInc}, #{operands[1].sh4SingleLo}"
+ $asm.puts "fmov.s #{operands[0].sh4OperandPostInc}, #{operands[1].sh4SingleHi}"
+ when "storedReversedAndDecrementAddress"
+ # As we are little endian, we don't use "fmov DRm, @Rn" here.
+ $asm.puts "fmov.s #{operands[0].sh4SingleHi}, #{operands[1].sh4OperandPreDec}"
+ $asm.puts "fmov.s #{operands[0].sh4SingleLo}, #{operands[1].sh4OperandPreDec}"
+ when "ci2d"
+ $asm.puts "lds #{operands[0].sh4Operand}, fpul"
+ $asm.puts "float fpul, #{operands[1].sh4Operand}"
+ when "fii2d"
+ $asm.puts "lds #{operands[0].sh4Operand}, fpul"
+ $asm.puts "fsts fpul, #{operands[2].sh4SingleLo}"
+ $asm.puts "lds #{operands[1].sh4Operand}, fpul"
+ $asm.puts "fsts fpul, #{operands[2].sh4SingleHi}"
+ when "fd2ii"
+ $asm.puts "flds #{operands[0].sh4SingleLo}, fpul"
+ $asm.puts "sts fpul, #{operands[1].sh4Operand}"
+ $asm.puts "flds #{operands[0].sh4SingleHi}, fpul"
+ $asm.puts "sts fpul, #{operands[2].sh4Operand}"
+ when "addd", "subd", "muld", "divd"
+ sh4opcode = opcode[0..-2]
+ $asm.puts "f#{sh4opcode} #{sh4Operands(operands)}"
+ when "bcd2i"
+ $asm.puts "ftrc #{operands[0].sh4Operand}, fpul"
+ $asm.puts "sts fpul, #{operands[1].sh4Operand}"
+ $asm.puts "float fpul, #{SH4_TMP_FPRS[0].sh4Operand}"
+ $asm.puts "fcmp/eq #{sh4Operands([operands[0], SH4_TMP_FPRS[0]])}"
+ $asm.puts "bf #{operands[2].asmLabel}"
+ $asm.puts "tst #{sh4Operands([operands[1], operands[1]])}"
+ $asm.puts "bt #{operands[2].asmLabel}"
+ when "bdnan"
+ emitSH4BranchIfNaN(operands)
+ when "bdneq"
+ emitSH4DoubleCondBranch("eq", true, operands)
+ when "bdgteq"
+ emitSH4DoubleCondBranch("lt", true, operands)
+ when "bdlt"
+ emitSH4DoubleCondBranch("lt", false, operands)
+ when "bdlteq"
+ emitSH4DoubleCondBranch("gt", true, operands)
+ when "bdgt"
+ emitSH4DoubleCondBranch("gt", false, operands)
+ when "baddio", "baddpo", "bsubio", "bsubpo"
+ raise "#{opcode} with #{operands.size} operands is not handled yet" unless operands.size == 3
+ $asm.puts "#{opcode[1, 3]}v #{sh4Operands([operands[0], operands[1]])}"
+ $asm.puts "bt #{operands[2].asmLabel}"
+ when "bmulio", "bmulpo"
+ raise "Invalid operands number (#{operands.size})" unless operands.size == 5
+ $asm.puts "dmuls.l #{sh4Operands([operands[2], operands[3]])}"
+ $asm.puts "sts macl, #{operands[3].sh4Operand}"
+ $asm.puts "cmp/pz #{operands[3].sh4Operand}"
+ $asm.puts "movt #{operands[1].sh4Operand}"
+ $asm.puts "add #-1, #{operands[1].sh4Operand}"
+ $asm.puts "sts mach, #{operands[0].sh4Operand}"
+ $asm.puts "cmp/eq #{sh4Operands([operands[0], operands[1]])}"
+ $asm.puts "bf #{operands[4].asmLabel}"
+ when "btiz", "btpz", "btbz", "btinz", "btpnz", "btbnz"
+ if operands.size == 3
+ $asm.puts "tst #{sh4Operands([operands[0], operands[1]])}"
+ else
+ if operands[0].sh4Operand == "r0"
+ $asm.puts "cmp/eq #0, r0"
+ else
+ $asm.puts "tst #{sh4Operands([operands[0], operands[0]])}"
+ end
+ end
+ emitSH4BranchIfT(operands[-1], (opcode[-2, 2] == "nz"))
+ when "cieq", "cpeq", "cbeq"
+ emitSH4CompareSet("eq", false, operands)
+ when "cineq", "cpneq", "cbneq"
+ emitSH4CompareSet("eq", true, operands)
+ when "cib", "cpb", "cbb"
+ emitSH4CompareSet("hs", true, operands)
+ when "bieq", "bpeq", "bbeq"
+ emitSH4CondBranch("eq", false, operands)
+ when "bineq", "bpneq", "bbneq"
+ emitSH4CondBranch("eq", true, operands)
+ when "bib", "bpb", "bbb"
+ emitSH4CondBranch("hs", true, operands)
+ when "bia", "bpa", "bba"
+ emitSH4CondBranch("hi", false, operands)
+ when "biaeq", "bpaeq"
+ emitSH4CondBranch("hs", false, operands)
+ when "bigteq", "bpgteq", "bbgteq"
+ emitSH4CondBranch("ge", false, operands)
+ when "bilt", "bplt", "bblt"
+ emitSH4CondBranch("ge", true, operands)
+ when "bigt", "bpgt", "bbgt"
+ emitSH4CondBranch("gt", false, operands)
+ when "bilteq", "bplteq", "bblteq"
+ emitSH4CondBranch("gt", true, operands)
+ when "bs"
+ $asm.puts "cmp/pz #{operands[0].sh4Operand}"
+ $asm.puts "bf #{operands[1].asmLabel}"
+ when "call"
+ if operands[0].is_a? LocalLabelReference
+ $asm.puts "bsr #{operands[0].asmLabel}"
+ $asm.puts "nop"
+ elsif operands[0].is_a? RegisterID or operands[0].is_a? SpecialRegister
+ emitSH4Branch("jsr", operands[0])
+ else
+ raise "Unhandled parameters for opcode #{opcode} at #{codeOriginString}"
+ end
+ when "callf"
+ $asm.puts ".balign 4"
+ $asm.puts "mov r0, #{operands[0].sh4Operand}"
+ $asm.puts "mova @(14, PC), r0"
+ $asm.puts "lds r0, pr"
+ $asm.puts "mov.l @(6, PC), #{operands[1].sh4Operand}"
+ $asm.puts "braf #{operands[1].sh4Operand}"
+ $asm.puts "mov #{operands[0].sh4Operand}, r0"
+ $asm.puts ".long #{operands[2].asmLabel}-."
+ when "jmp"
+ if operands[0].is_a? LocalLabelReference
+ $asm.puts "bra #{operands[0].asmLabel}"
+ $asm.puts "nop"
+ elsif operands[0].is_a? RegisterID or operands[0].is_a? SpecialRegister
+ emitSH4Branch("jmp", operands[0])
+ else
+ raise "Unhandled parameters for opcode #{opcode} at #{codeOriginString}"
+ end
+ when "jmpf"
+ emitSH4Load32AndJump(operands[1].asmLabel, operands[0])
+ when "ret"
+ $asm.puts "rts"
+ $asm.puts "nop"
+ when "loadb"
+ $asm.puts "mov.b #{sh4Operands(operands)}"
+ $asm.puts "extu.b #{sh4Operands([operands[1], operands[1]])}"
+ when "storeb"
+ $asm.puts "mov.b #{sh4Operands(operands)}"
+ when "loadh"
+ $asm.puts "mov.w #{sh4Operands(operands)}"
+ $asm.puts "extu.w #{sh4Operands([operands[1], operands[1]])}"
+ when "loadi", "loadis", "loadp", "storei", "storep"
+ $asm.puts "mov.l #{sh4Operands(operands)}"
+ when "move"
+ if operands[0].is_a? Immediate
+ emitSH4LoadImm(operands)
+ else
+ $asm.puts "mov #{sh4Operands(operands)}"
+ end
+ when "leap"
+ if operands[0].is_a? BaseIndex
+ biop = operands[0]
+ $asm.puts "mov #{sh4Operands([biop.index, operands[1]])}"
+ if biop.scaleShift > 0
+ emitSH4ShiftImm(biop.scaleShift, operands[1], "l")
+ end
+ $asm.puts "add #{sh4Operands([biop.base, operands[1]])}"
+ if biop.offset.value != 0
+ $asm.puts "add #{sh4Operands([biop.offset, operands[1]])}"
+ end
+ elsif operands[0].is_a? Address
+ if operands[0].base != operands[1]
+ $asm.puts "mov #{sh4Operands([operands[0].base, operands[1]])}"
+ end
+ if operands[0].offset.value != 0
+ $asm.puts "add #{sh4Operands([operands[0].offset, operands[1]])}"
+ end
+ else
+ raise "Unhandled parameters for opcode #{opcode} at #{codeOriginString}"
+ end
+ when "ldspr"
+ $asm.puts "lds #{sh4Operands(operands)}, pr"
+ when "stspr"
+ $asm.puts "sts pr, #{sh4Operands(operands)}"
+ when "break"
+ # This special opcode always generates an illegal instruction exception.
+ $asm.puts ".word 0xfffd"
+ else
+ raise "Unhandled opcode #{opcode} at #{codeOriginString}"
+ end
+ end
+end
+
diff --git a/Source/JavaScriptCore/offlineasm/x86.rb b/Source/JavaScriptCore/offlineasm/x86.rb
index f78b43912..5e040ba76 100644
--- a/Source/JavaScriptCore/offlineasm/x86.rb
+++ b/Source/JavaScriptCore/offlineasm/x86.rb
@@ -1,4 +1,5 @@
# Copyright (C) 2012 Apple Inc. All rights reserved.
+# Copyright (C) 2013 Digia Plc. and/or its subsidiary(-ies)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -34,6 +35,17 @@ def isX64
end
end
+def useX87
+ case $activeBackend
+ when "X86"
+ true
+ when "X86_64"
+ false
+ else
+ raise "bad value for $activeBackend: #{$activeBackend}"
+ end
+end
+
class SpecialRegister < NoChildren
def x86Operand(kind)
raise unless @name =~ /^r/
@@ -255,6 +267,7 @@ end
class FPRegisterID
def x86Operand(kind)
raise unless kind == :double
+ raise if useX87
case name
when "ft0", "fa0", "fr"
"%xmm0"
@@ -272,6 +285,23 @@ class FPRegisterID
raise "Bad register #{name} for X86 at #{codeOriginString}"
end
end
+ def x87DefaultStackPosition
+ case name
+ when "ft0", "fr"
+ 0
+ when "ft1"
+ 1
+ when "ft2", "ft3", "ft4", "ft5"
+ raise "Unimplemented register #{name} for X86 at #{codeOriginString}"
+ else
+ raise "Bad register #{name} for X86 at #{codeOriginString}"
+ end
+ end
+ def x87Operand(offset)
+ raise unless useX87
+ raise unless offset == 0 or offset == 1
+ "%st(#{x87DefaultStackPosition + offset})"
+ end
def x86CallOperand(kind)
"*#{x86Operand(kind)}"
end
@@ -422,7 +452,7 @@ class Instruction
when :quad
isX64 ? "q" : raise
when :double
- "sd"
+ not useX87 ? "sd" : raise
else
raise
end
@@ -478,13 +508,17 @@ class Instruction
end
def handleX86DoubleBranch(branchOpcode, mode)
- case mode
- when :normal
- $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
- when :reverse
- $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ if useX87
+ handleX87Compare(mode)
else
- raise mode.inspect
+ case mode
+ when :normal
+ $asm.puts "ucomisd #{operands[1].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
+ when :reverse
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ else
+ raise mode.inspect
+ end
end
$asm.puts "#{branchOpcode} #{operands[2].asmLabel}"
end
@@ -584,7 +618,7 @@ class Instruction
end
$asm.puts "#{branchOpcode} #{jumpTarget.asmLabel}"
end
-
+
def handleX86Add(kind)
if operands.size == 3 and operands[1] == operands[2]
unless Immediate.new(nil, 0) == operands[0]
@@ -650,6 +684,38 @@ class Instruction
end
end
+ def handleX87Compare(mode)
+ case mode
+ when :normal
+ if (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "fucomi #{operands[1].x87Operand(0)}"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fucomip #{operands[1].x87Operand(1)}"
+ end
+ when :reverse
+ if (operands[1].x87DefaultStackPosition == 0)
+ $asm.puts "fucomi #{operands[0].x87Operand(0)}"
+ else
+ $asm.puts "fld #{operands[1].x87Operand(0)}"
+ $asm.puts "fucomip #{operands[0].x87Operand(1)}"
+ end
+ else
+ raise mode.inspect
+ end
+ end
+
+ def handleX87BinOp(opcode, opcodereverse)
+ if (operands[1].x87DefaultStackPosition == 0)
+ $asm.puts "#{opcode} #{operands[0].x87Operand(0)}, %st"
+ elsif (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "#{opcodereverse} %st, #{operands[1].x87Operand(0)}"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "#{opcodereverse}p %st, #{operands[1].x87Operand(1)}"
+ end
+ end
+
def lowerX86
raise unless $activeBackend == "X86"
lowerX86Common
@@ -749,22 +815,82 @@ class Instruction
$asm.puts "movswl #{operands[0].x86Operand(:half)}, #{operands[1].x86Operand(:int)}"
when "storeb"
$asm.puts "movb #{x86Operands(:byte, :byte)}"
- when "loadd", "moved", "stored"
- $asm.puts "movsd #{x86Operands(:double, :double)}"
+ when "loadd"
+ if useX87
+ $asm.puts "fldl #{operands[0].x86Operand(:double)}"
+ $asm.puts "fstp #{operands[1].x87Operand(1)}"
+ else
+ $asm.puts "movsd #{x86Operands(:double, :double)}"
+ end
+ when "moved"
+ if useX87
+ if (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "fst #{operands[1].x87Operand(0)}"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fstp #{operands[1].x87Operand(1)}"
+ end
+ else
+ $asm.puts "movsd #{x86Operands(:double, :double)}"
+ end
+ when "stored"
+ if useX87
+ if (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "fstl #{operands[1].x86Operand(:double)}"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fstpl #{operands[1].x86Operand(:double)}"
+ end
+ else
+ $asm.puts "movsd #{x86Operands(:double, :double)}"
+ end
when "addd"
- $asm.puts "addsd #{x86Operands(:double, :double)}"
- when "divd"
- $asm.puts "divsd #{x86Operands(:double, :double)}"
- when "subd"
- $asm.puts "subsd #{x86Operands(:double, :double)}"
+ if useX87
+ handleX87BinOp("fadd", "fadd")
+ else
+ $asm.puts "addsd #{x86Operands(:double, :double)}"
+ end
when "muld"
- $asm.puts "mulsd #{x86Operands(:double, :double)}"
+ if useX87
+ handleX87BinOp("fmul", "fmul")
+ else
+ $asm.puts "mulsd #{x86Operands(:double, :double)}"
+ end
+ when "subd"
+ if useX87
+ handleX87BinOp("fsub", "fsubr")
+ else
+ $asm.puts "subsd #{x86Operands(:double, :double)}"
+ end
+ when "divd"
+ if useX87
+ handleX87BinOp("fdiv", "fdivr")
+ else
+ $asm.puts "divsd #{x86Operands(:double, :double)}"
+ end
when "sqrtd"
- $asm.puts "sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ if useX87
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fsqrtl"
+ $asm.puts "fstp #{operands[1].x87Operand(1)}"
+ else
+ $asm.puts "sqrtsd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ end
when "ci2d"
- $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
+ if useX87
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "movl #{operands[0].x86Operand(:int)}, -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fildl -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fstp #{operands[1].x87Operand(1)}"
+ else
+ $asm.puts "cvtsi2sd #{operands[0].x86Operand(:int)}, #{operands[1].x86Operand(:double)}"
+ end
when "bdeq"
- $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ if useX87
+ handleX87Compare(:normal)
+ else
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ end
if operands[0] == operands[1]
# This is just a jump ordered, which is a jnp.
$asm.puts "jnp #{operands[2].asmLabel}"
@@ -787,7 +913,11 @@ class Instruction
when "bdequn"
handleX86DoubleBranch("je", :normal)
when "bdnequn"
- $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ if useX87
+ handleX87Compare(:normal)
+ else
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:double)}"
+ end
if operands[0] == operands[1]
# This is just a jump unordered, which is a jp.
$asm.puts "jp #{operands[2].asmLabel}"
@@ -809,21 +939,47 @@ class Instruction
when "bdltequn"
handleX86DoubleBranch("jbe", :normal)
when "btd2i"
+ # FIXME: unused and unimplemented for x87
+ raise if useX87
$asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
$asm.puts "cmpl $0x80000000 #{operands[1].x86Operand(:int)}"
$asm.puts "je #{operands[2].asmLabel}"
when "td2i"
+ # FIXME: unused and unimplemented for x87
+ raise if useX87
$asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
when "bcd2i"
- $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
- $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
- $asm.puts "je #{operands[2].asmLabel}"
- $asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
- $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
- $asm.puts "jp #{operands[2].asmLabel}"
- $asm.puts "jne #{operands[2].asmLabel}"
+ if useX87
+ sp = RegisterID.new(nil, "sp")
+ if (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "fistl -4(#{sp.x86Operand(:ptr)})"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fistpl -4(#{sp.x86Operand(:ptr)})"
+ end
+ $asm.puts "movl -4(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:int)}"
+ $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+ $asm.puts "je #{operands[2].asmLabel}"
+ $asm.puts "fildl -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fucomip #{operands[0].x87Operand(1)}"
+ $asm.puts "jp #{operands[2].asmLabel}"
+ $asm.puts "jne #{operands[2].asmLabel}"
+ else
+ $asm.puts "cvttsd2si #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
+ $asm.puts "testl #{operands[1].x86Operand(:int)}, #{operands[1].x86Operand(:int)}"
+ $asm.puts "je #{operands[2].asmLabel}"
+ $asm.puts "cvtsi2sd #{operands[1].x86Operand(:int)}, %xmm7"
+ $asm.puts "ucomisd #{operands[0].x86Operand(:double)}, %xmm7"
+ $asm.puts "jp #{operands[2].asmLabel}"
+ $asm.puts "jne #{operands[2].asmLabel}"
+ end
when "movdz"
- $asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
+ if useX87
+ $asm.puts "fldzl"
+ $asm.puts "fstp #{operands[0].x87Operand(1)}"
+ else
+ $asm.puts "xorpd #{operands[0].x86Operand(:double)}, #{operands[0].x86Operand(:double)}"
+ end
when "pop"
$asm.puts "pop #{operands[0].x86Operand(:ptr)}"
when "push"
@@ -993,6 +1149,12 @@ class Instruction
when "break"
$asm.puts "int $3"
when "call"
+ if useX87
+ 2.times {
+ | offset |
+ $asm.puts "ffree %st(#{offset})"
+ }
+ end
$asm.puts "call #{operands[0].x86CallOperand(:ptr)}"
when "ret"
$asm.puts "ret"
@@ -1117,19 +1279,57 @@ class Instruction
when "idivi"
$asm.puts "idivl #{operands[0].x86Operand(:int)}"
when "fii2d"
- $asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
- $asm.puts "movd #{operands[1].x86Operand(:int)}, %xmm7"
- $asm.puts "psllq $32, %xmm7"
- $asm.puts "por %xmm7, #{operands[2].x86Operand(:double)}"
+ if useX87
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "movl #{operands[0].x86Operand(:int)}, -8(#{sp.x86Operand(:ptr)})"
+ $asm.puts "movl #{operands[1].x86Operand(:int)}, -4(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fldl -8(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fstp #{operands[2].x87Operand(1)}"
+ else
+ $asm.puts "movd #{operands[0].x86Operand(:int)}, #{operands[2].x86Operand(:double)}"
+ $asm.puts "movd #{operands[1].x86Operand(:int)}, %xmm7"
+ $asm.puts "psllq $32, %xmm7"
+ $asm.puts "por %xmm7, #{operands[2].x86Operand(:double)}"
+ end
when "fd2ii"
- $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
- $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
- $asm.puts "psrlq $32, %xmm7"
- $asm.puts "movd %xmm7, #{operands[2].x86Operand(:int)}"
+ if useX87
+ sp = RegisterID.new(nil, "sp")
+ if (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "fstl -8(#{sp.x86Operand(:ptr)})"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fstpl -8(#{sp.x86Operand(:ptr)})"
+ end
+ $asm.puts "movl -8(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:int)}"
+ $asm.puts "movl -4(#{sp.x86Operand(:ptr)}), #{operands[2].x86Operand(:int)}"
+ else
+ $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:int)}"
+ $asm.puts "movsd #{operands[0].x86Operand(:double)}, %xmm7"
+ $asm.puts "psrlq $32, %xmm7"
+ $asm.puts "movd %xmm7, #{operands[2].x86Operand(:int)}"
+ end
when "fq2d"
- $asm.puts "movd #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
+ if useX87
+ sp = RegisterID.new(nil, "sp")
+ $asm.puts "movq #{operands[0].x86Operand(:quad)}, -8(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fldl -8(#{sp.x86Operand(:ptr)})"
+ $asm.puts "fstp #{operands[1].x87Operand(1)}"
+ else
+ $asm.puts "movq #{operands[0].x86Operand(:quad)}, #{operands[1].x86Operand(:double)}"
+ end
when "fd2q"
- $asm.puts "movd #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
+ if useX87
+ sp = RegisterID.new(nil, "sp")
+ if (operands[0].x87DefaultStackPosition == 0)
+ $asm.puts "fstl -8(#{sp.x86Operand(:ptr)})"
+ else
+ $asm.puts "fld #{operands[0].x87Operand(0)}"
+ $asm.puts "fstpl -8(#{sp.x86Operand(:ptr)})"
+ end
+ $asm.puts "movq -8(#{sp.x86Operand(:ptr)}), #{operands[1].x86Operand(:quad)}"
+ else
+ $asm.puts "movq #{operands[0].x86Operand(:double)}, #{operands[1].x86Operand(:quad)}"
+ end
when "bo"
$asm.puts "jo #{operands[0].asmLabel}"
when "bs"
diff --git a/Source/JavaScriptCore/os-win32/WinMain.cpp b/Source/JavaScriptCore/os-win32/WinMain.cpp
deleted file mode 100644
index d4ff3e657..000000000
--- a/Source/JavaScriptCore/os-win32/WinMain.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2009 Patrick Gansterer (paroga@paroga.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include <wtf/Vector.h>
-#include <winbase.h>
-#include <winnls.h>
-#include <wtf/UnusedParam.h>
-
-int main(int argc, char** argv);
-
-static inline char* convertToUtf8(LPCWSTR widecharString, int length)
-{
- int requiredSize = WideCharToMultiByte(CP_UTF8, 0, widecharString, length, 0, 0, 0, 0);
- char* multibyteString = new char[requiredSize + 1];
-
- WideCharToMultiByte(CP_UTF8, 0, widecharString, length, multibyteString, requiredSize, 0, 0);
- multibyteString[requiredSize] = '\0';
-
- return multibyteString;
-}
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
-{
- UNUSED_PARAM(hInstance);
- UNUSED_PARAM(hPrevInstance);
- UNUSED_PARAM(nCmdShow);
-
- Vector<char*> arguments;
- TCHAR buffer[MAX_PATH];
-
- int length = GetModuleFileNameW(0, buffer, MAX_PATH);
- arguments.append(convertToUtf8(buffer, length));
-
- WCHAR* commandLine = lpCmdLine;
- while (commandLine[0] != '\0') {
- int commandLineLength = 1;
- WCHAR endChar = ' ';
-
- while (commandLine[0] == ' ')
- ++commandLine;
-
- if (commandLine[0] == '\"') {
- ++commandLine;
- endChar = '\"';
- }
-
- while (commandLine[commandLineLength] != endChar && commandLine[commandLineLength] != '\0')
- ++commandLineLength;
-
- arguments.append(convertToUtf8(commandLine, commandLineLength));
-
- commandLine += commandLineLength;
- if (endChar != ' ' && commandLine[0] != '\0')
- ++commandLine;
- }
-
- int res = main(arguments.size(), arguments.data());
-
- for (size_t i = 0; i < arguments.size(); i++)
- delete arguments[i];
-
- return res;
-}
diff --git a/Source/JavaScriptCore/os-win32/inttypes.h b/Source/JavaScriptCore/os-win32/inttypes.h
index af7390e98..5ecc2762a 100644
--- a/Source/JavaScriptCore/os-win32/inttypes.h
+++ b/Source/JavaScriptCore/os-win32/inttypes.h
@@ -38,11 +38,6 @@
#error "This inttypes.h file should only be compiled with MSVC"
#endif
-#ifdef WTF_COMPILER_MSVC7_OR_LOWER
-// https://bugs.webkit.org/show_bug.cgi?id=76210
-#error "Visual Studio 2005 or newer is required"
-#endif
-
#if _MSC_VER > 1000
#pragma once
#endif
diff --git a/Source/JavaScriptCore/os-win32/stdint.h b/Source/JavaScriptCore/os-win32/stdint.h
deleted file mode 100644
index b5dff5660..000000000
--- a/Source/JavaScriptCore/os-win32/stdint.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2005, 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef STDINT_WIN32_H
-#define STDINT_WIN32_H
-
-#include <wtf/Platform.h>
-
-/* This file emulates enough of stdint.h on Windows to make JavaScriptCore and WebCore
- compile using MSVC which does not ship with the stdint.h header. */
-
-#if !COMPILER(MSVC)
-#error "This stdint.h file should only be compiled with MSVC"
-#endif
-
-#include <limits.h>
-
-typedef unsigned char uint8_t;
-typedef signed char int8_t;
-typedef unsigned short uint16_t;
-typedef short int16_t;
-typedef unsigned int uint32_t;
-typedef int int32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
-#ifndef SIZE_MAX
-#ifdef _WIN64
-#define SIZE_MAX _UI64_MAX
-#else
-#define SIZE_MAX _UI32_MAX
-#endif
-#endif
-#endif
-
-#ifndef CASSERT
-#define CASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
-#endif
-
-CASSERT(sizeof(int8_t) == 1, int8_t_is_one_byte)
-CASSERT(sizeof(uint8_t) == 1, uint8_t_is_one_byte)
-CASSERT(sizeof(int16_t) == 2, int16_t_is_two_bytes)
-CASSERT(sizeof(uint16_t) == 2, uint16_t_is_two_bytes)
-CASSERT(sizeof(int32_t) == 4, int32_t_is_four_bytes)
-CASSERT(sizeof(uint32_t) == 4, uint32_t_is_four_bytes)
-CASSERT(sizeof(int64_t) == 8, int64_t_is_eight_bytes)
-CASSERT(sizeof(uint64_t) == 8, uint64_t_is_eight_bytes)
-
-#endif
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index 6e7334f97..43d9b4f1b 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,50 +33,68 @@
namespace JSC {
class ASTBuilder {
+ struct PositionInfo {
+ unsigned startPos;
+ unsigned line;
+ unsigned lineStartPos;
+ };
+
struct BinaryOpInfo {
BinaryOpInfo() {}
- BinaryOpInfo(int s, int d, int e, bool r)
- : start(s)
- , divot(d)
- , end(e)
- , hasAssignment(r)
+ BinaryOpInfo(int otherStart, int otherDivot, int otherEnd, unsigned otherDivotLine, unsigned otherDivotLineStart, bool rhsHasAssignment)
+ : start(otherStart)
+ , divot(otherDivot)
+ , end(otherEnd)
+ , divotLine(otherDivotLine)
+ , divotLineStart(otherDivotLineStart)
+ , hasAssignment(rhsHasAssignment)
{
}
BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
: start(lhs.start)
, divot(rhs.start)
, end(rhs.end)
+ , divotLine(rhs.divotLine)
+ , divotLineStart(rhs.divotLineStart)
, hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
{
}
int start;
int divot;
int end;
+ unsigned divotLine;
+ unsigned divotLineStart;
bool hasAssignment;
};
struct AssignmentInfo {
AssignmentInfo() {}
- AssignmentInfo(ExpressionNode* node, int start, int divot, int initAssignments, Operator op)
+ AssignmentInfo(ExpressionNode* node, unsigned start, unsigned divot, unsigned divotLine, unsigned divotLineStart, int initAssignments, Operator op)
: m_node(node)
, m_start(start)
, m_divot(divot)
+ , m_divotLine(divotLine)
+ , m_divotLineStart(divotLineStart)
, m_initAssignments(initAssignments)
, m_op(op)
{
+ ASSERT(m_divot >= m_divotLineStart);
+ ASSERT(m_start >= m_divotLineStart);
}
ExpressionNode* m_node;
- int m_start;
- int m_divot;
+ unsigned m_start;
+ unsigned m_divot;
+ unsigned m_divotLine;
+ unsigned m_divotLineStart;
int m_initAssignments;
Operator m_op;
};
public:
- ASTBuilder(JSGlobalData* globalData, SourceCode* sourceCode)
- : m_globalData(globalData)
+ ASTBuilder(VM* vm, SourceCode* sourceCode)
+ : m_vm(vm)
, m_sourceCode(sourceCode)
- , m_scope(globalData)
+ , m_scope(vm)
, m_evalCount(0)
{
}
@@ -113,9 +131,9 @@ public:
static const int DontBuildStrings = 0;
ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
- ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
+ ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, int start, unsigned divot, int end, unsigned divotLine, unsigned divotLineStart);
- JSC::SourceElements* createSourceElements() { return new (m_globalData) JSC::SourceElements(); }
+ JSC::SourceElements* createSourceElements() { return new (m_vm) JSC::SourceElements(); }
ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
@@ -124,13 +142,13 @@ public:
void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
- CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(location, lhs, rhs); }
+ CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_vm) CommaNode(location, lhs, rhs); }
- ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end);
- ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end);
- ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end);
+ ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart);
+ ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart);
+ ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart);
ExpressionNode* makeTypeOfNode(const JSTokenLocation&, ExpressionNode*);
- ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, int start, int divot, int end);
+ ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart);
ExpressionNode* makeNegateNode(const JSTokenLocation&, ExpressionNode*);
ExpressionNode* makeBitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
ExpressionNode* makeMultNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
@@ -145,355 +163,359 @@ public:
ExpressionNode* makeRightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
ExpressionNode* makeURightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* createLogicalNot(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(location, expr); }
- ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(location, expr); }
+ ExpressionNode* createLogicalNot(const JSTokenLocation& location, ExpressionNode* expr)
+ {
+ if (expr->isNumber())
+ return createBoolean(location, isZeroOrUnordered(static_cast<NumberNode*>(expr)->value()));
+
+ return new (m_vm) LogicalNotNode(location, expr);
+ }
+ ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_vm) UnaryPlusNode(location, expr); }
ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
{
incConstants();
- return new (m_globalData) VoidNode(location, expr);
+ return new (m_vm) VoidNode(location, expr);
}
ExpressionNode* thisExpr(const JSTokenLocation& location)
{
usesThis();
- return new (m_globalData) ThisNode(location);
+ return new (m_vm) ThisNode(location);
}
- ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, int start)
+ ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, unsigned start, unsigned divotLine, unsigned divotLineStart)
{
- if (m_globalData->propertyNames->arguments == *ident)
+ if (m_vm->propertyNames->arguments == *ident)
usesArguments();
- return new (m_globalData) ResolveNode(location, *ident, start);
+ return new (m_vm) ResolveNode(location, *ident, start, divotLine, divotLineStart);
}
- ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_globalData) ObjectLiteralNode(location); }
- ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(location, properties); }
+ ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_vm) ObjectLiteralNode(location); }
+ ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_vm) ObjectLiteralNode(location, properties); }
ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
{
if (elisions)
incConstants();
- return new (m_globalData) ArrayNode(location, elisions);
+ return new (m_vm) ArrayNode(location, elisions);
}
- ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_globalData) ArrayNode(location, elems); }
+ ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_vm) ArrayNode(location, elems); }
ExpressionNode* createArray(const JSTokenLocation& location, int elisions, ElementNode* elems)
{
if (elisions)
incConstants();
- return new (m_globalData) ArrayNode(location, elisions, elems);
+ return new (m_vm) ArrayNode(location, elisions, elems);
}
ExpressionNode* createNumberExpr(const JSTokenLocation& location, double d)
{
incConstants();
- return new (m_globalData) NumberNode(location, d);
+ return new (m_vm) NumberNode(location, d);
}
ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
{
incConstants();
- return new (m_globalData) StringNode(location, *string);
+ return new (m_vm) StringNode(location, *string);
}
ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
{
incConstants();
- return new (m_globalData) BooleanNode(location, b);
+ return new (m_vm) BooleanNode(location, b);
}
ExpressionNode* createNull(const JSTokenLocation& location)
{
incConstants();
- return new (m_globalData) NullNode(location);
+ return new (m_vm) NullNode(location);
}
- ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end)
+ ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
- BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(location, base, property, propertyHasAssignments);
- setExceptionLocation(node, start, divot, end);
+ BracketAccessorNode* node = new (m_vm) BracketAccessorNode(location, base, property, propertyHasAssignments);
+ setExceptionLocation(node, start, divot, end, divotLine, divotLineStart);
return node;
}
- ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, int start, int divot, int end)
+ ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
- DotAccessorNode* node = new (m_globalData) DotAccessorNode(location, base, *property);
- setExceptionLocation(node, start, divot, end);
+ DotAccessorNode* node = new (m_vm) DotAccessorNode(location, base, *property);
+ setExceptionLocation(node, start, divot, end, divotLine, divotLineStart);
return node;
}
- ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, int start)
+ ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, int start, unsigned divotLine, unsigned divotLineStart)
{
if (Yarr::checkSyntax(pattern.string()))
return 0;
- RegExpNode* node = new (m_globalData) RegExpNode(location, pattern, flags);
+ RegExpNode* node = new (m_vm) RegExpNode(location, pattern, flags);
int size = pattern.length() + 2; // + 2 for the two /'s
- setExceptionLocation(node, start, start + size, start + size);
+ setExceptionLocation(node, start, start + size, start + size, divotLine, divotLineStart);
return node;
}
- ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end)
+ ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
- NewExprNode* node = new (m_globalData) NewExprNode(location, expr, arguments);
- setExceptionLocation(node, start, divot, end);
+ NewExprNode* node = new (m_vm) NewExprNode(location, expr, arguments);
+ setExceptionLocation(node, start, divot, end, divotLine, divotLineStart);
return node;
}
- ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
+ ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, int start, int end, unsigned divotLine, unsigned divotLineStart)
{
- NewExprNode* node = new (m_globalData) NewExprNode(location, expr);
- setExceptionLocation(node, start, end, end);
+ NewExprNode* node = new (m_vm) NewExprNode(location, expr);
+ setExceptionLocation(node, start, end, end, divotLine, divotLineStart);
return node;
}
ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
{
- return new (m_globalData) ConditionalNode(location, condition, lhs, rhs);
+ return new (m_vm) ConditionalNode(location, condition, lhs, rhs);
}
- ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, int start, int divot, int end)
+ ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
if (rhs->isFuncExprNode())
static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident);
- AssignResolveNode* node = new (m_globalData) AssignResolveNode(location, ident, rhs);
- setExceptionLocation(node, start, divot, end);
+ AssignResolveNode* node = new (m_vm) AssignResolveNode(location, ident, rhs);
+ setExceptionLocation(node, start, divot, end, divotLine, divotLineStart);
return node;
}
- ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned startColumn)
{
- FuncExprNode* result = new (m_globalData) FuncExprNode(location, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
- body->setLoc(bodyStartLine, bodyEndLine, location.column);
+ FuncExprNode* result = new (m_vm) FuncExprNode(location, *name, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, startColumn), parameters);
+ body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
return result;
}
- FunctionBodyNode* createFunctionBody(const JSTokenLocation& location, bool inStrictContext)
+ FunctionBodyNode* createFunctionBody(const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext)
+ {
+ return FunctionBodyNode::create(m_vm, startLocation, endLocation, startColumn, inStrictContext);
+ }
+
+ void setFunctionStart(FunctionBodyNode* body, int functionStart)
{
- return FunctionBodyNode::create(m_globalData, location, inStrictContext);
+ body->setFunctionStart(functionStart);
}
- template <bool> PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ template <bool> PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn)
{
ASSERT(name);
- body->setLoc(bodyStartLine, bodyEndLine, location.column);
+ body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
body->setInferredName(*name);
- return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(location, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
+ return new (m_vm) PropertyNode(m_vm, *name, new (m_vm) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), params), type);
}
- template <bool> PropertyNode* createGetterOrSetterProperty(JSGlobalData*, const JSTokenLocation& location, PropertyNode::Type type, double name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ template <bool> PropertyNode* createGetterOrSetterProperty(VM*, const JSTokenLocation& location, PropertyNode::Type type, double name, ParameterNode* params, FunctionBodyNode* body, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn)
{
- body->setLoc(bodyStartLine, bodyEndLine, location.column);
- return new (m_globalData) PropertyNode(m_globalData, name, new (m_globalData) FuncExprNode(location, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
+ body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
+ return new (m_vm) PropertyNode(m_vm, name, new (m_vm) FuncExprNode(location, m_vm->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), params), type);
}
- ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(); }
- ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(args); }
- ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(location, arg); }
- ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(location, args, arg); }
+ ArgumentsNode* createArguments() { return new (m_vm) ArgumentsNode(); }
+ ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_vm) ArgumentsNode(args); }
+ ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_vm) ArgumentListNode(location, arg); }
+ ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_vm) ArgumentListNode(location, args, arg); }
template <bool> PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type)
{
if (node->isFuncExprNode())
static_cast<FuncExprNode*>(node)->body()->setInferredName(*propertyName);
- return new (m_globalData) PropertyNode(m_globalData, *propertyName, node, type);
+ return new (m_vm) PropertyNode(m_vm, *propertyName, node, type);
}
- template <bool> PropertyNode* createProperty(JSGlobalData*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, propertyName, node, type); }
- PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_globalData) PropertyListNode(location, property); }
- PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(location, property, tail); }
+ template <bool> PropertyNode* createProperty(VM*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_vm) PropertyNode(m_vm, propertyName, node, type); }
+ PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_vm) PropertyListNode(location, property); }
+ PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_vm) PropertyListNode(location, property, tail); }
- ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(elisions, expr); }
- ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(elems, elisions, expr); }
+ ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_vm) ElementNode(elisions, expr); }
+ ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_vm) ElementNode(elems, elisions, expr); }
- ParameterNode* createFormalParameterList(const Identifier& ident) { return new (m_globalData) ParameterNode(ident); }
- ParameterNode* createFormalParameterList(ParameterNode* list, const Identifier& ident) { return new (m_globalData) ParameterNode(list, ident); }
+ ParameterNode* createFormalParameterList(const Identifier& ident) { return new (m_vm) ParameterNode(ident); }
+ ParameterNode* createFormalParameterList(ParameterNode* list, const Identifier& ident) { return new (m_vm) ParameterNode(list, ident); }
- CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_globalData) CaseClauseNode(expr, statements); }
- ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(clause); }
- ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(tail, clause); }
+ CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_vm) CaseClauseNode(expr, statements); }
+ ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_vm) ClauseListNode(clause); }
+ ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_vm) ClauseListNode(tail, clause); }
void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); }
- StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, unsigned openBraceOffset, unsigned closeBraceOffset, int bodyStartLine, int bodyEndLine, unsigned bodyStartColumn)
{
- FuncDeclNode* decl = new (m_globalData) FuncDeclNode(location, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
- if (*name == m_globalData->propertyNames->arguments)
+ FuncDeclNode* decl = new (m_vm) FuncDeclNode(location, *name, body, m_sourceCode->subExpression(openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn), parameters);
+ if (*name == m_vm->propertyNames->arguments)
usesArguments();
m_scope.m_funcDeclarations->data.append(decl->body());
- body->setLoc(bodyStartLine, bodyEndLine, location.column);
+ body->setLoc(bodyStartLine, bodyEndLine, location.startOffset, location.lineStartOffset);
return decl;
}
StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine)
{
- BlockNode* block = new (m_globalData) BlockNode(location, elements);
- block->setLoc(startLine, endLine, location.column);
+ BlockNode* block = new (m_vm) BlockNode(location, elements);
+ block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return block;
}
StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
{
- ExprStatementNode* result = new (m_globalData) ExprStatementNode(location, expr);
- result->setLoc(start, end, location.column);
- return result;
- }
-
- StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, int start, int end)
- {
- IfNode* result = new (m_globalData) IfNode(location, condition, trueBlock);
- result->setLoc(start, end, location.column);
+ ExprStatementNode* result = new (m_vm) ExprStatementNode(location, expr);
+ result->setLoc(start, end, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
{
- IfNode* result = new (m_globalData) IfElseNode(location, condition, trueBlock, falseBlock);
- result->setLoc(start, end, location.column);
+ IfElseNode* result = new (m_vm) IfElseNode(location, condition, trueBlock, falseBlock);
+ result->setLoc(start, end, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
{
- ForNode* result = new (m_globalData) ForNode(location, initializer, condition, iter, statements);
- result->setLoc(start, end);
+ ForNode* result = new (m_vm) ForNode(location, initializer, condition, iter, statements);
+ result->setLoc(start, end, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createForInLoop(const JSTokenLocation& location, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine)
+ StatementNode* createForInLoop(const JSTokenLocation& location, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine, unsigned divotLine, unsigned divotLineStart)
{
- ForInNode* result = new (m_globalData) ForInNode(m_globalData, location, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart);
- result->setLoc(startLine, endLine, location.column);
- setExceptionLocation(result, start, divot + 1, end);
+ ForInNode* result = new (m_vm) ForInNode(m_vm, location, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart, divotLine, divotLineStart);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
+ setExceptionLocation(result, start, divot + 1, end, divotLine, divotLineStart);
return result;
}
- StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end)
+ StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end, unsigned divotLine, unsigned divotLineStart)
{
- ForInNode* result = new (m_globalData) ForInNode(location, lhs, iter, statements);
- result->setLoc(start, end, location.column);
- setExceptionLocation(result, eStart, eDivot, eEnd);
+ ForInNode* result = new (m_vm) ForInNode(location, lhs, iter, statements);
+ result->setLoc(start, end, location.startOffset, location.lineStartOffset);
+ setExceptionLocation(result, eStart, eDivot, eEnd, divotLine, divotLineStart);
return result;
}
- StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_globalData) EmptyStatementNode(location); }
+ StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_vm) EmptyStatementNode(location); }
StatementNode* createVarStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
{
StatementNode* result;
if (!expr)
- result = new (m_globalData) EmptyStatementNode(location);
+ result = new (m_vm) EmptyStatementNode(location);
else
- result = new (m_globalData) VarStatementNode(location, expr);
- result->setLoc(start, end, location.column);
+ result = new (m_vm) VarStatementNode(location, expr);
+ result->setLoc(start, end, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine, unsigned divotLine, unsigned divotLineStart)
{
- ReturnNode* result = new (m_globalData) ReturnNode(location, expression);
- setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine, location.column);
+ ReturnNode* result = new (m_vm) ReturnNode(location, expression);
+ setExceptionLocation(result, eStart, eEnd, eEnd, divotLine, divotLineStart);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createBreakStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createBreakStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart)
{
- BreakNode* result = new (m_globalData) BreakNode(m_globalData, location);
- setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine, location.column);
+ BreakNode* result = new (m_vm) BreakNode(m_vm, location);
+ setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart)
{
- BreakNode* result = new (m_globalData) BreakNode(location, *ident);
- setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine, location.column);
+ BreakNode* result = new (m_vm) BreakNode(location, *ident);
+ setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createContinueStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createContinueStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart)
{
- ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, location);
- setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine, location.column);
+ ContinueNode* result = new (m_vm) ContinueNode(m_vm, location);
+ setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart)
{
- ContinueNode* result = new (m_globalData) ContinueNode(location, *ident);
- setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine, location.column);
+ ContinueNode* result = new (m_vm) ContinueNode(location, *ident);
+ setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
{
- TryNode* result = new (m_globalData) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
+ TryNode* result = new (m_vm) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
if (catchBlock)
usesCatch();
- result->setLoc(startLine, endLine, location.column);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
{
- CaseBlockNode* cases = new (m_globalData) CaseBlockNode(firstClauses, defaultClause, secondClauses);
- SwitchNode* result = new (m_globalData) SwitchNode(location, expr, cases);
- result->setLoc(startLine, endLine, location.column);
+ CaseBlockNode* cases = new (m_vm) CaseBlockNode(firstClauses, defaultClause, secondClauses);
+ SwitchNode* result = new (m_vm) SwitchNode(location, expr, cases);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
{
- WhileNode* result = new (m_globalData) WhileNode(location, expr, statement);
- result->setLoc(startLine, endLine, location.column);
+ WhileNode* result = new (m_vm) WhileNode(location, expr, statement);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
{
- DoWhileNode* result = new (m_globalData) DoWhileNode(location, statement, expr);
- result->setLoc(startLine, endLine, location.column);
+ DoWhileNode* result = new (m_vm) DoWhileNode(location, statement, expr);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, int start, int end)
+ StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, unsigned start, unsigned end, unsigned divotLine, unsigned divotLineStart)
{
- LabelNode* result = new (m_globalData) LabelNode(location, *ident, statement);
- setExceptionLocation(result, start, end, end);
+ LabelNode* result = new (m_vm) LabelNode(location, *ident, statement);
+ setExceptionLocation(result, start, end, end, divotLine, divotLineStart);
return result;
}
- StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
+ StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, unsigned end, unsigned startLine, unsigned endLine, unsigned divotLine, unsigned divotLineStart)
{
usesWith();
- WithNode* result = new (m_globalData) WithNode(location, expr, statement, end, end - start);
- result->setLoc(startLine, endLine, location.column);
+ WithNode* result = new (m_vm) WithNode(location, expr, statement, end, divotLine, divotLineStart, end - start);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
- StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end, int startLine, int endLine)
+ StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end, int startLine, int endLine, unsigned divotLine, unsigned divotLineStart)
{
- ThrowNode* result = new (m_globalData) ThrowNode(location, expr);
- result->setLoc(startLine, endLine, location.column);
- setExceptionLocation(result, start, end, end);
+ ThrowNode* result = new (m_vm) ThrowNode(location, expr);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
+ setExceptionLocation(result, start, end, end, divotLine, divotLineStart);
return result;
}
StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
{
- DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(location);
- result->setLoc(startLine, endLine, location.column);
+ DebuggerStatementNode* result = new (m_vm) DebuggerStatementNode(location);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
StatementNode* createConstStatement(const JSTokenLocation& location, ConstDeclNode* decls, int startLine, int endLine)
{
- ConstStatementNode* result = new (m_globalData) ConstStatementNode(location, decls);
- result->setLoc(startLine, endLine, location.column);
+ ConstStatementNode* result = new (m_vm) ConstStatementNode(location, decls);
+ result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
return result;
}
ConstDeclNode* appendConstDecl(const JSTokenLocation& location, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
{
- ConstDeclNode* result = new (m_globalData) ConstDeclNode(location, *name, initializer);
+ ConstDeclNode* result = new (m_vm) ConstDeclNode(location, *name, initializer);
if (tail)
tail->m_next = result;
return result;
@@ -506,7 +528,7 @@ public:
void addVar(const Identifier* ident, int attrs)
{
- if (m_globalData->propertyNames->arguments == *ident)
+ if (m_vm->propertyNames->arguments == *ident)
usesArguments();
m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
}
@@ -519,15 +541,15 @@ public:
static_cast<CommaNode*>(list)->append(init);
return list;
}
- return new (m_globalData) CommaNode(location, list, init);
+ return new (m_vm) CommaNode(location, list, init);
}
int evalCount() const { return m_evalCount; }
- void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
+ void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, unsigned divotLine, unsigned divotLineStart, bool hasAssignments)
{
operandStackDepth++;
- m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
+ m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, divotLine, divotLineStart, hasAssignments)));
}
// Logic to handle datastructures used during parsing of binary expressions
@@ -564,10 +586,11 @@ public:
return result;
}
- void appendUnaryToken(int& tokenStackDepth, int type, int start)
+ void appendUnaryToken(int& tokenStackDepth, int type, unsigned start, unsigned divotLine, unsigned divotLineStart)
{
tokenStackDepth++;
- m_unaryTokenStack.append(std::make_pair(type, start));
+ PositionInfo position = { start, divotLine, divotLineStart };
+ m_unaryTokenStack.append(std::make_pair(type, position));
}
int unaryTokenStackLastType(int&)
@@ -575,26 +598,34 @@ public:
return m_unaryTokenStack.last().first;
}
- int unaryTokenStackLastStart(int&)
+ unsigned unaryTokenStackLastStart(int&)
{
- return m_unaryTokenStack.last().second;
+ return m_unaryTokenStack.last().second.startPos;
}
+ unsigned unaryTokenStackLastLineStartPosition(int&)
+ {
+ return m_unaryTokenStack.last().second.lineStartPos;
+ }
+
void unaryTokenStackRemoveLast(int& tokenStackDepth)
{
tokenStackDepth--;
m_unaryTokenStack.removeLast();
}
- void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, int start, int divot, int assignmentCount, Operator op)
+ void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, unsigned start, unsigned divot, unsigned divotLine, unsigned divotLineStart, int assignmentCount, Operator op)
{
assignmentStackDepth++;
- m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
+ ASSERT(start >= divotLineStart);
+ ASSERT(divot >= divotLineStart);
+ m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, divotLine, divotLineStart, assignmentCount, op));
}
ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd)
{
- ExpressionNode* result = makeAssignNode(location, m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd);
+ AssignmentInfo& info = m_assignmentInfoStack.last();
+ ExpressionNode* result = makeAssignNode(location, info.m_node, info.m_op, rhs, info.m_initAssignments != initialAssignmentCount, info.m_initAssignments != currentAssignmentCount, info.m_start, info.m_divot + 1, lastTokenEnd, info.m_divotLine, info.m_divotLineStart);
m_assignmentInfoStack.removeLast();
assignmentStackDepth--;
return result;
@@ -607,9 +638,9 @@ public:
private:
struct Scope {
- Scope(JSGlobalData* globalData)
- : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
- , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
+ Scope(VM* vm)
+ : m_varDeclarations(new (vm) ParserArenaData<DeclarationStacks::VarStack>)
+ , m_funcDeclarations(new (vm) ParserArenaData<DeclarationStacks::FunctionStack>)
, m_features(0)
, m_numConstants(0)
{
@@ -620,9 +651,10 @@ private:
int m_numConstants;
};
- static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
+ static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end, unsigned divotLine, unsigned divotLineStart)
{
- node->setExceptionSourceCode(divot, divot - start, end - divot);
+ ASSERT(divot >= divotLineStart);
+ node->setExceptionSourceCode(divot, divot - start, end - divot, divotLine, divotLineStart);
}
void incConstants() { m_scope.m_numConstants++; }
@@ -637,16 +669,16 @@ private:
}
ExpressionNode* createNumber(const JSTokenLocation& location, double d)
{
- return new (m_globalData) NumberNode(location, d);
+ return new (m_vm) NumberNode(location, d);
}
- JSGlobalData* m_globalData;
+ VM* m_vm;
SourceCode* m_sourceCode;
Scope m_scope;
- Vector<BinaryOperand, 10> m_binaryOperandStack;
- Vector<AssignmentInfo, 10> m_assignmentInfoStack;
- Vector<pair<int, int>, 10> m_binaryOperatorStack;
- Vector<pair<int, int>, 10> m_unaryTokenStack;
+ Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack;
+ Vector<AssignmentInfo, 10, UnsafeVectorOverflow> m_assignmentInfoStack;
+ Vector<pair<int, int>, 10, UnsafeVectorOverflow> m_binaryOperatorStack;
+ Vector<pair<int, PositionInfo>, 10, UnsafeVectorOverflow> m_unaryTokenStack;
int m_evalCount;
};
@@ -654,26 +686,26 @@ ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, Expr
{
if (expr->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(expr);
- return new (m_globalData) TypeOfResolveNode(location, resolve->identifier());
+ return new (m_vm) TypeOfResolveNode(location, resolve->identifier());
}
- return new (m_globalData) TypeOfValueNode(location, expr);
+ return new (m_vm) TypeOfValueNode(location, expr);
}
-ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
if (!expr->isLocation())
- return new (m_globalData) DeleteValueNode(location, expr);
+ return new (m_vm) DeleteValueNode(location, expr);
if (expr->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(expr);
- return new (m_globalData) DeleteResolveNode(location, resolve->identifier(), divot, divot - start, end - divot);
+ return new (m_vm) DeleteResolveNode(location, resolve->identifier(), divot, divot - start, end - divot, divotLine, divotLineStart);
}
if (expr->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
- return new (m_globalData) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
+ return new (m_vm) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, divot - start, end - divot, divotLine, divotLineStart);
}
ASSERT(expr->isDotAccessorNode());
DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
- return new (m_globalData) DeleteDotNode(location, dot->base(), dot->identifier(), divot, divot - start, end - divot);
+ return new (m_vm) DeleteDotNode(location, dot->base(), dot->identifier(), divot, divot - start, end - divot, divotLine, divotLineStart);
}
ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
@@ -684,14 +716,14 @@ ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, Expr
return numberNode;
}
- return new (m_globalData) NegateNode(location, n);
+ return new (m_vm) NegateNode(location, n);
}
ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
{
if (expr->isNumber())
return createNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
- return new (m_globalData) BitwiseNotNode(location, expr);
+ return new (m_vm) BitwiseNotNode(location, expr);
}
ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -703,12 +735,12 @@ ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, Expres
return createNumber(location, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
- return new (m_globalData) UnaryPlusNode(location, expr2);
+ return new (m_vm) UnaryPlusNode(location, expr2);
if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
- return new (m_globalData) UnaryPlusNode(location, expr1);
+ return new (m_vm) UnaryPlusNode(location, expr1);
- return new (m_globalData) MultNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) MultNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -718,7 +750,7 @@ ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, Express
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
- return new (m_globalData) DivNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) DivNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -728,14 +760,14 @@ ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, Express
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) ModNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) ModNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
- return new (m_globalData) AddNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) AddNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -745,80 +777,81 @@ ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, Express
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
- return new (m_globalData) SubNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) SubNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
- return new (m_globalData) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
- return new (m_globalData) RightShiftNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) RightShiftNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
- return new (m_globalData) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) BitOrNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) BitOrNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) BitAndNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) BitAndNode(location, expr1, expr2, rightHasAssignments);
}
ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) BitXOrNode(location, expr1, expr2, rightHasAssignments);
+ return new (m_vm) BitXOrNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, int start, unsigned divot, int end, unsigned divotLine, unsigned divotLineStart)
{
+ ASSERT(divot >= divotLineStart);
if (!func->isLocation())
- return new (m_globalData) FunctionCallValueNode(location, func, args, divot, divot - start, end - divot);
+ return new (m_vm) FunctionCallValueNode(location, func, args, divot, divot - start, end - divot, divotLine, divotLineStart);
if (func->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(func);
const Identifier& identifier = resolve->identifier();
- if (identifier == m_globalData->propertyNames->eval) {
+ if (identifier == m_vm->propertyNames->eval) {
usesEval();
- return new (m_globalData) EvalFunctionCallNode(location, args, divot, divot - start, end - divot);
+ return new (m_vm) EvalFunctionCallNode(location, args, divot, divot - start, end - divot, divotLine, divotLineStart);
}
- return new (m_globalData) FunctionCallResolveNode(location, identifier, args, divot, divot - start, end - divot);
+ return new (m_vm) FunctionCallResolveNode(location, identifier, args, divot, divot - start, end - divot, divotLine, divotLineStart);
}
if (func->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
- FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot);
- node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
+ FunctionCallBracketNode* node = new (m_vm) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot, divotLine, divotLineStart);
+ node->setSubexpressionInfo(bracket->divot(), bracket->divotEndOffset(), bracket->divotLine(), bracket->divotLineStart());
return node;
}
ASSERT(func->isDotAccessorNode());
DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
FunctionCallDotNode* node;
- if (dot->identifier() == m_globalData->propertyNames->call)
- node = new (m_globalData) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
- else if (dot->identifier() == m_globalData->propertyNames->apply)
- node = new (m_globalData) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
+ if (dot->identifier() == m_vm->propertyNames->call)
+ node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot, divotLine, divotLineStart);
+ else if (dot->identifier() == m_vm->propertyNames->apply)
+ node = new (m_vm) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot, divotLine, divotLineStart);
else
- node = new (m_globalData) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
- node->setSubexpressionInfo(dot->divot(), dot->endOffset());
+ node = new (m_vm) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot, divotLine, divotLineStart);
+ node->setSubexpressionInfo(dot->divot(), dot->divotEndOffset(), dot->divotLine(), dot->divotLineStart());
return node;
}
@@ -826,10 +859,10 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int
{
switch (token) {
case OR:
- return new (m_globalData) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
+ return new (m_vm) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
case AND:
- return new (m_globalData) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
+ return new (m_vm) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
case BITOR:
return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
@@ -841,38 +874,38 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int
return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case EQEQ:
- return new (m_globalData) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case NE:
- return new (m_globalData) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case STREQ:
- return new (m_globalData) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case STRNEQ:
- return new (m_globalData) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case LT:
- return new (m_globalData) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case GT:
- return new (m_globalData) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case LE:
- return new (m_globalData) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case GE:
- return new (m_globalData) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_vm) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case INSTANCEOF: {
- InstanceOfNode* node = new (m_globalData) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
- setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
+ InstanceOfNode* node = new (m_vm) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end, rhs.second.divotLine, rhs.second.divotLineStart);
return node;
}
case INTOKEN: {
- InNode* node = new (m_globalData) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
- setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
+ InNode* node = new (m_vm) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
+ setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end, rhs.second.divotLine, rhs.second.divotLineStart);
return node;
}
@@ -904,28 +937,28 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int
return 0;
}
-ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
if (!loc->isLocation())
- return new (m_globalData) AssignErrorNode(location, divot, divot - start, end - divot);
+ return new (m_vm) AssignErrorNode(location, divot, divot - start, end - divot, divotLine, divotLineStart);
if (loc->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(loc);
if (op == OpEqual) {
if (expr->isFuncExprNode())
static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier());
- AssignResolveNode* node = new (m_globalData) AssignResolveNode(location, resolve->identifier(), expr);
- setExceptionLocation(node, start, divot, end);
+ AssignResolveNode* node = new (m_vm) AssignResolveNode(location, resolve->identifier(), expr);
+ setExceptionLocation(node, start, divot, end, divotLine, divotLineStart);
return node;
}
- return new (m_globalData) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
+ return new (m_vm) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot, divotLine, divotLineStart);
}
if (loc->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
if (op == OpEqual)
- return new (m_globalData) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
- ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
- node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
+ return new (m_vm) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot(), bracket->divotLine(), bracket->divotLineStart());
+ ReadModifyBracketNode* node = new (m_vm) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot, divotLine, divotLineStart);
+ node->setSubexpressionInfo(bracket->divot(), bracket->divotEndOffset(), bracket->divotLine(), bracket->divotLineStart());
return node;
}
ASSERT(loc->isDotAccessorNode());
@@ -933,22 +966,22 @@ ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, Expr
if (op == OpEqual) {
if (expr->isFuncExprNode())
static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier());
- return new (m_globalData) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
+ return new (m_vm) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot(), dot->divotLine(), dot->divotLineStart());
}
- ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
- node->setSubexpressionInfo(dot->divot(), dot->endOffset());
+ ReadModifyDotNode* node = new (m_vm) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot, divotLine, divotLineStart);
+ node->setSubexpressionInfo(dot->divot(), dot->divotEndOffset(), dot->divotLine(), dot->divotLineStart());
return node;
}
-ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
- return new (m_globalData) PrefixNode(location, expr, op, divot, divot - start, end - divot);
+ return new (m_vm) PrefixNode(location, expr, op, divot, divot - start, end - divot, divotLine, divotLineStart);
}
-ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart)
{
- return new (m_globalData) PostfixNode(location, expr, op, divot, divot - start, end - divot);
+ return new (m_vm) PostfixNode(location, expr, op, divot, divot - start, end - divot, divotLine, divotLineStart);
}
}
diff --git a/Source/JavaScriptCore/parser/Lexer.cpp b/Source/JavaScriptCore/parser/Lexer.cpp
index 477d403c1..4925656a7 100644
--- a/Source/JavaScriptCore/parser/Lexer.cpp
+++ b/Source/JavaScriptCore/parser/Lexer.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013 Apple Inc. All Rights Reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2010 Zoltan Herczeg (zherczeg@inf.u-szeged.hu)
* Copyright (C) 2012 Mathias Bynens (mathias@qiwi.be)
@@ -46,8 +46,8 @@ using namespace Unicode;
namespace JSC {
-Keywords::Keywords(JSGlobalData* globalData)
- : m_globalData(globalData)
+Keywords::Keywords(VM* vm)
+ : m_vm(vm)
, m_keywordTable(JSC::mainTable)
{
}
@@ -489,9 +489,9 @@ static const LChar singleCharacterEscapeValuesForASCII[128] = {
};
template <typename T>
-Lexer<T>::Lexer(JSGlobalData* globalData)
+Lexer<T>::Lexer(VM* vm)
: m_isReparsing(false)
- , m_globalData(globalData)
+ , m_vm(vm)
{
}
@@ -524,7 +524,7 @@ String Lexer<T>::invalidCharacterMessage() const
}
template <typename T>
-ALWAYS_INLINE const T* Lexer<T>::currentCharacter() const
+ALWAYS_INLINE const T* Lexer<T>::currentSourcePtr() const
{
ASSERT(m_code <= m_codeEnd);
return m_code;
@@ -546,11 +546,13 @@ void Lexer<T>::setCode(const SourceCode& source, ParserArena* arena)
m_codeStart = 0;
m_source = &source;
- m_code = m_codeStart + source.startOffset();
+ m_sourceOffset = source.startOffset();
+ m_codeStartPlusOffset = m_codeStart + source.startOffset();
+ m_code = m_codeStartPlusOffset;
m_codeEnd = m_codeStart + source.endOffset();
m_error = false;
m_atLineStart = true;
- m_columnNumber = 0;
+ m_lineStart = m_code;
m_lexErrorMessage = String();
m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
@@ -567,7 +569,7 @@ template <typename T>
template <int shiftAmount> ALWAYS_INLINE void Lexer<T>::internalShift()
{
m_code += shiftAmount;
- m_columnNumber += shiftAmount;
+ ASSERT(currentOffset() >= currentLineStartOffset());
m_current = *m_code;
}
@@ -579,7 +581,6 @@ ALWAYS_INLINE void Lexer<T>::shift()
++m_code;
if (LIKELY(m_code < m_codeEnd))
m_current = *m_code;
- ++m_columnNumber;
}
template <typename T>
@@ -598,21 +599,21 @@ ALWAYS_INLINE T Lexer<T>::peek(int offset) const
}
template <typename T>
-int Lexer<T>::parseFourDigitUnicodeHex()
+typename Lexer<T>::UnicodeHexValue Lexer<T>::parseFourDigitUnicodeHex()
{
T char1 = peek(1);
T char2 = peek(2);
T char3 = peek(3);
if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(char1) || !isASCIIHexDigit(char2) || !isASCIIHexDigit(char3)))
- return -1;
+ return UnicodeHexValue((m_code + 4) >= m_codeEnd ? UnicodeHexValue::IncompleteHex : UnicodeHexValue::InvalidHex);
int result = convertUnicode(m_current, char1, char2, char3);
shift();
shift();
shift();
shift();
- return result;
+ return UnicodeHexValue(result);
}
template <typename T>
@@ -768,20 +769,21 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::p
}
}
- const LChar* identifierStart = currentCharacter();
+ const LChar* identifierStart = currentSourcePtr();
+ unsigned identifierLineStart = currentLineStartOffset();
while (isIdentPart(m_current))
shift();
if (UNLIKELY(m_current == '\\')) {
- setOffsetFromCharOffset(identifierStart);
+ setOffsetFromSourcePtr(identifierStart, identifierLineStart);
return parseIdentifierSlowCase<shouldCreateIdentifier>(tokenData, lexerFlags, strictMode);
}
const Identifier* ident = 0;
if (shouldCreateIdentifier) {
- int identifierLength = currentCharacter() - identifierStart;
+ int identifierLength = currentSourcePtr() - identifierStart;
ident = makeIdentifier(identifierStart, identifierLength);
tokenData->ident = ident;
@@ -791,7 +793,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::p
if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords))) {
ASSERT(shouldCreateIdentifier);
if (remaining < maxTokenLength) {
- const HashEntry* entry = m_globalData->keywords->getKeyword(*ident);
+ const HashEntry* entry = m_vm->keywords->getKeyword(*ident);
ASSERT((remaining < maxTokenLength) || !entry);
if (!entry)
return IDENT;
@@ -816,7 +818,8 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
}
}
- const UChar* identifierStart = currentCharacter();
+ const UChar* identifierStart = currentSourcePtr();
+ int identifierLineStart = currentLineStartOffset();
UChar orAllChars = 0;
@@ -826,7 +829,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
}
if (UNLIKELY(m_current == '\\')) {
- setOffsetFromCharOffset(identifierStart);
+ setOffsetFromSourcePtr(identifierStart, identifierLineStart);
return parseIdentifierSlowCase<shouldCreateIdentifier>(tokenData, lexerFlags, strictMode);
}
@@ -838,7 +841,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
const Identifier* ident = 0;
if (shouldCreateIdentifier) {
- int identifierLength = currentCharacter() - identifierStart;
+ int identifierLength = currentSourcePtr() - identifierStart;
if (isAll8Bit)
ident = makeIdentifierLCharFromUChar(identifierStart, identifierLength);
else
@@ -851,7 +854,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords))) {
ASSERT(shouldCreateIdentifier);
if (remaining < maxTokenLength) {
- const HashEntry* entry = m_globalData->keywords->getKeyword(*ident);
+ const HashEntry* entry = m_vm->keywords->getKeyword(*ident);
ASSERT((remaining < maxTokenLength) || !entry);
if (!entry)
return IDENT;
@@ -868,7 +871,7 @@ template <typename T>
template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlowCase(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
{
const ptrdiff_t remaining = m_codeEnd - m_code;
- const T* identifierStart = currentCharacter();
+ const T* identifierStart = currentSourcePtr();
bool bufferRequired = false;
while (true) {
@@ -881,32 +884,32 @@ template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlow
// \uXXXX unicode characters.
bufferRequired = true;
- if (identifierStart != currentCharacter())
- m_buffer16.append(identifierStart, currentCharacter() - identifierStart);
+ if (identifierStart != currentSourcePtr())
+ m_buffer16.append(identifierStart, currentSourcePtr() - identifierStart);
shift();
if (UNLIKELY(m_current != 'u'))
- return ERRORTOK;
+ return atEnd() ? UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK : INVALID_IDENTIFIER_ESCAPE_ERRORTOK;
shift();
- int character = parseFourDigitUnicodeHex();
- if (UNLIKELY(character == -1))
- return ERRORTOK;
- UChar ucharacter = static_cast<UChar>(character);
+ UnicodeHexValue character = parseFourDigitUnicodeHex();
+ if (UNLIKELY(!character.isValid()))
+ return character.valueType() == UnicodeHexValue::IncompleteHex ? UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK : INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK;
+ UChar ucharacter = static_cast<UChar>(character.value());
if (UNLIKELY(m_buffer16.size() ? !isIdentPart(ucharacter) : !isIdentStart(ucharacter)))
- return ERRORTOK;
+ return INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK;
if (shouldCreateIdentifier)
record16(ucharacter);
- identifierStart = currentCharacter();
+ identifierStart = currentSourcePtr();
}
int identifierLength;
const Identifier* ident = 0;
if (shouldCreateIdentifier) {
if (!bufferRequired) {
- identifierLength = currentCharacter() - identifierStart;
+ identifierLength = currentSourcePtr() - identifierStart;
ident = makeIdentifier(identifierStart, identifierLength);
} else {
- if (identifierStart != currentCharacter())
- m_buffer16.append(identifierStart, currentCharacter() - identifierStart);
+ if (identifierStart != currentSourcePtr())
+ m_buffer16.append(identifierStart, currentSourcePtr() - identifierStart);
ident = makeIdentifier(m_buffer16.data(), m_buffer16.size());
}
@@ -918,7 +921,7 @@ template <bool shouldCreateIdentifier> JSTokenType Lexer<T>::parseIdentifierSlow
ASSERT(shouldCreateIdentifier);
// Keywords must not be recognized if there was an \uXXXX in the identifier.
if (remaining < maxTokenLength) {
- const HashEntry* entry = m_globalData->keywords->getKeyword(*ident);
+ const HashEntry* entry = m_vm->keywords->getKeyword(*ident);
ASSERT((remaining < maxTokenLength) || !entry);
if (!entry)
return IDENT;
@@ -943,19 +946,20 @@ static ALWAYS_INLINE bool characterRequiresParseStringSlowCase(UChar character)
}
template <typename T>
-template <bool shouldBuildStrings> ALWAYS_INLINE bool Lexer<T>::parseString(JSTokenData* tokenData, bool strictMode)
+template <bool shouldBuildStrings> ALWAYS_INLINE typename Lexer<T>::StringParseResult Lexer<T>::parseString(JSTokenData* tokenData, bool strictMode)
{
int startingOffset = currentOffset();
+ int startingLineStartOffset = currentLineStartOffset();
int startingLineNumber = lineNumber();
T stringQuoteCharacter = m_current;
shift();
- const T* stringStart = currentCharacter();
+ const T* stringStart = currentSourcePtr();
while (m_current != stringQuoteCharacter) {
if (UNLIKELY(m_current == '\\')) {
- if (stringStart != currentCharacter() && shouldBuildStrings)
- append8(stringStart, currentCharacter() - stringStart);
+ if (stringStart != currentSourcePtr() && shouldBuildStrings)
+ append8(stringStart, currentSourcePtr() - stringStart);
shift();
LChar escape = singleEscape(m_current);
@@ -971,7 +975,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE bool Lexer<T>::parseString(JSTo
shift();
if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
m_lexErrorMessage = "\\x can only be followed by a hex character sequence";
- return false;
+ return (atEnd() || (isASCIIHexDigit(m_current) && (m_code + 1 == m_codeEnd))) ? StringUnterminated : StringCannotBeParsed;
}
T prev = m_current;
shift();
@@ -979,17 +983,17 @@ template <bool shouldBuildStrings> ALWAYS_INLINE bool Lexer<T>::parseString(JSTo
record8(convertHex(prev, m_current));
shift();
} else {
- setOffset(startingOffset);
+ setOffset(startingOffset, startingLineStartOffset);
setLineNumber(startingLineNumber);
m_buffer8.resize(0);
return parseStringSlowCase<shouldBuildStrings>(tokenData, strictMode);
}
- stringStart = currentCharacter();
+ stringStart = currentSourcePtr();
continue;
}
if (UNLIKELY(characterRequiresParseStringSlowCase(m_current))) {
- setOffset(startingOffset);
+ setOffset(startingOffset, startingLineStartOffset);
setLineNumber(startingLineNumber);
m_buffer8.resize(0);
return parseStringSlowCase<shouldBuildStrings>(tokenData, strictMode);
@@ -998,29 +1002,29 @@ template <bool shouldBuildStrings> ALWAYS_INLINE bool Lexer<T>::parseString(JSTo
shift();
}
- if (currentCharacter() != stringStart && shouldBuildStrings)
- append8(stringStart, currentCharacter() - stringStart);
+ if (currentSourcePtr() != stringStart && shouldBuildStrings)
+ append8(stringStart, currentSourcePtr() - stringStart);
if (shouldBuildStrings) {
tokenData->ident = makeIdentifier(m_buffer8.data(), m_buffer8.size());
m_buffer8.resize(0);
} else
tokenData->ident = 0;
- return true;
+ return StringParsedSuccessfully;
}
template <typename T>
-template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenData* tokenData, bool strictMode)
+template <bool shouldBuildStrings> typename Lexer<T>::StringParseResult Lexer<T>::parseStringSlowCase(JSTokenData* tokenData, bool strictMode)
{
T stringQuoteCharacter = m_current;
shift();
- const T* stringStart = currentCharacter();
+ const T* stringStart = currentSourcePtr();
while (m_current != stringQuoteCharacter) {
if (UNLIKELY(m_current == '\\')) {
- if (stringStart != currentCharacter() && shouldBuildStrings)
- append16(stringStart, currentCharacter() - stringStart);
+ if (stringStart != currentSourcePtr() && shouldBuildStrings)
+ append16(stringStart, currentSourcePtr() - stringStart);
shift();
LChar escape = singleEscape(m_current);
@@ -1036,7 +1040,7 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
shift();
if (!isASCIIHexDigit(m_current) || !isASCIIHexDigit(peek(1))) {
m_lexErrorMessage = "\\x can only be followed by a hex character sequence";
- return false;
+ return StringCannotBeParsed;
}
T prev = m_current;
shift();
@@ -1045,16 +1049,16 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
shift();
} else if (m_current == 'u') {
shift();
- int character = parseFourDigitUnicodeHex();
- if (character != -1) {
+ UnicodeHexValue character = parseFourDigitUnicodeHex();
+ if (character.isValid()) {
if (shouldBuildStrings)
- record16(character);
+ record16(character.value());
} else if (m_current == stringQuoteCharacter) {
if (shouldBuildStrings)
record16('u');
} else {
m_lexErrorMessage = "\\u can only be followed by a Unicode character sequence";
- return false;
+ return character.valueType() == UnicodeHexValue::IncompleteHex ? StringUnterminated : StringCannotBeParsed;
}
} else if (strictMode && isASCIIDigit(m_current)) {
// The only valid numeric escape in strict mode is '\0', and this must not be followed by a decimal digit.
@@ -1062,7 +1066,7 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
shift();
if (character1 != '0' || isASCIIDigit(m_current)) {
m_lexErrorMessage = "The only valid numeric escape in strict mode is '\\0'";
- return false;
+ return StringCannotBeParsed;
}
if (shouldBuildStrings)
record16(0);
@@ -1092,10 +1096,10 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
shift();
} else {
m_lexErrorMessage = "Unterminated string constant";
- return false;
+ return StringUnterminated;
}
- stringStart = currentCharacter();
+ stringStart = currentSourcePtr();
continue;
}
// Fast check for characters that require special handling.
@@ -1105,22 +1109,22 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
// New-line or end of input is not allowed
if (atEnd() || isLineTerminator(m_current)) {
m_lexErrorMessage = "Unexpected EOF";
- return false;
+ return atEnd() ? StringUnterminated : StringCannotBeParsed;
}
// Anything else is just a normal character
}
shift();
}
- if (currentCharacter() != stringStart && shouldBuildStrings)
- append16(stringStart, currentCharacter() - stringStart);
+ if (currentSourcePtr() != stringStart && shouldBuildStrings)
+ append16(stringStart, currentSourcePtr() - stringStart);
if (shouldBuildStrings)
tokenData->ident = makeIdentifier(m_buffer16.data(), m_buffer16.size());
else
tokenData->ident = 0;
m_buffer16.resize(0);
- return true;
+ return StringParsedSuccessfully;
}
template <typename T>
@@ -1319,7 +1323,7 @@ start:
return EOFTOK;
tokenLocation->startOffset = currentOffset();
- tokenLocation->column = m_columnNumber;
+ ASSERT(currentOffset() >= currentLineStartOffset());
CharacterType type;
if (LIKELY(isLatin1(m_current)))
@@ -1464,6 +1468,7 @@ start:
if (parseMultilineComment())
goto start;
m_lexErrorMessage = "Multiline comment was not closed properly";
+ token = UNTERMINATED_MULTILINE_COMMENT_ERRORTOK;
goto returnError;
}
if (m_current == '=') {
@@ -1556,12 +1561,18 @@ start:
token = SEMICOLON;
break;
case CharacterOpenBrace:
- tokenData->intValue = currentOffset();
+ tokenData->line = lineNumber();
+ tokenData->offset = currentOffset();
+ tokenData->lineStartOffset = currentLineStartOffset();
+ ASSERT(tokenData->offset >= tokenData->lineStartOffset);
shift();
token = OPENBRACE;
break;
case CharacterCloseBrace:
- tokenData->intValue = currentOffset();
+ tokenData->line = lineNumber();
+ tokenData->offset = currentOffset();
+ tokenData->lineStartOffset = currentLineStartOffset();
+ ASSERT(tokenData->offset >= tokenData->lineStartOffset);
shift();
token = CLOSEBRACE;
break;
@@ -1583,6 +1594,7 @@ start:
if (parseOctal(tokenData->doubleValue)) {
if (strictMode) {
m_lexErrorMessage = "Octal escapes are forbidden in strict mode";
+ token = INVALID_OCTAL_NUMBER_ERRORTOK;
goto returnError;
}
token = NUMBER;
@@ -1601,6 +1613,7 @@ inNumberAfterDecimalPoint:
if ((m_current | 0x20) == 'e') {
if (!parseNumberAfterExponentIndicator()) {
m_lexErrorMessage = "Non-number found after exponent indicator";
+ token = atEnd() ? UNTERMINATED_NUMERIC_LITERAL_ERRORTOK : INVALID_NUMERIC_LITERAL_ERRORTOK;
goto returnError;
}
}
@@ -1613,17 +1626,24 @@ inNumberAfterDecimalPoint:
// No identifiers allowed directly after numeric literal, e.g. "3in" is bad.
if (UNLIKELY(isIdentStart(m_current))) {
m_lexErrorMessage = "At least one digit must occur after a decimal point";
+ token = atEnd() ? UNTERMINATED_NUMERIC_LITERAL_ERRORTOK : INVALID_NUMERIC_LITERAL_ERRORTOK;
goto returnError;
}
m_buffer8.resize(0);
break;
case CharacterQuote:
if (lexerFlags & LexerFlagsDontBuildStrings) {
- if (UNLIKELY(!parseString<false>(tokenData, strictMode)))
+ StringParseResult result = parseString<false>(tokenData, strictMode);
+ if (UNLIKELY(result != StringParsedSuccessfully)) {
+ token = result == StringUnterminated ? UNTERMINATED_STRING_LITERAL_ERRORTOK : INVALID_STRING_LITERAL_ERRORTOK;
goto returnError;
+ }
} else {
- if (UNLIKELY(!parseString<true>(tokenData, strictMode)))
+ StringParseResult result = parseString<true>(tokenData, strictMode);
+ if (UNLIKELY(result != StringParsedSuccessfully)) {
+ token = result == StringUnterminated ? UNTERMINATED_STRING_LITERAL_ERRORTOK : INVALID_STRING_LITERAL_ERRORTOK;
goto returnError;
+ }
}
shift();
token = STRING;
@@ -1642,14 +1662,16 @@ inNumberAfterDecimalPoint:
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
- m_columnNumber = 0;
+ m_lineStart = m_code;
goto start;
case CharacterInvalid:
m_lexErrorMessage = invalidCharacterMessage();
+ token = ERRORTOK;
goto returnError;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
m_lexErrorMessage = "Internal Error";
+ token = ERRORTOK;
goto returnError;
}
@@ -1665,7 +1687,7 @@ inSingleLineComment:
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
- m_columnNumber = 0;
+ m_lineStart = m_code;
if (!lastTokenWasRestrKeyword())
goto start;
@@ -1675,6 +1697,8 @@ inSingleLineComment:
returnToken:
tokenLocation->line = m_lineNumber;
tokenLocation->endOffset = currentOffset();
+ tokenLocation->lineStartOffset = currentLineStartOffset();
+ ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
m_lastToken = token;
return token;
@@ -1682,7 +1706,10 @@ returnError:
m_error = true;
tokenLocation->line = m_lineNumber;
tokenLocation->endOffset = currentOffset();
- return ERRORTOK;
+ tokenLocation->lineStartOffset = currentLineStartOffset();
+ ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
+ RELEASE_ASSERT(token & ErrorTokenFlag);
+ return token;
}
template <typename T>
@@ -1820,11 +1847,11 @@ void Lexer<T>::clear()
}
template <typename T>
-SourceCode Lexer<T>::sourceCode(int openBrace, int closeBrace, int firstLine)
+SourceCode Lexer<T>::sourceCode(int openBrace, int closeBrace, int firstLine, unsigned startColumn)
{
ASSERT(m_source->provider()->source()[openBrace] == '{');
ASSERT(m_source->provider()->source()[closeBrace] == '}');
- return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine);
+ return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine, startColumn);
}
// Instantiate the two flavors of Lexer we need instead of putting most of this file in Lexer.h
diff --git a/Source/JavaScriptCore/parser/Lexer.h b/Source/JavaScriptCore/parser/Lexer.h
index 78c8c8cbd..5ecdcc650 100644
--- a/Source/JavaScriptCore/parser/Lexer.h
+++ b/Source/JavaScriptCore/parser/Lexer.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 Zoltan Herczeg (zherczeg@inf.u-szeged.hu)
*
* This library is free software; you can redistribute it and/or
@@ -28,7 +28,6 @@
#include "ParserTokens.h"
#include "SourceCode.h"
#include <wtf/ASCIICType.h>
-#include <wtf/AlwaysInline.h>
#include <wtf/SegmentedVector.h>
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
@@ -39,12 +38,12 @@ class Keywords {
public:
bool isKeyword(const Identifier& ident) const
{
- return m_keywordTable.entry(m_globalData, ident);
+ return m_keywordTable.entry(m_vm, ident);
}
const HashEntry* getKeyword(const Identifier& ident) const
{
- return m_keywordTable.entry(m_globalData, ident);
+ return m_keywordTable.entry(m_vm, ident);
}
~Keywords()
@@ -53,11 +52,11 @@ public:
}
private:
- friend class JSGlobalData;
+ friend class VM;
- Keywords(JSGlobalData*);
+ Keywords(VM*);
- JSGlobalData* m_globalData;
+ VM* m_vm;
const HashTable m_keywordTable;
};
@@ -73,7 +72,7 @@ class Lexer {
WTF_MAKE_FAST_ALLOCATED;
public:
- Lexer(JSGlobalData*);
+ Lexer(VM*);
~Lexer();
// Character manipulation functions.
@@ -90,11 +89,12 @@ public:
JSTokenType lex(JSTokenData*, JSTokenLocation*, unsigned, bool strictMode);
bool nextTokenIsColon();
int lineNumber() const { return m_lineNumber; }
- int currentColumnNumber() const { return m_columnNumber; }
+ ALWAYS_INLINE int currentOffset() const { return offsetFromSourcePtr(m_code); }
+ ALWAYS_INLINE int currentLineStartOffset() const { return offsetFromSourcePtr(m_lineStart); }
void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
int lastLineNumber() const { return m_lastLineNumber; }
bool prevTerminator() const { return m_terminator; }
- SourceCode sourceCode(int openBrace, int closeBrace, int firstLine);
+ SourceCode sourceCode(int openBrace, int closeBrace, int firstLine, unsigned startColumn);
bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0);
bool skipRegExp();
@@ -102,11 +102,15 @@ public:
bool sawError() const { return m_error; }
String getErrorMessage() const { return m_lexErrorMessage; }
void clear();
- void setOffset(int offset)
+ void setOffset(int offset, int lineStartOffset)
{
m_error = 0;
m_lexErrorMessage = String();
- m_code = m_codeStart + offset;
+
+ m_code = sourcePtrFromOffset(offset);
+ m_lineStart = sourcePtrFromOffset(lineStartOffset);
+ ASSERT(currentOffset() >= currentLineStartOffset());
+
m_buffer8.resize(0);
m_buffer16.resize(0);
if (LIKELY(m_code < m_codeEnd))
@@ -134,13 +138,44 @@ private:
ALWAYS_INLINE void shift();
ALWAYS_INLINE bool atEnd() const;
ALWAYS_INLINE T peek(int offset) const;
- int parseFourDigitUnicodeHex();
+ struct UnicodeHexValue {
+
+ enum ValueType { ValidHex, IncompleteHex, InvalidHex };
+
+ explicit UnicodeHexValue(int value)
+ : m_value(value)
+ {
+ }
+ explicit UnicodeHexValue(ValueType type)
+ : m_value(type == IncompleteHex ? -2 : -1)
+ {
+ }
+
+ ValueType valueType() const
+ {
+ if (m_value >= 0)
+ return ValidHex;
+ return m_value == -2 ? IncompleteHex : InvalidHex;
+ }
+ bool isValid() const { return m_value >= 0; }
+ int value() const
+ {
+ ASSERT(m_value >= 0);
+ return m_value;
+ }
+
+ private:
+ int m_value;
+ };
+ UnicodeHexValue parseFourDigitUnicodeHex();
void shiftLineTerminator();
+ ALWAYS_INLINE int offsetFromSourcePtr(const T* ptr) const { return ptr - m_codeStart; }
+ ALWAYS_INLINE const T* sourcePtrFromOffset(int offset) const { return m_codeStart + offset; }
+
String invalidCharacterMessage() const;
- ALWAYS_INLINE const T* currentCharacter() const;
- ALWAYS_INLINE int currentOffset() const { return m_code - m_codeStart; }
- ALWAYS_INLINE void setOffsetFromCharOffset(const T* charOffset) { setOffset(charOffset - m_codeStart); }
+ ALWAYS_INLINE const T* currentSourcePtr() const;
+ ALWAYS_INLINE void setOffsetFromSourcePtr(const T* sourcePtr, unsigned lineStartOffset) { setOffset(offsetFromSourcePtr(sourcePtr), lineStartOffset); }
ALWAYS_INLINE void setCodeStart(const StringImpl*);
@@ -157,8 +192,13 @@ private:
template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType parseKeyword(JSTokenData*);
template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned lexerFlags, bool strictMode);
template <bool shouldBuildIdentifiers> NEVER_INLINE JSTokenType parseIdentifierSlowCase(JSTokenData*, unsigned lexerFlags, bool strictMode);
- template <bool shouldBuildStrings> ALWAYS_INLINE bool parseString(JSTokenData*, bool strictMode);
- template <bool shouldBuildStrings> NEVER_INLINE bool parseStringSlowCase(JSTokenData*, bool strictMode);
+ enum StringParseResult {
+ StringParsedSuccessfully,
+ StringUnterminated,
+ StringCannotBeParsed
+ };
+ template <bool shouldBuildStrings> ALWAYS_INLINE StringParseResult parseString(JSTokenData*, bool strictMode);
+ template <bool shouldBuildStrings> NEVER_INLINE StringParseResult parseStringSlowCase(JSTokenData*, bool strictMode);
ALWAYS_INLINE void parseHex(double& returnValue);
ALWAYS_INLINE bool parseOctal(double& returnValue);
ALWAYS_INLINE bool parseDecimal(double& returnValue);
@@ -170,7 +210,6 @@ private:
int m_lineNumber;
int m_lastLineNumber;
- int m_columnNumber;
Vector<LChar> m_buffer8;
Vector<UChar> m_buffer16;
@@ -178,9 +217,12 @@ private:
int m_lastToken;
const SourceCode* m_source;
+ unsigned m_sourceOffset;
const T* m_code;
const T* m_codeStart;
const T* m_codeEnd;
+ const T* m_codeStartPlusOffset;
+ const T* m_lineStart;
bool m_isReparsing;
bool m_atLineStart;
bool m_error;
@@ -190,7 +232,7 @@ private:
IdentifierArena* m_arena;
- JSGlobalData* m_globalData;
+ VM* m_vm;
};
template <>
@@ -232,28 +274,28 @@ inline UChar Lexer<T>::convertUnicode(int c1, int c2, int c3, int c4)
template <typename T>
ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifier(const LChar* characters, size_t length)
{
- return &m_arena->makeIdentifier(m_globalData, characters, length);
+ return &m_arena->makeIdentifier(m_vm, characters, length);
}
template <typename T>
ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifier(const UChar* characters, size_t length)
{
- return &m_arena->makeIdentifier(m_globalData, characters, length);
+ return &m_arena->makeIdentifier(m_vm, characters, length);
}
template <>
ALWAYS_INLINE const Identifier* Lexer<LChar>::makeRightSizedIdentifier(const UChar* characters, size_t length, UChar)
{
- return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length);
+ return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length);
}
template <>
ALWAYS_INLINE const Identifier* Lexer<UChar>::makeRightSizedIdentifier(const UChar* characters, size_t length, UChar orAllChars)
{
if (!(orAllChars & ~0xff))
- return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length);
+ return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length);
- return &m_arena->makeIdentifier(m_globalData, characters, length);
+ return &m_arena->makeIdentifier(m_vm, characters, length);
}
template <>
@@ -273,19 +315,19 @@ ALWAYS_INLINE void Lexer<UChar>::setCodeStart(const StringImpl* sourceString)
template <typename T>
ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifierLCharFromUChar(const UChar* characters, size_t length)
{
- return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length);
+ return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length);
}
template <typename T>
ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const LChar* characters, size_t length)
{
- return &m_arena->makeIdentifier(m_globalData, characters, length);
+ return &m_arena->makeIdentifier(m_vm, characters, length);
}
template <typename T>
ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const UChar* characters, size_t length)
{
- return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length);
+ return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length);
}
template <typename T>
@@ -317,7 +359,7 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData,
m_current = 0;
m_code = ptr;
- m_columnNumber = m_columnNumber + (m_code - start);
+ ASSERT(currentOffset() >= currentLineStartOffset());
// Create the identifier if needed
if (lexerFlags & LexexFlagsDontBuildKeywords)
@@ -325,9 +367,10 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData,
else
tokenData->ident = makeLCharIdentifier(start, ptr - start);
tokenLocation->line = m_lineNumber;
- tokenLocation->startOffset = start - m_codeStart;
+ tokenLocation->lineStartOffset = currentLineStartOffset();
+ tokenLocation->startOffset = offsetFromSourcePtr(start);
tokenLocation->endOffset = currentOffset();
- tokenLocation->column = m_columnNumber;
+ ASSERT(tokenLocation->startOffset >= tokenLocation->lineStartOffset);
m_lastToken = IDENT;
return IDENT;
diff --git a/Source/JavaScriptCore/parser/NodeConstructors.h b/Source/JavaScriptCore/parser/NodeConstructors.h
index 274491960..47f6eea09 100644
--- a/Source/JavaScriptCore/parser/NodeConstructors.h
+++ b/Source/JavaScriptCore/parser/NodeConstructors.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,25 +27,27 @@
namespace JSC {
- inline void* ParserArenaFreeable::operator new(size_t size, JSGlobalData* globalData)
+ inline void* ParserArenaFreeable::operator new(size_t size, VM* vm)
{
- return globalData->parserArena->allocateFreeable(size);
+ return vm->parserArena->allocateFreeable(size);
}
- inline void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData)
+ inline void* ParserArenaDeletable::operator new(size_t size, VM* vm)
{
- return globalData->parserArena->allocateDeletable(size);
+ return vm->parserArena->allocateDeletable(size);
}
- inline ParserArenaRefCounted::ParserArenaRefCounted(JSGlobalData* globalData)
+ inline ParserArenaRefCounted::ParserArenaRefCounted(VM* vm)
{
- globalData->parserArena->derefWithArena(adoptRef(this));
+ vm->parserArena->derefWithArena(adoptRef(this));
}
inline Node::Node(const JSTokenLocation& location)
: m_lineNumber(location.line)
- , m_columnNumber(location.column)
+ , m_startOffset(location.startOffset)
+ , m_lineStartOffset(location.lineStartOffset)
{
+ ASSERT(location.startOffset >= location.lineStartOffset);
}
inline ExpressionNode::ExpressionNode(const JSTokenLocation& location, ResultType resultType)
@@ -60,25 +62,30 @@ namespace JSC {
{
}
+ inline ConstantNode::ConstantNode(const JSTokenLocation& location, ResultType resultType)
+ : ExpressionNode(location, resultType)
+ {
+ }
+
inline NullNode::NullNode(const JSTokenLocation& location)
- : ExpressionNode(location, ResultType::nullType())
+ : ConstantNode(location, ResultType::nullType())
{
}
inline BooleanNode::BooleanNode(const JSTokenLocation& location, bool value)
- : ExpressionNode(location, ResultType::booleanType())
+ : ConstantNode(location, ResultType::booleanType())
, m_value(value)
{
}
inline NumberNode::NumberNode(const JSTokenLocation& location, double value)
- : ExpressionNode(location, ResultType::numberType())
+ : ConstantNode(location, JSValue(value).isInt32() ? ResultType::numberTypeIsInt32() : ResultType::numberType())
, m_value(value)
{
}
inline StringNode::StringNode(const JSTokenLocation& location, const Identifier& value)
- : ExpressionNode(location, ResultType::stringType())
+ : ConstantNode(location, ResultType::stringType())
, m_value(value)
{
}
@@ -95,11 +102,14 @@ namespace JSC {
{
}
- inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, int startOffset)
+inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned startOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
, m_ident(ident)
, m_startOffset(startOffset)
+ , m_divotLine(divotLine)
+ , m_divotLineStart(divotLineStart)
{
+ ASSERT(m_startOffset >= m_divotLineStart);
}
inline ElementNode::ElementNode(int elision, ExpressionNode* node)
@@ -141,29 +151,29 @@ namespace JSC {
{
}
- inline PropertyNode::PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* assign, Type type)
+ inline PropertyNode::PropertyNode(VM*, const Identifier& name, ExpressionNode* assign, Type type)
: m_name(name)
, m_assign(assign)
, m_type(type)
{
}
- inline PropertyNode::PropertyNode(JSGlobalData* globalData, double name, ExpressionNode* assign, Type type)
- : m_name(globalData->parserArena->identifierArena().makeNumericIdentifier(globalData, name))
+ inline PropertyNode::PropertyNode(VM* vm, double name, ExpressionNode* assign, Type type)
+ : m_name(vm->parserArena->identifierArena().makeNumericIdentifier(vm, name))
, m_assign(assign)
, m_type(type)
{
}
inline PropertyListNode::PropertyListNode(const JSTokenLocation& location, PropertyNode* node)
- : Node(location)
+ : ExpressionNode(location)
, m_node(node)
, m_next(0)
{
}
inline PropertyListNode::PropertyListNode(const JSTokenLocation& location, PropertyNode* node, PropertyListNode* list)
- : Node(location)
+ : ExpressionNode(location)
, m_node(node)
, m_next(0)
{
@@ -198,14 +208,14 @@ namespace JSC {
}
inline ArgumentListNode::ArgumentListNode(const JSTokenLocation& location, ExpressionNode* expr)
- : Node(location)
+ : ExpressionNode(location)
, m_next(0)
, m_expr(expr)
{
}
inline ArgumentListNode::ArgumentListNode(const JSTokenLocation& location, ArgumentListNode* listNode, ExpressionNode* expr)
- : Node(location)
+ : ExpressionNode(location)
, m_next(0)
, m_expr(expr)
{
@@ -236,83 +246,81 @@ namespace JSC {
{
}
- inline EvalFunctionCallNode::EvalFunctionCallNode(const JSTokenLocation& location, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline EvalFunctionCallNode::EvalFunctionCallNode(const JSTokenLocation& location, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_args(args)
{
+ ASSERT(divot >= divotLineStart);
}
- inline FunctionCallValueNode::FunctionCallValueNode(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline FunctionCallValueNode::FunctionCallValueNode(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_expr(expr)
, m_args(args)
{
}
- inline FunctionCallResolveNode::FunctionCallResolveNode(const JSTokenLocation& location, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline FunctionCallResolveNode::FunctionCallResolveNode(const JSTokenLocation& location, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_ident(ident)
, m_args(args)
{
}
- inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
+ , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_subscript(subscript)
, m_args(args)
{
}
- inline FunctionCallDotNode::FunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline FunctionCallDotNode::FunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
+ , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_ident(ident)
, m_args(args)
{
}
- inline CallFunctionCallDotNode::CallFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset)
+ inline CallFunctionCallDotNode::CallFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset, divotLine, divotLineStart)
{
}
- inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset)
+ inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset, divotLine, divotLineStart)
{
}
- inline PostfixNode::PostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
- , m_expr(expr)
- , m_operator(oper)
+ inline PostfixNode::PostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : PrefixNode(location, expr, oper, divot, startOffset, endOffset, divotLine, divotLineStart)
{
}
- inline DeleteResolveNode::DeleteResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline DeleteResolveNode::DeleteResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_ident(ident)
{
}
- inline DeleteBracketNode::DeleteBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline DeleteBracketNode::DeleteBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_subscript(subscript)
{
}
- inline DeleteDotNode::DeleteDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline DeleteDotNode::DeleteDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_ident(ident)
{
@@ -342,9 +350,9 @@ namespace JSC {
{
}
- inline PrefixNode::PrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline PrefixNode::PrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
+ , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_expr(expr)
, m_operator(oper)
{
@@ -358,7 +366,7 @@ namespace JSC {
}
inline UnaryPlusNode::UnaryPlusNode(const JSTokenLocation& location, ExpressionNode* expr)
- : UnaryOpNode(location, ResultType::numberType(), expr, op_to_jsnumber)
+ : UnaryOpNode(location, ResultType::numberType(), expr, op_to_number)
{
}
@@ -528,14 +536,16 @@ namespace JSC {
{
}
- inline ReadModifyResolveNode::ReadModifyResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline ReadModifyResolveNode::ReadModifyResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_ident(ident)
, m_right(right)
, m_operator(oper)
, m_rightHasAssignments(rightHasAssignments)
{
+ ASSERT(divot >= divotLineStart);
+ ASSERT(divot - startOffset >= divotLineStart);
}
inline AssignResolveNode::AssignResolveNode(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* right)
@@ -545,9 +555,9 @@ namespace JSC {
{
}
- inline ReadModifyBracketNode::ReadModifyBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline ReadModifyBracketNode::ReadModifyBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
+ , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_subscript(subscript)
, m_right(right)
@@ -557,9 +567,9 @@ namespace JSC {
{
}
- inline AssignBracketNode::AssignBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline AssignBracketNode::AssignBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_subscript(subscript)
, m_right(right)
@@ -568,9 +578,9 @@ namespace JSC {
{
}
- inline AssignDotNode::AssignDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline AssignDotNode::AssignDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_ident(ident)
, m_right(right)
@@ -578,9 +588,9 @@ namespace JSC {
{
}
- inline ReadModifyDotNode::ReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline ReadModifyDotNode::ReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableSubExpressionData(divot, startOffset, endOffset)
+ , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_base(base)
, m_ident(ident)
, m_right(right)
@@ -589,9 +599,9 @@ namespace JSC {
{
}
- inline AssignErrorNode::AssignErrorNode(const JSTokenLocation& location, unsigned divot, unsigned startOffset, unsigned endOffset)
+ inline AssignErrorNode::AssignErrorNode(const JSTokenLocation& location, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: ExpressionNode(location)
- , ThrowableExpressionData(divot, startOffset, endOffset)
+ , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
{
}
@@ -634,15 +644,10 @@ namespace JSC {
{
}
- inline IfNode::IfNode(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* ifBlock)
+ inline IfElseNode::IfElseNode(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock)
: StatementNode(location)
, m_condition(condition)
, m_ifBlock(ifBlock)
- {
- }
-
- inline IfElseNode::IfElseNode(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock)
- : IfNode(location, condition, ifBlock)
, m_elseBlock(elseBlock)
{
}
@@ -671,9 +676,9 @@ namespace JSC {
ASSERT(statement);
}
- inline ContinueNode::ContinueNode(JSGlobalData* globalData, const JSTokenLocation& location)
+ inline ContinueNode::ContinueNode(VM* vm, const JSTokenLocation& location)
: StatementNode(location)
- , m_ident(globalData->propertyNames->nullIdentifier)
+ , m_ident(vm->propertyNames->nullIdentifier)
{
}
@@ -683,9 +688,9 @@ namespace JSC {
{
}
- inline BreakNode::BreakNode(JSGlobalData* globalData, const JSTokenLocation& location)
+ inline BreakNode::BreakNode(VM* vm, const JSTokenLocation& location)
: StatementNode(location)
- , m_ident(globalData->propertyNames->nullIdentifier)
+ , m_ident(vm->propertyNames->nullIdentifier)
{
}
@@ -701,11 +706,13 @@ namespace JSC {
{
}
- inline WithNode::WithNode(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength)
+ inline WithNode::WithNode(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength)
: StatementNode(location)
, m_expr(expr)
, m_statement(statement)
, m_divot(divot)
+ , m_divotLine(divotLine)
+ , m_divotLineStart(divotLineStart)
, m_expressionLength(expressionLength)
{
}
@@ -815,16 +822,17 @@ namespace JSC {
{
}
- inline ForInNode::ForInNode(JSGlobalData* globalData, const JSTokenLocation& location, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
+ inline ForInNode::ForInNode(VM* vm, const JSTokenLocation& location, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart)
: StatementNode(location)
, m_init(0)
- , m_lexpr(new (globalData) ResolveNode(location, ident, divot - startOffset))
+ , m_lexpr(new (vm) ResolveNode(location, ident, divot - startOffset, divotLine, divotLineStart))
, m_expr(expr)
, m_statement(statement)
{
if (in) {
- AssignResolveNode* node = new (globalData) AssignResolveNode(location, ident, in);
- node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
+ AssignResolveNode* node = new (vm) AssignResolveNode(location, ident, in);
+ ASSERT(divot >= divotLineStart);
+ node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot, divotLine, divotLineStart);
m_init = node;
}
// for( var foo = bar in baz )
diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp
index 03ee8ee12..97ffaa163 100644
--- a/Source/JavaScriptCore/parser/Nodes.cpp
+++ b/Source/JavaScriptCore/parser/Nodes.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
-* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -52,18 +52,13 @@ namespace JSC {
// ------------------------------ StatementNode --------------------------------
-void StatementNode::setLoc(int firstLine, int lastLine, int column)
+void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
{
m_lineNumber = firstLine;
m_lastLine = lastLine;
- m_columnNumber = column;
-}
-
-void StatementNode::setLoc(int firstLine, int lastLine)
-{
- m_lineNumber = firstLine;
- m_lastLine = lastLine;
- m_columnNumber = 0;
+ m_startOffset = startOffset;
+ m_lineStartOffset = lineStartOffset;
+ ASSERT(m_startOffset >= m_lineStartOffset);
}
// ------------------------------ SourceElements --------------------------------
@@ -83,24 +78,30 @@ StatementNode* SourceElements::singleStatement() const
// ------------------------------ ScopeNode -----------------------------
-ScopeNode::ScopeNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
- : StatementNode(location)
- , ParserArenaRefCounted(globalData)
+ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
+ : StatementNode(endLocation)
+ , ParserArenaRefCounted(vm)
+ , m_startLineNumber(startLocation.line)
+ , m_startStartOffset(startLocation.startOffset)
+ , m_startLineStartOffset(startLocation.lineStartOffset)
, m_features(inStrictContext ? StrictModeFeature : NoFeatures)
, m_numConstants(0)
, m_statements(0)
{
}
-ScopeNode::ScopeNode(JSGlobalData* globalData, const JSTokenLocation& location, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
- : StatementNode(location)
- , ParserArenaRefCounted(globalData)
+ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
+ : StatementNode(endLocation)
+ , ParserArenaRefCounted(vm)
+ , m_startLineNumber(startLocation.line)
+ , m_startStartOffset(startLocation.startOffset)
+ , m_startLineStartOffset(startLocation.lineStartOffset)
, m_features(features)
, m_source(source)
, m_numConstants(numConstants)
, m_statements(children)
{
- m_arena.swap(*globalData->parserArena);
+ m_arena.swap(*vm->parserArena);
if (varStack)
m_varStack.swap(*varStack);
if (funcStack)
@@ -115,14 +116,15 @@ StatementNode* ScopeNode::singleStatement() const
// ------------------------------ ProgramNode -----------------------------
-inline ProgramNode::ProgramNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, location, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline ProgramNode::ProgramNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+ , m_startColumn(startColumn)
{
}
-PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<ProgramNode> node = new ProgramNode(globalData, location, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+ RefPtr<ProgramNode> node = new ProgramNode(vm, startLocation, endLocation, startColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
@@ -133,14 +135,14 @@ PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, const JSTo
// ------------------------------ EvalNode -----------------------------
-inline EvalNode::EvalNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, location, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<EvalNode> EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<EvalNode> node = new EvalNode(globalData, location, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+ RefPtr<EvalNode> node = new EvalNode(vm, startLocation, endLocation, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
@@ -151,25 +153,40 @@ PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, const JSTokenLoc
// ------------------------------ FunctionBodyNode -----------------------------
-FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
+PassRefPtr<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
{
unsigned parameterCount = 0;
for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
++parameterCount;
- reserveInitialCapacity(parameterCount);
+ size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(StringImpl*) * parameterCount;
+ void* slot = fastMalloc(objectSize);
+ return adoptRef(new (slot) FunctionParameters(firstParameter, parameterCount));
+}
+FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size)
+ : m_size(size)
+{
+ unsigned i = 0;
for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
- uncheckedAppend(parameter->ident());
+ new (&identifiers()[i++]) Identifier(parameter->ident());
+}
+
+FunctionParameters::~FunctionParameters()
+{
+ for (unsigned i = 0; i < m_size; ++i)
+ identifiers()[i].~Identifier();
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
- : ScopeNode(globalData, location, inStrictContext)
+inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext)
+ : ScopeNode(vm, startLocation, endLocation, inStrictContext)
+ , m_startColumn(startColumn)
{
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, location, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+ : ScopeNode(vm, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
+ , m_startColumn(startColumn)
{
}
@@ -187,14 +204,14 @@ void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters,
m_functionNameIsInScopeToggle = functionNameIsInScopeToggle;
}
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
+FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext)
{
- return new FunctionBodyNode(globalData, location, inStrictContext);
+ return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, inStrictContext);
}
-PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
{
- RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, location, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
+ RefPtr<FunctionBodyNode> node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index 509d36d1a..2eeaae9d9 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -30,6 +30,7 @@
#include "JITCode.h"
#include "Opcode.h"
#include "ParserArena.h"
+#include "ParserTokens.h"
#include "ResultType.h"
#include "SourceCode.h"
#include "SymbolTable.h"
@@ -47,19 +48,6 @@ namespace JSC {
class JSScope;
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;
-
- const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
-
enum Operator {
OpEqual,
OpPlusEq,
@@ -82,6 +70,12 @@ namespace JSC {
OpLogicalOr
};
+ enum FallThroughMode {
+ FallThroughMeansTrue = 0,
+ FallThroughMeansFalse = 1
+ };
+ inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
+
typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
namespace DeclarationStacks {
@@ -100,7 +94,7 @@ namespace JSC {
public:
// ParserArenaFreeable objects are are freed when the arena is deleted.
// Destructors are not called. Clients must not call delete on such objects.
- void* operator new(size_t, JSGlobalData*);
+ void* operator new(size_t, VM*);
};
class ParserArenaDeletable {
@@ -109,7 +103,7 @@ namespace JSC {
// ParserArenaDeletable objects are deleted when the arena is deleted.
// Clients must not call delete directly on such objects.
- void* operator new(size_t, JSGlobalData*);
+ void* operator new(size_t, VM*);
};
template <typename T>
@@ -119,7 +113,7 @@ namespace JSC {
class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
protected:
- ParserArenaRefCounted(JSGlobalData*);
+ ParserArenaRefCounted(VM*);
public:
virtual ~ParserArenaRefCounted()
@@ -135,15 +129,14 @@ namespace JSC {
public:
virtual ~Node() { }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
-
int lineNo() const { return m_lineNumber; }
-
- int columnNo() const { return m_columnNumber; }
+ int startOffset() const { return m_startOffset; }
+ int lineStartOffset() const { return m_lineStartOffset; }
protected:
int m_lineNumber;
- int m_columnNumber;
+ int m_startOffset;
+ int m_lineStartOffset;
};
class ExpressionNode : public Node {
@@ -151,10 +144,13 @@ namespace JSC {
ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
public:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
+
virtual bool isNumber() const { return false; }
virtual bool isString() const { return false; }
virtual bool isNull() const { return false; }
virtual bool isPure(BytecodeGenerator&) const { return false; }
+ virtual bool isConstant() const { return false; }
virtual bool isLocation() const { return false; }
virtual bool isResolveNode() const { return false; }
virtual bool isBracketAccessorNode() const { return false; }
@@ -164,9 +160,9 @@ namespace JSC {
virtual bool isSimpleArray() const { return false; }
virtual bool isAdd() const { return false; }
virtual bool isSubtract() const { return false; }
- virtual bool hasConditionContextCodegen() const { return false; }
+ virtual bool isBoolean() const { return false; }
- virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); }
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
virtual ExpressionNode* stripUnaryPlus() { return this; }
@@ -181,72 +177,76 @@ namespace JSC {
StatementNode(const JSTokenLocation&);
public:
- JS_EXPORT_PRIVATE void setLoc(int firstLine, int lastLine);
- void setLoc(int firstLine, int lastLine, int column);
- int firstLine() const { return lineNo(); }
- int lastLine() const { return m_lastLine; }
- int column() const { return columnNo();}
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
+
+ void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
+ unsigned firstLine() const { return lineNo(); }
+ unsigned lastLine() const { return m_lastLine; }
virtual bool isEmptyStatement() const { return false; }
virtual bool isReturnNode() const { return false; }
virtual bool isExprStatement() const { return false; }
-
+ virtual bool isBreak() const { return false; }
+ virtual bool isContinue() const { return false; }
virtual bool isBlock() const { return false; }
private:
int m_lastLine;
};
- class NullNode : public ExpressionNode {
+ class ConstantNode : public ExpressionNode {
public:
- NullNode(const JSTokenLocation&);
-
+ ConstantNode(const JSTokenLocation&, ResultType);
+ virtual bool isPure(BytecodeGenerator&) const { return true; }
+ virtual bool isConstant() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const = 0;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
+ };
+ class NullNode : public ConstantNode {
+ public:
+ NullNode(const JSTokenLocation&);
+
+ private:
virtual bool isNull() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const { return jsNull(); }
};
- class BooleanNode : public ExpressionNode {
+ class BooleanNode : public ConstantNode {
public:
BooleanNode(const JSTokenLocation&, bool value);
+ bool value() { return m_value; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- virtual bool isPure(BytecodeGenerator&) const { return true; }
+ virtual bool isBoolean() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const { return jsBoolean(m_value); }
bool m_value;
};
- class NumberNode : public ExpressionNode {
+ class NumberNode : public ConstantNode {
public:
NumberNode(const JSTokenLocation&, double value);
-
- double value() const { return m_value; }
+ double value() { return m_value; }
void setValue(double value) { m_value = value; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
virtual bool isNumber() const { return true; }
- virtual bool isPure(BytecodeGenerator&) const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const { return jsNumber(m_value); }
double m_value;
};
- class StringNode : public ExpressionNode {
+ class StringNode : public ConstantNode {
public:
StringNode(const JSTokenLocation&, const Identifier&);
-
const Identifier& value() { return m_value; }
private:
- virtual bool isPure(BytecodeGenerator&) const { return true; }
-
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
virtual bool isString() const { return true; }
+ virtual JSValue jsValue(BytecodeGenerator&) const;
const Identifier& m_value;
};
@@ -255,36 +255,48 @@ namespace JSC {
public:
ThrowableExpressionData()
: m_divot(static_cast<uint32_t>(-1))
- , m_startOffset(static_cast<uint16_t>(-1))
- , m_endOffset(static_cast<uint16_t>(-1))
+ , m_divotStartOffset(static_cast<uint16_t>(-1))
+ , m_divotEndOffset(static_cast<uint16_t>(-1))
+ , m_divotLine(static_cast<uint32_t>(-1))
+ , m_divotLineStart(static_cast<uint32_t>(-1))
{
}
- ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
+ ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
: m_divot(divot)
- , m_startOffset(startOffset)
- , m_endOffset(endOffset)
+ , m_divotStartOffset(startOffset)
+ , m_divotEndOffset(endOffset)
+ , m_divotLine(divotLine)
+ , m_divotLineStart(divotLineStart)
{
+ ASSERT(m_divot >= m_divotLineStart);
}
- void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
+ void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
{
+ ASSERT(divot >= divotLineStart);
m_divot = divot;
- m_startOffset = startOffset;
- m_endOffset = endOffset;
+ m_divotStartOffset = startOffset;
+ m_divotEndOffset = endOffset;
+ m_divotLine = divotLine;
+ m_divotLineStart = divotLineStart;
}
uint32_t divot() const { return m_divot; }
- uint16_t startOffset() const { return m_startOffset; }
- uint16_t endOffset() const { return m_endOffset; }
+ uint16_t divotStartOffset() const { return m_divotStartOffset; }
+ uint16_t divotEndOffset() const { return m_divotEndOffset; }
+ uint32_t divotLine() const { return m_divotLine; }
+ uint32_t divotLineStart() const { return m_divotLineStart; }
protected:
RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
private:
uint32_t m_divot;
- uint16_t m_startOffset;
- uint16_t m_endOffset;
+ uint16_t m_divotStartOffset;
+ uint16_t m_divotEndOffset;
+ uint32_t m_divotLine;
+ uint32_t m_divotLineStart;
};
class ThrowableSubExpressionData : public ThrowableExpressionData {
@@ -292,28 +304,48 @@ namespace JSC {
ThrowableSubExpressionData()
: m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
- : ThrowableExpressionData(divot, startOffset, endOffset)
+ ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
{
ASSERT(subexpressionDivot <= divot());
- if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ // Overflow means we can't do this safely, so just point at the primary divot,
+ // divotLine, or divotLineStart.
+ if ((divot() - subexpressionDivot) & ~0xFFFF)
+ return;
+ if ((divotLine() - subexpressionLine) & ~0xFFFF)
+ return;
+ if ((divotLineStart() - subexpressionLineStart) & ~0xFFFF)
return;
m_subexpressionDivotOffset = divot() - subexpressionDivot;
m_subexpressionEndOffset = subexpressionOffset;
+ m_subexpressionLineOffset = divotLine() - subexpressionLine;
+ m_subexpressionLineStartOffset = divotLineStart() - subexpressionLineStart;
}
+ unsigned subexpressionDivot() { return divot() - m_subexpressionDivotOffset; }
+ unsigned subexpressionStartOffset() { return divotStartOffset() - m_subexpressionDivotOffset; }
+ unsigned subexpressionEndOffset() { return m_subexpressionEndOffset; }
+ unsigned subexpressionLine() { return divotLine() - m_subexpressionLineOffset; }
+ unsigned subexpressionLineStart() { return divotLineStart() - m_subexpressionLineStartOffset; }
+
protected:
uint16_t m_subexpressionDivotOffset;
uint16_t m_subexpressionEndOffset;
+ uint16_t m_subexpressionLineOffset;
+ uint16_t m_subexpressionLineStartOffset;
};
class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
@@ -321,28 +353,48 @@ namespace JSC {
ThrowablePrefixedSubExpressionData()
: m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
- : ThrowableExpressionData(divot, startOffset, endOffset)
+ ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+ : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
, m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
+ , m_subexpressionLineOffset(0)
+ , m_subexpressionLineStartOffset(0)
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
{
ASSERT(subexpressionDivot >= divot());
- if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ // Overflow means we can't do this safely, so just point at the primary divot,
+ // divotLine, or divotLineStart.
+ if ((subexpressionDivot - divot()) & ~0xFFFF)
+ return;
+ if ((subexpressionLine - divotLine()) & ~0xFFFF)
+ return;
+ if ((subexpressionLineStart - divotLineStart()) & ~0xFFFF)
return;
m_subexpressionDivotOffset = subexpressionDivot - divot();
m_subexpressionStartOffset = subexpressionOffset;
+ m_subexpressionLineOffset = subexpressionLine - divotLine();
+ m_subexpressionLineStartOffset = subexpressionLineStart - divotLineStart();
}
+ unsigned subexpressionDivot() { return divot() + m_subexpressionDivotOffset; }
+ unsigned subexpressionStartOffset() { return m_subexpressionStartOffset; }
+ unsigned subexpressionEndOffset() { return divotEndOffset() + m_subexpressionDivotOffset; }
+ unsigned subexpressionLine() { return divotLine() + m_subexpressionLineOffset; }
+ unsigned subexpressionLineStart() { return divotLineStart() + m_subexpressionLineStartOffset; }
+
protected:
uint16_t m_subexpressionDivotOffset;
uint16_t m_subexpressionStartOffset;
+ uint16_t m_subexpressionLineOffset;
+ uint16_t m_subexpressionLineStartOffset;
};
class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
@@ -366,7 +418,7 @@ namespace JSC {
class ResolveNode : public ExpressionNode {
public:
- ResolveNode(const JSTokenLocation&, const Identifier&, int startOffset);
+ ResolveNode(const JSTokenLocation&, const Identifier&, unsigned startOffset, unsigned divotLine, unsigned divotLineStart);
const Identifier& identifier() const { return m_ident; }
@@ -378,7 +430,9 @@ namespace JSC {
virtual bool isResolveNode() const { return true; }
const Identifier& m_ident;
- int32_t m_startOffset;
+ uint32_t m_startOffset;
+ uint32_t m_divotLine;
+ uint32_t m_divotLineStart;
};
class ElementNode : public ParserArenaFreeable {
@@ -402,7 +456,7 @@ namespace JSC {
ArrayNode(const JSTokenLocation&, ElementNode*);
ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
- ArgumentListNode* toArgumentList(JSGlobalData*, int, int) const;
+ ArgumentListNode* toArgumentList(VM*, int, int) const;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -418,8 +472,8 @@ namespace JSC {
public:
enum Type { Constant = 1, Getter = 2, Setter = 4 };
- PropertyNode(JSGlobalData*, const Identifier&, ExpressionNode*, Type);
- PropertyNode(JSGlobalData*, double, ExpressionNode*, Type);
+ PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
+ PropertyNode(VM*, double, ExpressionNode*, Type);
const Identifier& name() const { return m_name; }
Type type() const { return m_type; }
@@ -431,7 +485,7 @@ namespace JSC {
Type m_type;
};
- class PropertyListNode : public Node {
+ class PropertyListNode : public ExpressionNode {
public:
PropertyListNode(const JSTokenLocation&, PropertyNode*);
PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
@@ -491,7 +545,7 @@ namespace JSC {
const Identifier& m_ident;
};
- class ArgumentListNode : public Node {
+ class ArgumentListNode : public ExpressionNode {
public:
ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
@@ -525,7 +579,7 @@ namespace JSC {
class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
public:
- EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -535,7 +589,7 @@ namespace JSC {
class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -546,7 +600,7 @@ namespace JSC {
class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -557,7 +611,7 @@ namespace JSC {
class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -569,7 +623,7 @@ namespace JSC {
class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -582,7 +636,7 @@ namespace JSC {
class CallFunctionCallDotNode : public FunctionCallDotNode {
public:
- CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -590,29 +644,15 @@ namespace JSC {
class ApplyFunctionCallDotNode : public FunctionCallDotNode {
public:
- ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
-
- private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- };
-
- class PostfixNode : public ExpressionNode, public ThrowableExpressionData {
- public:
- PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
- virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
- virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_expr;
- Operator m_operator;
};
class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -622,7 +662,7 @@ namespace JSC {
class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -633,7 +673,7 @@ namespace JSC {
class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -686,9 +726,9 @@ namespace JSC {
class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
public:
- PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
- private:
+ protected:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
@@ -698,6 +738,17 @@ namespace JSC {
Operator m_operator;
};
+ class PostfixNode : public PrefixNode {
+ public:
+ PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
+
+ private:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
+ virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
+ };
+
class UnaryOpNode : public ExpressionNode {
public:
UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
@@ -746,8 +797,7 @@ namespace JSC {
public:
LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
private:
- void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
- virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
};
class BinaryOpNode : public ExpressionNode {
@@ -756,11 +806,13 @@ namespace JSC {
BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
ExpressionNode* lhs() { return m_expr1; };
ExpressionNode* rhs() { return m_expr2; };
private:
+ void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
protected:
@@ -909,8 +961,7 @@ namespace JSC {
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
- virtual bool hasConditionContextCodegen() const { return true; }
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
@@ -932,7 +983,7 @@ namespace JSC {
class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -956,7 +1007,7 @@ namespace JSC {
class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -971,7 +1022,7 @@ namespace JSC {
class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -985,7 +1036,7 @@ namespace JSC {
class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -998,7 +1049,7 @@ namespace JSC {
class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1012,7 +1063,7 @@ namespace JSC {
class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1060,7 +1111,7 @@ namespace JSC {
ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ConstDeclNode* m_next;
};
@@ -1088,7 +1139,7 @@ namespace JSC {
StatementNode* lastStatement() const;
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isBlock() const { return true; }
@@ -1100,7 +1151,7 @@ namespace JSC {
EmptyStatementNode(const JSTokenLocation&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isEmptyStatement() const { return true; }
};
@@ -1110,7 +1161,7 @@ namespace JSC {
DebuggerStatementNode(const JSTokenLocation&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
class ExprStatementNode : public StatementNode {
@@ -1122,7 +1173,7 @@ namespace JSC {
private:
virtual bool isExprStatement() const { return true; }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
@@ -1131,29 +1182,22 @@ namespace JSC {
public:
VarStatementNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
- class IfNode : public StatementNode {
- public:
- IfNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock);
-
- protected:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
- ExpressionNode* m_condition;
- StatementNode* m_ifBlock;
- };
-
- class IfElseNode : public IfNode {
+ class IfElseNode : public StatementNode {
public:
IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
+ Label*& trueTarget, FallThroughMode&);
+ ExpressionNode* m_condition;
+ StatementNode* m_ifBlock;
StatementNode* m_elseBlock;
};
@@ -1162,7 +1206,7 @@ namespace JSC {
DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
StatementNode* m_statement;
ExpressionNode* m_expr;
@@ -1173,7 +1217,7 @@ namespace JSC {
WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
StatementNode* m_statement;
@@ -1184,7 +1228,7 @@ namespace JSC {
ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
@@ -1195,10 +1239,10 @@ namespace JSC {
class ForInNode : public StatementNode, public ThrowableExpressionData {
public:
ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
- ForInNode(JSGlobalData*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
+ ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_init;
ExpressionNode* m_lexpr;
@@ -1208,22 +1252,26 @@ namespace JSC {
class ContinueNode : public StatementNode, public ThrowableExpressionData {
public:
- ContinueNode(JSGlobalData*, const JSTokenLocation&);
+ ContinueNode(VM*, const JSTokenLocation&);
ContinueNode(const JSTokenLocation&, const Identifier&);
+ Label* trivialTarget(BytecodeGenerator&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual bool isContinue() const { return true; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
};
class BreakNode : public StatementNode, public ThrowableExpressionData {
public:
- BreakNode(JSGlobalData*, const JSTokenLocation&);
+ BreakNode(VM*, const JSTokenLocation&);
BreakNode(const JSTokenLocation&, const Identifier&);
+ Label* trivialTarget(BytecodeGenerator&);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual bool isBreak() const { return true; }
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_ident;
};
@@ -1235,7 +1283,7 @@ namespace JSC {
ExpressionNode* value() { return m_value; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isReturnNode() const { return true; }
@@ -1244,14 +1292,16 @@ namespace JSC {
class WithNode : public StatementNode {
public:
- WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
+ WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
StatementNode* m_statement;
uint32_t m_divot;
+ uint32_t m_divotLine;
+ uint32_t m_divotLineStart;
uint32_t m_expressionLength;
};
@@ -1260,7 +1310,7 @@ namespace JSC {
LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
const Identifier& m_name;
StatementNode* m_statement;
@@ -1271,7 +1321,7 @@ namespace JSC {
ThrowNode(const JSTokenLocation&, ExpressionNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
};
@@ -1281,7 +1331,7 @@ namespace JSC {
TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
StatementNode* m_tryBlock;
const Identifier& m_exceptionIdent;
@@ -1307,8 +1357,8 @@ namespace JSC {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*, const JSTokenLocation&, bool inStrictContext);
- ScopeNode(JSGlobalData*, const JSTokenLocation&, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+ ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+ ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
using ParserArenaRefCounted::operator new;
@@ -1325,6 +1375,10 @@ namespace JSC {
const String& sourceURL() const { return m_source.provider()->url(); }
intptr_t sourceID() const { return m_source.providerID(); }
+ int startLine() const { return m_startLineNumber; }
+ int startStartOffset() const { return m_startStartOffset; }
+ int startLineStartOffset() const { return m_startLineStartOffset; }
+
void setFeatures(CodeFeatures features) { m_features = features; }
CodeFeatures features() { return m_features; }
@@ -1357,6 +1411,10 @@ namespace JSC {
void setSource(const SourceCode& source) { m_source = source; }
ParserArena m_arena;
+ int m_startLineNumber;
+ unsigned m_startStartOffset;
+ unsigned m_startLineStartOffset;
+
private:
CodeFeatures m_features;
SourceCode m_source;
@@ -1370,49 +1428,64 @@ namespace JSC {
class ProgramNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<ProgramNode> create(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+ unsigned startColumn() { return m_startColumn; }
static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+ unsigned m_startColumn;
};
class EvalNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<EvalNode> create(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+ unsigned startColumn() { return 1; }
static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
- class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> {
+ class FunctionParameters : public RefCounted<FunctionParameters> {
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); }
+ static PassRefPtr<FunctionParameters> create(ParameterNode*);
+ ~FunctionParameters();
+
+ unsigned size() const { return m_size; }
+ const Identifier& at(unsigned index) const { ASSERT(index < m_size); return identifiers()[index]; }
private:
- FunctionParameters(ParameterNode*);
+ FunctionParameters(ParameterNode*, unsigned size);
+
+ Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
+ const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
+
+ unsigned m_size;
+ void* m_storage;
};
- enum FunctionNameIsInScopeToggle { FunctionNameIsNotInScope, FunctionNameIsInScope };
class FunctionBodyNode : public ScopeNode {
public:
static const bool isFunctionNode = true;
- static FunctionBodyNode* create(JSGlobalData*, const JSTokenLocation&, bool isStrictMode);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool isStrictMode);
+ static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
@@ -1424,16 +1497,22 @@ namespace JSC {
bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; }
FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
+ void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
+ int functionStart() const { return m_functionStart; }
+ unsigned startColumn() const { return m_startColumn; }
+
static const bool scopeIsFunction = true;
private:
- FunctionBodyNode(JSGlobalData*, const JSTokenLocation&, bool inStrictContext);
- FunctionBodyNode(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool inStrictContext);
+ FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
Identifier m_ident;
Identifier m_inferredName;
FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
RefPtr<FunctionParameters> m_parameters;
+ int m_functionStart;
+ unsigned m_startColumn;
};
class FuncExprNode : public ExpressionNode {
@@ -1457,7 +1536,7 @@ namespace JSC {
FunctionBodyNode* body() { return m_body; }
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
FunctionBodyNode* m_body;
};
@@ -1492,10 +1571,11 @@ namespace JSC {
public:
CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
- RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
+ void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
private:
- SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+ SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+ static const size_t s_tableSwitchMinimum = 10;
ClauseListNode* m_list1;
CaseClauseNode* m_defaultClause;
ClauseListNode* m_list2;
@@ -1506,7 +1586,7 @@ namespace JSC {
SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_expr;
CaseBlockNode* m_block;
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index cf3cb4e4f..aefba302f 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,20 +26,21 @@
#include "ASTBuilder.h"
#include "CodeBlock.h"
#include "Debugger.h"
-#include "JSGlobalData.h"
+#include "JSCJSValueInlines.h"
#include "Lexer.h"
#include "NodeInfo.h"
#include "SourceProvider.h"
+#include "VM.h"
#include <utility>
#include <wtf/HashFunctions.h>
#include <wtf/OwnPtr.h>
#include <wtf/WTFThreadData.h>
-#define fail() do { if (!m_error) updateErrorMessage(); return 0; } while (0)
-#define failWithToken(tok) do { if (!m_error) updateErrorMessage(tok); return 0; } while (0)
-#define failWithMessage(msg) do { if (!m_error) updateErrorMessage(msg); return 0; } while (0)
-#define failWithNameAndMessage(before, name, after) do { if (!m_error) updateErrorWithNameAndMessage(before, name, after); return 0; } while (0)
-#define failWithStackOverflow() do { m_error = true; m_hasStackOverflow = true; return 0; } while (0)
+#define fail() do { if (!hasError()) updateErrorMessage(); return 0; } while (0)
+#define failWithToken(tok) do { if (!hasError()) updateErrorMessage(tok); return 0; } while (0)
+#define failWithMessage(msg) do { if (!hasError()) updateErrorMessage(msg); return 0; } while (0)
+#define failWithNameAndMessage(before, name, after) do { if (!hasError()) updateErrorWithNameAndMessage(before, name, after); return 0; } while (0)
+#define failWithStackOverflow() do { updateErrorMessage("Stack exhausted"); m_hasStackOverflow = true; return 0; } while (0)
#define failIfFalse(cond) do { if (!(cond)) fail(); } while (0)
#define failIfFalseWithMessage(cond, msg) do { if (!(cond)) failWithMessage(msg); } while (0)
#define failIfFalseWithNameAndMessage(cond, before, name, msg) do { if (!(cond)) failWithNameAndMessage(before, name, msg); } while (0)
@@ -62,13 +63,11 @@ using namespace std;
namespace JSC {
template <typename LexerType>
-Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode)
- : m_globalData(globalData)
+Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode)
+ : m_vm(vm)
, m_source(&source)
- , m_stack(wtfThreadData().stack())
+ , m_stack(*vm, wtfThreadData().stack())
, m_hasStackOverflow(false)
- , m_error(false)
- , m_errorMessage("Parse error")
, m_allowsIn(true)
, m_lastLine(0)
, m_lastTokenEnd(0)
@@ -80,11 +79,13 @@ Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, Fu
, m_lastIdentifier(0)
, m_sourceElements(0)
{
- m_lexer = adoptPtr(new LexerType(globalData));
- m_arena = m_globalData->parserArena.get();
+ m_lexer = adoptPtr(new LexerType(vm));
+ m_arena = m_vm->parserArena.get();
m_lexer->setCode(source, m_arena);
+ m_token.m_location.endOffset = source.startOffset();
+ m_token.m_location.lineStartOffset = source.startOffset();
- m_functionCache = source.provider()->cache();
+ m_functionCache = vm->addSourceProviderCache(source.provider());
ScopeRef scope = pushScope();
if (parserMode == JSParseFunctionCode)
scope->setIsFunction();
@@ -97,7 +98,6 @@ Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, Fu
if (!name.isNull())
scope->declareCallee(&name);
next();
- m_lexer->setLastLineNumber(tokenLine());
}
template <typename LexerType>
@@ -110,14 +110,17 @@ String Parser<LexerType>::parseInner()
{
String parseError = String();
- unsigned oldFunctionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
- ASTBuilder context(const_cast<JSGlobalData*>(m_globalData), const_cast<SourceCode*>(m_source));
+ ASTBuilder context(const_cast<VM*>(m_vm), const_cast<SourceCode*>(m_source));
if (m_lexer->isReparsing())
m_statementDepth--;
ScopeRef scope = currentScope();
SourceElements* sourceElements = parseSourceElements<CheckForStrictMode>(context);
- if (!sourceElements || !consume(EOFTOK))
- parseError = m_errorMessage;
+ if (!sourceElements || !consume(EOFTOK)) {
+ if (hasError())
+ parseError = m_errorMessage;
+ else
+ parseError = ASCIILiteral("Parser error");
+ }
IdentifierSet capturedVariables;
scope->getCapturedVariables(capturedVariables);
@@ -126,9 +129,6 @@ String Parser<LexerType>::parseInner()
features |= StrictModeFeature;
if (scope->shadowsArguments())
features |= ShadowsArgumentsFeature;
- unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
- if (functionCacheSize != oldFunctionCacheSize)
- m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize);
didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
m_lastLine, context.numConstants(), capturedVariables);
@@ -164,6 +164,7 @@ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser<
const Identifier* directive = 0;
unsigned directiveLiteralLength = 0;
unsigned startOffset = m_token.m_location.startOffset;
+ unsigned startLineStartOffset = m_token.m_location.lineStartOffset;
unsigned oldLastLineNumber = m_lexer->lastLineNumber();
unsigned oldLineNumber = m_lexer->lineNumber();
bool hasSetStrict = false;
@@ -171,15 +172,15 @@ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser<
if (mode == CheckForStrictMode && !seenNonDirective) {
if (directive) {
// "use strict" must be the exact literal without escape sequences or line continuation.
- if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_globalData->propertyNames->useStrictIdentifier == *directive) {
+ if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_vm->propertyNames->useStrictIdentifier == *directive) {
setStrictMode();
hasSetStrict = true;
failIfFalse(isValidStrictMode());
- m_lexer->setOffset(startOffset);
+ m_lexer->setOffset(startOffset, startLineStartOffset);
next();
m_lexer->setLastLineNumber(oldLastLineNumber);
m_lexer->setLineNumber(oldLineNumber);
- failIfTrue(m_error);
+ failIfTrue(hasError());
continue;
}
} else
@@ -187,9 +188,8 @@ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser<
}
context.appendStatement(sourceElements, statement);
}
-
- if (m_error)
- fail();
+
+ failIfTrue(hasError());
return sourceElements;
}
@@ -205,7 +205,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaratio
TreeExpression scratch2 = 0;
int scratch3 = 0;
TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3);
- failIfTrue(m_error);
+ failIfTrue(hasError());
failIfFalse(autoSemiColon());
return context.createVarStatement(location, varDecls, start, end);
@@ -219,7 +219,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseConstDeclarat
int start = tokenLine();
int end = 0;
TreeConstDeclList constDecls = parseConstDeclarationList(context);
- failIfTrue(m_error);
+ failIfTrue(hasError());
failIfFalse(autoSemiColon());
return context.createConstStatement(location, constDecls, start, end);
@@ -288,6 +288,8 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
if (hasInitializer) {
int varDivot = tokenStart() + 1;
+ unsigned varLine = tokenLine();
+ unsigned varLineStart = tokenLineStart();
initStart = tokenStart();
next(TreeBuilder::DontBuildStrings); // consume '='
TreeExpression initializer = parseAssignmentExpression(context);
@@ -295,7 +297,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
lastInitializer = initializer;
failIfFalse(initializer);
- TreeExpression node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEnd());
+ TreeExpression node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEnd(), varLine, varLineStart);
if (!varDecls)
varDecls = node;
else
@@ -320,6 +322,7 @@ template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDecl
bool hasInitializer = match(EQUAL);
declareVariable(name);
context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
+
TreeExpression initializer = 0;
if (hasInitializer) {
next(TreeBuilder::DontBuildStrings); // consume '='
@@ -344,6 +347,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
int declarations = 0;
int declsStart = 0;
int declsEnd = 0;
+ unsigned declsLine = 0;
+ unsigned declsLineStart = 0;
TreeExpression decls = 0;
if (match(VAR)) {
/*
@@ -358,9 +363,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
int initEnd = 0;
decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd);
m_allowsIn = true;
- if (m_error)
- fail();
-
+ failIfTrue(hasError());
+
// Remainder of a standard for loop is handled identically
if (match(SEMICOLON))
goto standardForLoop;
@@ -369,6 +373,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
// Handle for-in with var declaration
int inLocation = tokenStart();
+ unsigned inLine = tokenLine();
+ unsigned inLineStart = tokenLineStart();
consumeOrFail(INTOKEN);
TreeExpression expr = parseExpression(context);
@@ -384,7 +390,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
endLoop();
failIfFalse(statement);
- return context.createForInLoop(location, forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine);
+ return context.createForInLoop(location, forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine, inLine, inLineStart);
}
if (!match(SEMICOLON)) {
@@ -392,6 +398,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
declsStart = tokenStart();
decls = parseExpression(context);
declsEnd = lastTokenEnd();
+ declsLine = lastTokenLine();
+ declsLineStart = lastTokenLineStart();
m_allowsIn = true;
failIfFalse(decls);
}
@@ -437,7 +445,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
endLoop();
failIfFalse(statement);
- return context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine);
+ return context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, declsLine, declsLineStart);
}
template <typename LexerType>
@@ -449,20 +457,22 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatemen
int endCol = tokenEnd();
int startLine = tokenLine();
int endLine = tokenLine();
+ unsigned endLineStart = tokenLineStart();
next();
if (autoSemiColon()) {
failIfFalseWithMessage(breakIsValid(), "'break' is only valid inside a switch or loop statement");
- return context.createBreakStatement(location, startCol, endCol, startLine, endLine);
+ return context.createBreakStatement(location, startCol, endCol, startLine, endLine, endLineStart);
}
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
failIfFalseWithNameAndMessage(getLabel(ident), "Label", ident->impl(), "is not defined");
endCol = tokenEnd();
endLine = tokenLine();
+ endLineStart = tokenLineStart();
next();
failIfFalse(autoSemiColon());
- return context.createBreakStatement(location, ident, startCol, endCol, startLine, endLine);
+ return context.createBreakStatement(location, ident, startCol, endCol, startLine, endLine, endLineStart);
}
template <typename LexerType>
@@ -474,11 +484,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueState
int endCol = tokenEnd();
int startLine = tokenLine();
int endLine = tokenLine();
+ unsigned endLineStart = tokenLineStart();
next();
if (autoSemiColon()) {
failIfFalseWithMessage(continueIsValid(), "'continue' is only valid inside a loop statement");
- return context.createContinueStatement(location, startCol, endCol, startLine, endLine);
+ return context.createContinueStatement(location, startCol, endCol, startLine, endLine, endLineStart);
}
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
@@ -487,9 +498,10 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueState
failIfFalseWithMessage(label->m_isLoop, "'continue' is only valid inside a loop statement");
endCol = tokenEnd();
endLine = tokenLine();
+ endLineStart = tokenLineStart();
next();
failIfFalse(autoSemiColon());
- return context.createContinueStatement(location, ident, startCol, endCol, startLine, endLine);
+ return context.createContinueStatement(location, ident, startCol, endCol, startLine, endLine, endLineStart);
}
template <typename LexerType>
@@ -502,6 +514,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStateme
int endLine = startLine;
int start = tokenStart();
int end = tokenEnd();
+ unsigned divotLine = tokenLine();
+ unsigned divotLineStart = tokenLineStart();
next();
// We do the auto semicolon check before attempting to parse an expression
// as we need to ensure the a line break after the return correctly terminates
@@ -509,14 +523,16 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStateme
if (match(SEMICOLON))
endLine = tokenLine();
if (autoSemiColon())
- return context.createReturnStatement(location, 0, start, end, startLine, endLine);
+ return context.createReturnStatement(location, 0, start, end, startLine, endLine, divotLine, divotLineStart);
TreeExpression expr = parseExpression(context);
failIfFalse(expr);
end = lastTokenEnd();
+ divotLine = lastTokenLine();
+ divotLineStart = lastTokenLineStart();
if (match(SEMICOLON))
endLine = tokenLine();
failIfFalse(autoSemiColon());
- return context.createReturnStatement(location, expr, start, end, startLine, endLine);
+ return context.createReturnStatement(location, expr, start, end, startLine, endLine, divotLine, divotLineStart);
}
template <typename LexerType>
@@ -533,10 +549,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatemen
TreeExpression expr = parseExpression(context);
failIfFalse(expr);
int eEnd = lastTokenEnd();
+ unsigned divotLine = lastTokenLine();
+ unsigned divotLineStart = lastTokenLineStart();
int endLine = tokenLine();
failIfFalse(autoSemiColon());
- return context.createThrowStatement(location, expr, eStart, eEnd, startLine, endLine);
+ return context.createThrowStatement(location, expr, eStart, eEnd, startLine, endLine, divotLine, divotLineStart);
}
template <typename LexerType>
@@ -553,14 +571,15 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement
TreeExpression expr = parseExpression(context);
failIfFalse(expr);
int end = lastTokenEnd();
-
+ unsigned divotLine = lastTokenLine();
+ unsigned divotLineStart = lastTokenLineStart();
int endLine = tokenLine();
consumeOrFail(CLOSEPAREN);
const Identifier* unused = 0;
TreeStatement statement = parseStatement(context, unused);
failIfFalse(statement);
- return context.createWithStatement(location, expr, statement, start, end, startLine, endLine);
+ return context.createWithStatement(location, expr, statement, start, end, startLine, endLine, divotLine, divotLineStart);
}
template <typename LexerType>
@@ -578,13 +597,13 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseSwitchStateme
consumeOrFail(OPENBRACE);
startSwitch();
TreeClauseList firstClauses = parseSwitchClauses(context);
- failIfTrue(m_error);
+ failIfTrue(hasError());
TreeClause defaultClause = parseSwitchDefaultClause(context);
- failIfTrue(m_error);
+ failIfTrue(hasError());
TreeClauseList secondClauses = parseSwitchClauses(context);
- failIfTrue(m_error);
+ failIfTrue(hasError());
endSwitch();
consumeOrFail(CLOSEBRACE);
@@ -638,7 +657,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(
ASSERT(match(TRY));
JSTokenLocation location(tokenLocation());
TreeStatement tryBlock = 0;
- const Identifier* ident = &m_globalData->propertyNames->nullIdentifier;
+ const Identifier* ident = &m_vm->propertyNames->nullIdentifier;
TreeStatement catchBlock = 0;
TreeStatement finallyBlock = 0;
int firstLine = tokenLine();
@@ -798,17 +817,21 @@ template <class TreeBuilder> TreeFormalParameterList Parser<LexerType>::parseFor
template <typename LexerType>
template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
{
+ JSTokenLocation startLocation(tokenLocation());
+ unsigned startColumn = tokenColumn();
+ next();
+
if (match(CLOSEBRACE))
- return context.createFunctionBody(tokenLocation(), strictMode());
+ return context.createFunctionBody(startLocation, tokenLocation(), startColumn, strictMode());
DepthManager statementDepth(&m_statementDepth);
m_statementDepth = 0;
- typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get());
+ typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<VM*>(m_vm), m_lexer.get());
failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder));
- return context.createFunctionBody(tokenLocation(), strictMode());
+ return context.createFunctionBody(startLocation, tokenLocation(), startColumn, strictMode());
}
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)
+template <FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn)
{
AutoPopScopeRef functionScope(this, pushScope());
functionScope->setIsFunction();
@@ -828,55 +851,71 @@ template <FunctionRequirements requirements, bool nameIsInContainingScope, class
consumeOrFail(CLOSEPAREN);
matchOrFail(OPENBRACE);
- openBracePos = m_token.m_data.intValue;
+ openBraceOffset = m_token.m_data.offset;
bodyStartLine = tokenLine();
- JSTokenLocation location(tokenLocation());
+ bodyStartColumn = m_token.m_data.offset - m_token.m_data.lineStartOffset;
+ JSTokenLocation startLocation(tokenLocation());
// If we know about this function already, we can use the cached info and skip the parser to the end of the function.
- if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) {
+ if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBraceOffset) : 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(location, cachedInfo->strictMode);
+ JSTokenLocation endLocation;
+
+ endLocation.line = cachedInfo->closeBraceLine;
+ endLocation.startOffset = cachedInfo->closeBraceOffset;
+ endLocation.lineStartOffset = cachedInfo->closeBraceLineStartOffset;
+ ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
+
+ body = context.createFunctionBody(startLocation, endLocation, bodyStartColumn, cachedInfo->strictMode);
- functionScope->restoreFunctionInfo(cachedInfo);
+ functionScope->restoreFromSourceProviderCache(cachedInfo);
failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
- closeBracePos = cachedInfo->closeBracePos;
+ closeBraceOffset = cachedInfo->closeBraceOffset;
+
+ context.setFunctionStart(body, functionStart);
m_token = cachedInfo->closeBraceToken();
- m_lexer->setOffset(m_token.m_location.endOffset);
+
+ m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
m_lexer->setLineNumber(m_token.m_location.line);
next();
return true;
}
- next();
-
body = parseFunctionBody(context);
failIfFalse(body);
if (functionScope->strictMode() && name) {
- failIfTrueWithNameAndMessage(m_globalData->propertyNames->arguments == *name, "Function name", name->impl(), "is not valid in strict mode");
- failIfTrueWithNameAndMessage(m_globalData->propertyNames->eval == *name, "Function name", name->impl(), "is not valid in strict mode");
+ failIfTrueWithNameAndMessage(m_vm->propertyNames->arguments == *name, "Function name", name->impl(), "is not valid in strict mode");
+ failIfTrueWithNameAndMessage(m_vm->propertyNames->eval == *name, "Function name", name->impl(), "is not valid in strict mode");
}
- closeBracePos = m_token.m_data.intValue;
+ closeBraceOffset = m_token.m_data.offset;
+ unsigned closeBraceLine = m_token.m_data.line;
+ unsigned closeBraceLineStartOffset = m_token.m_data.lineStartOffset;
// Cache the tokenizer state and the function scope the first time the function is parsed.
// Any future reparsing can then skip the function.
- static const int minimumFunctionLengthToCache = 64;
+ static const int minimumFunctionLengthToCache = 16;
OwnPtr<SourceProviderCacheItem> newInfo;
- int functionLength = closeBracePos - openBracePos;
+ int functionLength = closeBraceOffset - openBraceOffset;
if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
- newInfo = adoptPtr(new SourceProviderCacheItem(functionStart, m_token.m_location.line, closeBracePos));
- functionScope->saveFunctionInfo(newInfo.get());
+ SourceProviderCacheItemCreationParameters parameters;
+ parameters.functionStart = functionStart;
+ parameters.closeBraceLine = closeBraceLine;
+ parameters.closeBraceOffset = closeBraceOffset;
+ parameters.closeBraceLineStartOffset = closeBraceLineStartOffset;
+ functionScope->fillParametersForSourceProviderCache(parameters);
+ newInfo = SourceProviderCacheItem::create(parameters);
+
}
+ context.setFunctionStart(body, functionStart);
failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
matchOrFail(CLOSEBRACE);
- if (newInfo) {
- unsigned approximateByteSize = newInfo->approximateByteSize();
- m_functionCache->add(openBracePos, newInfo.release(), approximateByteSize);
- }
+ if (newInfo)
+ m_functionCache->add(openBraceOffset, newInfo.release());
next();
return true;
@@ -891,26 +930,31 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
const Identifier* name = 0;
TreeFormalParameterList parameters = 0;
TreeFunctionBody body = 0;
- int openBracePos = 0;
- int closeBracePos = 0;
+ unsigned openBraceOffset = 0;
+ unsigned closeBraceOffset = 0;
int bodyStartLine = 0;
- failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
+ unsigned bodyStartColumn = 0;
+ failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)));
failIfFalse(name);
failIfFalseIfStrict(declareVariable(name));
- return context.createFuncDeclStatement(location, name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ return context.createFuncDeclStatement(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn);
}
struct LabelInfo {
- LabelInfo(const Identifier* ident, int start, int end)
+ LabelInfo(const Identifier* ident, unsigned start, unsigned end, unsigned divotLine, unsigned divotLineStart)
: m_ident(ident)
, m_start(start)
, m_end(end)
+ , m_divotLine(divotLine)
+ , m_divotLineStart(divotLineStart)
{
}
const Identifier* m_ident;
- int m_start;
- int m_end;
+ unsigned m_start;
+ unsigned m_end;
+ unsigned m_divotLine;
+ unsigned m_divotLineStart;
};
template <typename LexerType>
@@ -924,7 +968,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
JSTokenLocation location;
do {
int start = tokenStart();
- int startLine = tokenLine();
+ int startingLine = tokenLine();
location = tokenLocation();
if (!nextTokenIsColon()) {
// If we hit this path we're making a expression statement, which
@@ -933,10 +977,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
TreeExpression expression = parseExpression(context);
failIfFalse(expression);
failIfFalse(autoSemiColon());
- return context.createExprStatement(location, expression, startLine, m_lastLine);
+ return context.createExprStatement(location, expression, startingLine, m_lastLine);
}
const Identifier* ident = m_token.m_data.ident;
int end = tokenEnd();
+ unsigned divotLine = tokenLine();
+ unsigned divotLineStart = tokenLineStart();
next();
consumeOrFail(COLON);
if (!m_syntaxAlreadyValidated) {
@@ -945,7 +991,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
for (size_t i = 0; i < labels.size(); i++)
failIfTrue(ident->impl() == labels[i].m_ident->impl());
failIfTrue(getLabel(ident));
- labels.append(LabelInfo(ident, start, end));
+ labels.append(LabelInfo(ident, start, end, divotLine, divotLineStart));
}
} while (match(IDENT));
bool isLoop = false;
@@ -972,7 +1018,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
failIfFalse(statement);
for (size_t i = 0; i < labels.size(); i++) {
const LabelInfo& info = labels[labels.size() - i - 1];
- statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end);
+ statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end, info.m_divotLine, info.m_divotLineStart);
}
return statement;
}
@@ -1008,7 +1054,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
failIfFalse(trueBlock);
if (!match(ELSE))
- return context.createIfStatement(ifLocation, condition, trueBlock, start, end);
+ return context.createIfStatement(ifLocation, condition, trueBlock, 0, start, end);
Vector<TreeExpression> exprStack;
Vector<pair<int, int> > posStack;
@@ -1053,7 +1099,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
posStack.removeLast();
JSTokenLocation elseLocation = tokenLocationStack.last();
tokenLocationStack.removeLast();
- statementStack.append(context.createIfStatement(elseLocation, condition, trueBlock, pos.first, pos.second));
+ statementStack.append(context.createIfStatement(elseLocation, condition, trueBlock, 0, pos.first, pos.second));
}
while (!exprStack.isEmpty()) {
@@ -1102,6 +1148,8 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
{
failIfStackOverflow();
int start = tokenStart();
+ unsigned line = tokenLine();
+ unsigned lineStart = tokenLineStart();
JSTokenLocation location(tokenLocation());
int initialAssignmentCount = m_assignmentCount;
int initialNonLHSCount = m_nonLHSCount;
@@ -1132,13 +1180,15 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
}
m_nonTrivialExpressionCount++;
hadAssignment = true;
- context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op);
+ context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), line, lineStart, m_assignmentCount, op);
start = tokenStart();
+ line = tokenLine();
+ lineStart = tokenLineStart();
m_assignmentCount++;
next(TreeBuilder::DontBuildStrings);
if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
- failIfTrueIfStrictWithMessage(m_globalData->propertyNames->eval == *m_lastIdentifier, "'eval' cannot be modified in strict mode");
- failIfTrueIfStrictWithMessage(m_globalData->propertyNames->arguments == *m_lastIdentifier, "'arguments' cannot be modified in strict mode");
+ failIfTrueIfStrictWithMessage(m_vm->propertyNames->eval == *m_lastIdentifier, "'eval' cannot be modified in strict mode");
+ failIfTrueIfStrictWithMessage(m_vm->propertyNames->arguments == *m_lastIdentifier, "'arguments' cannot be modified in strict mode");
declareWrite(m_lastIdentifier);
m_lastIdentifier = 0;
}
@@ -1206,7 +1256,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpres
TreeExpression current = parseUnaryExpression(context);
failIfFalse(current);
- context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), initialAssignments != m_assignmentCount);
+ context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), lastTokenLine(), lastTokenLineStart(), initialAssignments != m_assignmentCount);
int precedence = isBinaryOperator(m_token.m_type);
if (!precedence)
break;
@@ -1248,7 +1298,7 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
wasIdent = true;
case STRING: {
const Identifier* ident = m_token.m_data.ident;
- if (complete || (wasIdent && (*ident == m_globalData->propertyNames->get || *ident == m_globalData->propertyNames->set)))
+ if (complete || (wasIdent && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))
nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
else
nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
@@ -1263,13 +1313,14 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
const Identifier* accessorName = 0;
TreeFormalParameterList parameters = 0;
TreeFunctionBody body = 0;
- int openBracePos = 0;
- int closeBracePos = 0;
+ unsigned openBraceOffset = 0;
+ unsigned closeBraceOffset = 0;
int bodyStartLine = 0;
+ unsigned bodyStartColumn = 0;
PropertyNode::Type type;
- if (*ident == m_globalData->propertyNames->get)
+ if (*ident == m_vm->propertyNames->get)
type = PropertyNode::Getter;
- else if (*ident == m_globalData->propertyNames->set)
+ else if (*ident == m_vm->propertyNames->set)
type = PropertyNode::Setter;
else
fail();
@@ -1283,10 +1334,10 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
fail();
JSTokenLocation location(tokenLocation());
next();
- failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
+ failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)));
if (stringPropertyName)
- return context.template createGetterOrSetterProperty<complete>(location, type, stringPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
- return context.template createGetterOrSetterProperty<complete>(const_cast<JSGlobalData*>(m_globalData), location, type, numericPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ return context.template createGetterOrSetterProperty<complete>(location, type, stringPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn);
+ return context.template createGetterOrSetterProperty<complete>(const_cast<VM*>(m_vm), location, type, numericPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn);
}
case NUMBER: {
double propertyName = m_token.m_data.doubleValue;
@@ -1294,7 +1345,7 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
consumeOrFail(COLON);
TreeExpression node = parseAssignmentExpression(context);
failIfFalse(node);
- return context.template createProperty<complete>(const_cast<JSGlobalData*>(m_globalData), propertyName, node, PropertyNode::Constant);
+ return context.template createProperty<complete>(const_cast<VM*>(m_vm), propertyName, node, PropertyNode::Constant);
}
default:
failIfFalse(m_token.m_type & KeywordTokenFlag);
@@ -1305,7 +1356,8 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
template <typename LexerType>
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context)
{
- int startOffset = m_token.m_data.intValue;
+ int startOffset = m_token.m_data.offset;
+ unsigned oldLineStartOffset = m_lexer->currentLineStartOffset();
unsigned oldLastLineNumber = m_lexer->lastLineNumber();
unsigned oldLineNumber = m_lexer->lineNumber();
consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings);
@@ -1321,7 +1373,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLitera
TreeProperty property = parseProperty<false>(context);
failIfFalse(property);
if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
- m_lexer->setOffset(startOffset);
+ m_lexer->setOffset(startOffset, oldLineStartOffset);
next();
m_lexer->setLastLineNumber(oldLastLineNumber);
m_lexer->setLineNumber(oldLineNumber);
@@ -1338,7 +1390,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLitera
property = parseProperty<false>(context);
failIfFalse(property);
if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
- m_lexer->setOffset(startOffset);
+ m_lexer->setOffset(startOffset, oldLineStartOffset);
next();
m_lexer->setLastLineNumber(oldLastLineNumber);
m_lexer->setLineNumber(oldLineNumber);
@@ -1484,12 +1536,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
}
case IDENT: {
int start = tokenStart();
+ int line = tokenLine();
+ int lineStart = tokenLineStart();
const Identifier* ident = m_token.m_data.ident;
JSTokenLocation location(tokenLocation());
next();
- currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
+ currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
m_lastIdentifier = ident;
- return context.createResolve(location, ident, start);
+ return context.createResolve(location, ident, start, line, lineStart);
}
case STRING: {
const Identifier* ident = m_token.m_data.ident;
@@ -1529,12 +1583,13 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
failIfFalse(m_lexer->scanRegExp(pattern, flags));
int start = tokenStart();
+ int line = tokenLine();
+ int lineStart = tokenLineStart();
JSTokenLocation location(tokenLocation());
next();
- TreeExpression re = context.createRegExp(location, *pattern, *flags, start);
+ TreeExpression re = context.createRegExp(location, *pattern, *flags, start, line, lineStart);
if (!re) {
const char* yarrErrorMsg = Yarr::checkSyntax(pattern->string());
- ASSERT(!m_errorMessage.isNull());
failWithMessage(yarrErrorMsg);
}
return re;
@@ -1575,6 +1630,8 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
TreeExpression base = 0;
int start = tokenStart();
int expressionStart = start;
+ int expressionLine = tokenLine();
+ int expressionLineStart = tokenLineStart();
int newCount = 0;
JSTokenLocation location;
while (match(NEW)) {
@@ -1583,16 +1640,17 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
}
if (match(FUNCTION)) {
- const Identifier* name = &m_globalData->propertyNames->nullIdentifier;
+ const Identifier* name = &m_vm->propertyNames->nullIdentifier;
TreeFormalParameterList parameters = 0;
TreeFunctionBody body = 0;
- int openBracePos = 0;
- int closeBracePos = 0;
+ unsigned openBraceOffset = 0;
+ unsigned closeBraceOffset = 0;
int bodyStartLine = 0;
+ unsigned bodyStartColumn = 0;
location = tokenLocation();
next();
- failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
- base = context.createFunctionExpr(location, name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn)));
+ base = context.createFunctionExpr(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn);
} else
base = parsePrimaryExpression(context);
@@ -1603,12 +1661,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
case OPENBRACKET: {
m_nonTrivialExpressionCount++;
int expressionEnd = lastTokenEnd();
+ int expressionLine = lastTokenLine();
+ int expressionLineStart = lastTokenLineStart();
next();
int nonLHSCount = m_nonLHSCount;
int initialAssignments = m_assignmentCount;
TreeExpression property = parseExpression(context);
failIfFalse(property);
- base = context.createBracketAccess(location, base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd());
+ base = context.createBracketAccess(location, base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd(), expressionLine, expressionLineStart);
consumeOrFail(CLOSEBRACKET);
m_nonLHSCount = nonLHSCount;
break;
@@ -1619,14 +1679,18 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
if (newCount) {
newCount--;
int exprEnd = lastTokenEnd();
+ unsigned expressionLine = lastTokenLine();
+ unsigned expressionLineStart = lastTokenLineStart();
TreeArguments arguments = parseArguments(context);
failIfFalse(arguments);
- base = context.createNewExpr(location, base, arguments, start, exprEnd, lastTokenEnd());
+ base = context.createNewExpr(location, base, arguments, start, exprEnd, lastTokenEnd(), expressionLine, expressionLineStart);
} else {
int expressionEnd = lastTokenEnd();
+ unsigned expressionLine = lastTokenLine();
+ int expressionLineStart = lastTokenLineStart();
TreeArguments arguments = parseArguments(context);
failIfFalse(arguments);
- base = context.makeFunctionCallNode(location, base, arguments, expressionStart, expressionEnd, lastTokenEnd());
+ base = context.makeFunctionCallNode(location, base, arguments, expressionStart, expressionEnd, lastTokenEnd(), expressionLine, expressionLineStart);
}
m_nonLHSCount = nonLHSCount;
break;
@@ -1634,9 +1698,10 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
case DOT: {
m_nonTrivialExpressionCount++;
int expressionEnd = lastTokenEnd();
+ expressionLineStart = lastTokenLineStart();
nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
matchOrFail(IDENT);
- base = context.createDotAccess(location, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
+ base = context.createDotAccess(location, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd(), expressionLine, expressionLineStart);
next();
break;
}
@@ -1646,7 +1711,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
}
endMemberExpression:
while (newCount--)
- base = context.createNewExpr(location, base, start, lastTokenEnd());
+ base = context.createNewExpr(location, base, start, lastTokenEnd(), expressionLine, expressionLineStart);
return base;
}
@@ -1679,25 +1744,28 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
}
}
m_nonLHSCount++;
- context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart());
+ context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart(), tokenLine(), tokenLineStart());
next();
m_nonTrivialExpressionCount++;
}
int subExprStart = tokenStart();
+ int subExprLine = tokenLine();
+ int subExprLineStartPosition = tokenLineStart();
+ ASSERT(subExprStart >= subExprLineStartPosition);
JSTokenLocation location(tokenLocation());
TreeExpression expr = parseMemberExpression(context);
failIfFalse(expr);
bool isEvalOrArguments = false;
if (strictMode() && !m_syntaxAlreadyValidated) {
if (context.isResolve(expr))
- isEvalOrArguments = *m_lastIdentifier == m_globalData->propertyNames->eval || *m_lastIdentifier == m_globalData->propertyNames->arguments;
+ isEvalOrArguments = *m_lastIdentifier == m_vm->propertyNames->eval || *m_lastIdentifier == m_vm->propertyNames->arguments;
}
failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments && modifiesExpr, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
switch (m_token.m_type) {
case PLUSPLUS:
m_nonTrivialExpressionCount++;
m_nonLHSCount++;
- expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
+ expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd(), tokenLine(), tokenLineStart());
m_assignmentCount++;
failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
failIfTrueIfStrict(requiresLExpr);
@@ -1706,7 +1774,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
case MINUSMINUS:
m_nonTrivialExpressionCount++;
m_nonLHSCount++;
- expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
+ expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd(), tokenLine(), tokenLineStart());
m_assignmentCount++;
failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
failIfTrueIfStrict(requiresLExpr);
@@ -1717,7 +1785,9 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
}
int end = lastTokenEnd();
-
+ int endLine = lastTokenLine();
+ int endLineStartPosition = lastTokenLineStart();
+
if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
return expr;
@@ -1739,12 +1809,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
break;
case PLUSPLUS:
case AUTOPLUSPLUS:
- expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
+ expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end, subExprLine, subExprLineStartPosition);
m_assignmentCount++;
break;
case MINUSMINUS:
case AUTOMINUSMINUS:
- expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
+ expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end, subExprLine, subExprLineStartPosition);
m_assignmentCount++;
break;
case TYPEOF:
@@ -1755,13 +1825,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
break;
case DELETETOKEN:
failIfTrueIfStrictWithNameAndMessage(context.isResolve(expr), "Cannot delete unqualified property", m_lastIdentifier->impl(), "in strict mode");
- expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
+ expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end, endLine, endLineStartPosition);
break;
default:
// If we get here something has gone horribly horribly wrong
CRASH();
}
subExprStart = context.unaryTokenStackLastStart(tokenStackDepth);
+ subExprLineStartPosition = context.unaryTokenStackLastLineStartPosition(tokenStackDepth);
context.unaryTokenStackRemoveLast(tokenStackDepth);
}
return expr;
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index 615d09eb7..e0a56754d 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,9 +30,12 @@
#include "Lexer.h"
#include "Nodes.h"
#include "ParserArena.h"
+#include "ParserError.h"
#include "ParserTokens.h"
#include "SourceProvider.h"
+#include "SourceProviderCache.h"
#include "SourceProviderCacheItem.h"
+#include "VMStackBounds.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -53,7 +56,7 @@ class ExecState;
class FunctionBodyNode;
class FunctionParameters;
class Identifier;
-class JSGlobalData;
+class VM;
class ProgramNode;
class SourceCode;
@@ -76,49 +79,6 @@ COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
-struct ParserError {
- enum ErrorType { ErrorNone, StackOverflow, SyntaxError, EvalError, OutOfMemory } m_type;
- String m_message;
- int m_line;
- ParserError()
- : m_type(ErrorNone)
- , m_line(-1)
- {
- }
-
- ParserError(ErrorType type)
- : m_type(type)
- , m_line(-1)
- {
- }
-
- ParserError(ErrorType type, String msg, int line)
- : m_type(type)
- , m_message(msg)
- , m_line(line)
- {
- }
-
- JSObject* toErrorObject(JSGlobalObject* globalObject, const SourceCode& source)
- {
- switch (m_type) {
- case ErrorNone:
- return 0;
- case SyntaxError:
- return addErrorInfo(globalObject->globalExec(), createSyntaxError(globalObject, m_message), m_line, source);
- case EvalError:
- return createSyntaxError(globalObject, m_message);
- case StackOverflow:
- return createStackOverflowError(globalObject);
- case OutOfMemory:
- return createOutOfMemoryError(globalObject);
- }
- CRASH();
- return createOutOfMemoryError(globalObject); // Appease Qt bot
- }
-
-};
-
template <typename T> inline bool isEvalNode() { return false; }
template <> inline bool isEvalNode<EvalNode>() { return true; }
@@ -151,8 +111,8 @@ struct ScopeLabelInfo {
};
struct Scope {
- Scope(const JSGlobalData* globalData, bool isFunction, bool strictMode)
- : m_globalData(globalData)
+ Scope(const VM* vm, bool isFunction, bool strictMode)
+ : m_vm(vm)
, m_shadowsArguments(false)
, m_usesEval(false)
, m_needsFullActivation(false)
@@ -167,7 +127,7 @@ struct Scope {
}
Scope(const Scope& rhs)
- : m_globalData(rhs.m_globalData)
+ : m_vm(rhs.m_vm)
, m_shadowsArguments(rhs.m_shadowsArguments)
, m_usesEval(rhs.m_usesEval)
, m_needsFullActivation(rhs.m_needsFullActivation)
@@ -237,7 +197,7 @@ struct Scope {
bool declareVariable(const Identifier* ident)
{
- bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
+ bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
m_declaredVariables.add(ident->string().impl());
return isValidStrictMode;
@@ -254,8 +214,8 @@ struct Scope {
bool declareParameter(const Identifier* ident)
{
- bool isArguments = m_globalData->propertyNames->arguments == *ident;
- bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_globalData->propertyNames->eval != *ident && !isArguments;
+ bool isArguments = m_vm->propertyNames->arguments == *ident;
+ bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
if (isArguments)
m_shadowsArguments = true;
@@ -328,35 +288,32 @@ struct Scope {
continue;
vector.append(*it);
}
- vector.shrinkToFit();
}
- void saveFunctionInfo(SourceProviderCacheItem* info)
+ void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
{
ASSERT(m_isFunction);
- info->usesEval = m_usesEval;
- info->strictMode = m_strictMode;
- info->needsFullActivation = m_needsFullActivation;
- copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables);
- copyCapturedVariablesToVector(m_usedVariables, info->usedVariables);
+ parameters.usesEval = m_usesEval;
+ parameters.strictMode = m_strictMode;
+ parameters.needsFullActivation = m_needsFullActivation;
+ copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
+ copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
}
- void restoreFunctionInfo(const SourceProviderCacheItem* info)
+ void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
{
ASSERT(m_isFunction);
m_usesEval = info->usesEval;
m_strictMode = info->strictMode;
m_needsFullActivation = info->needsFullActivation;
- unsigned size = info->usedVariables.size();
- for (unsigned i = 0; i < size; ++i)
- m_usedVariables.add(info->usedVariables[i]);
- size = info->writtenVariables.size();
- for (unsigned i = 0; i < size; ++i)
- m_writtenVariables.add(info->writtenVariables[i]);
+ for (unsigned i = 0; i < info->usedVariablesCount; ++i)
+ m_usedVariables.add(info->usedVariables()[i]);
+ for (unsigned i = 0; i < info->writtenVariablesCount; ++i)
+ m_writtenVariables.add(info->writtenVariables()[i]);
}
private:
- const JSGlobalData* m_globalData;
+ const VM* m_vm;
bool m_shadowsArguments : 1;
bool m_usesEval : 1;
bool m_needsFullActivation : 1;
@@ -409,7 +366,7 @@ class Parser {
WTF_MAKE_FAST_ALLOCATED;
public:
- Parser(JSGlobalData*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
+ Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
~Parser();
template <class ParsedNode>
@@ -466,7 +423,7 @@ private:
isStrict = m_scopeStack.last().strictMode();
isFunction = m_scopeStack.last().isFunction();
}
- m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
+ m_scopeStack.append(Scope(m_vm, isFunction, isStrict));
return currentScope();
}
@@ -525,11 +482,11 @@ private:
bool isFunctionBodyNode(ScopeNode*) { return false; }
bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
-
ALWAYS_INLINE void next(unsigned lexerFlags = 0)
{
m_lastLine = m_token.m_location.line;
m_lastTokenEnd = m_token.m_location.endOffset;
+ m_lastTokenLineStart = m_token.m_location.lineStartOffset;
m_lexer->setLastLineNumber(m_lastLine);
m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
}
@@ -538,6 +495,7 @@ private:
{
m_lastLine = m_token.m_location.line;
m_lastTokenEnd = m_token.m_location.endOffset;
+ m_lastTokenLineStart = m_token.m_location.lineStartOffset;
m_lexer->setLastLineNumber(m_lastLine);
m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
}
@@ -565,7 +523,7 @@ private:
return m_token.m_type == expected;
}
- ALWAYS_INLINE int tokenStart()
+ ALWAYS_INLINE unsigned tokenStart()
{
return m_token.m_location.startOffset;
}
@@ -575,11 +533,21 @@ private:
return m_token.m_location.line;
}
- ALWAYS_INLINE int tokenEnd()
+ ALWAYS_INLINE int tokenColumn()
+ {
+ return tokenStart() - tokenLineStart();
+ }
+
+ ALWAYS_INLINE unsigned tokenEnd()
{
return m_token.m_location.endOffset;
}
+ ALWAYS_INLINE unsigned tokenLineStart()
+ {
+ return m_token.m_location.lineStartOffset;
+ }
+
ALWAYS_INLINE const JSTokenLocation& tokenLocation()
{
return m_token.m_location;
@@ -749,14 +717,24 @@ private:
case RESERVED:
case NUMBER:
case IDENT:
- case STRING:
+ case STRING:
+ case UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK:
+ case UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
+ case UNTERMINATED_MULTILINE_COMMENT_ERRORTOK:
+ case UNTERMINATED_NUMERIC_LITERAL_ERRORTOK:
+ case UNTERMINATED_STRING_LITERAL_ERRORTOK:
+ case INVALID_IDENTIFIER_ESCAPE_ERRORTOK:
+ case INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
+ case INVALID_NUMERIC_LITERAL_ERRORTOK:
+ case INVALID_OCTAL_NUMBER_ERRORTOK:
+ case INVALID_STRING_LITERAL_ERRORTOK:
case ERRORTOK:
- case EOFTOK:
+ case EOFTOK:
return 0;
case LastUntaggedToken:
break;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return "internal error";
}
@@ -778,7 +756,36 @@ private:
case STRING:
m_errorMessage = "Unexpected string " + getToken();
return;
- case ERRORTOK:
+
+ case UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK:
+ case UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
+ m_errorMessage = "Incomplete unicode escape in identifier: '" + getToken() + '\'';
+ return;
+ case UNTERMINATED_MULTILINE_COMMENT_ERRORTOK:
+ m_errorMessage = "Unterminated multiline comment";
+ return;
+ case UNTERMINATED_NUMERIC_LITERAL_ERRORTOK:
+ m_errorMessage = "Unterminated numeric literal '" + getToken() + '\'';
+ return;
+ case UNTERMINATED_STRING_LITERAL_ERRORTOK:
+ m_errorMessage = "Unterminated string literal '" + getToken() + '\'';
+ return;
+ case INVALID_IDENTIFIER_ESCAPE_ERRORTOK:
+ m_errorMessage = "Invalid escape in identifier: '" + getToken() + '\'';
+ return;
+ case INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
+ m_errorMessage = "Invalid unicode escape in identifier: '" + getToken() + '\'';
+ return;
+ case INVALID_NUMERIC_LITERAL_ERRORTOK:
+ m_errorMessage = "Invalid numeric literal: '" + getToken() + '\'';
+ return;
+ case INVALID_OCTAL_NUMBER_ERRORTOK:
+ m_errorMessage = "Invalid use of octal: '" + getToken() + '\'';
+ return;
+ case INVALID_STRING_LITERAL_ERRORTOK:
+ m_errorMessage = "Invalid string literal: '" + getToken() + '\'';
+ return;
+ case ERRORTOK:
m_errorMessage = "Unrecognized token '" + getToken() + '\'';
return;
case EOFTOK:
@@ -788,7 +795,7 @@ private:
m_errorMessage = ASCIILiteral("Return statements are only valid inside functions");
return;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
m_errorMessage = ASCIILiteral("internal error");
return;
}
@@ -796,17 +803,16 @@ private:
NEVER_INLINE void updateErrorMessage()
{
- m_error = true;
const char* name = getTokenName(m_token.m_type);
if (!name)
updateErrorMessageSpecialCase(m_token.m_type);
else
m_errorMessage = String::format("Unexpected token '%s'", name);
+ ASSERT(!m_errorMessage.isNull());
}
NEVER_INLINE void updateErrorMessage(JSTokenType expectedToken)
{
- m_error = true;
const char* name = getTokenName(expectedToken);
if (name)
m_errorMessage = String::format("Expected token '%s'", name);
@@ -816,18 +822,19 @@ private:
else
updateErrorMessageSpecialCase(expectedToken);
}
+ ASSERT(!m_errorMessage.isNull());
}
NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMsg, String name, const char* afterMsg)
{
- m_error = true;
m_errorMessage = makeString(beforeMsg, " '", name, "' ", afterMsg);
}
NEVER_INLINE void updateErrorMessage(const char* msg)
- {
- m_error = true;
+ {
+ ASSERT(msg);
m_errorMessage = String(msg);
+ ASSERT(!m_errorMessage.isNull());
}
void startLoop() { currentScope()->startLoop(); }
@@ -910,7 +917,7 @@ private:
template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd);
template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context);
- template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine);
+ template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
ALWAYS_INLINE int isBinaryOperator(JSTokenType);
bool allowAutomaticSemicolon();
@@ -933,26 +940,42 @@ private:
return m_lastTokenEnd;
}
- JSGlobalData* m_globalData;
+ unsigned lastTokenLine() const
+ {
+ return m_lastLine;
+ }
+
+ unsigned lastTokenLineStart() const
+ {
+ return m_lastTokenLineStart;
+ }
+
+ bool hasError() const
+ {
+ return !m_errorMessage.isNull();
+ }
+
+ VM* m_vm;
const SourceCode* m_source;
ParserArena* m_arena;
OwnPtr<LexerType> m_lexer;
- StackBounds m_stack;
+ VMStackBounds m_stack;
bool m_hasStackOverflow;
- bool m_error;
String m_errorMessage;
JSToken m_token;
bool m_allowsIn;
- int m_lastLine;
+ unsigned m_lastLine;
int m_lastTokenEnd;
+ unsigned m_lastTokenLine;
+ unsigned m_lastTokenLineStart;
int m_assignmentCount;
int m_nonLHSCount;
bool m_syntaxAlreadyValidated;
int m_statementDepth;
int m_nonTrivialExpressionCount;
const Identifier* m_lastIdentifier;
- SourceProviderCache* m_functionCache;
+ RefPtr<SourceProviderCache> m_functionCache;
SourceElements* m_sourceElements;
ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
@@ -994,6 +1017,9 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
errLine = -1;
errMsg = String();
+ JSTokenLocation startLocation(tokenLocation());
+ unsigned startColumn = m_source->startColumn();
+
String parseError = parseInner();
int lineNumber = m_lexer->lineNumber();
@@ -1010,11 +1036,14 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
RefPtr<ParsedNode> result;
if (m_sourceElements) {
- JSTokenLocation location;
- location.line = m_lexer->lastLineNumber();
- location.column = m_lexer->currentColumnNumber();
- result = ParsedNode::create(m_globalData,
- location,
+ JSTokenLocation endLocation;
+ endLocation.line = m_lexer->lastLineNumber();
+ endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
+ endLocation.startOffset = m_lexer->currentOffset();
+ result = ParsedNode::create(m_vm,
+ startLocation,
+ endLocation,
+ startColumn,
m_sourceElements,
m_varDeclarations ? &m_varDeclarations->data : 0,
m_funcDeclarations ? &m_funcDeclarations->data : 0,
@@ -1022,7 +1051,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
*m_source,
m_features,
m_numConstants);
- result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentColumnNumber());
+ result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
} else {
// We can never see a syntax error when reparsing a function, since we should have
// reported the error when parsing the containing program or eval code. So if we're
@@ -1031,11 +1060,19 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
// code we assume that it was a syntax error since running out of stack is much less
// likely, and we are currently unable to distinguish between the two cases.
if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
- error = ParserError::StackOverflow;
- else if (isEvalNode<ParsedNode>())
- error = ParserError(ParserError::EvalError, errMsg, errLine);
- else
- error = ParserError(ParserError::SyntaxError, errMsg, errLine);
+ error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
+ else {
+ ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
+ if (m_token.m_type == EOFTOK)
+ errorType = ParserError::SyntaxErrorRecoverable;
+ else if (m_token.m_type & UnterminatedErrorTokenFlag)
+ errorType = ParserError::SyntaxErrorUnterminatedLiteral;
+
+ if (isEvalNode<ParsedNode>())
+ error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
+ else
+ error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
+ }
}
m_arena->reset();
@@ -1044,16 +1081,16 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
}
template <class ParsedNode>
-PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
+PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
{
SamplingRegion samplingRegion("Parsing");
ASSERT(!source.provider()->source().isNull());
if (source.provider()->source().is8Bit()) {
- Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode);
+ Parser< Lexer<LChar> > parser(vm, source, parameters, name, strictness, parserMode);
return parser.parse<ParsedNode>(error);
}
- Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode);
+ Parser< Lexer<UChar> > parser(vm, source, parameters, name, strictness, parserMode);
return parser.parse<ParsedNode>(error);
}
diff --git a/Source/JavaScriptCore/parser/ParserArena.h b/Source/JavaScriptCore/parser/ParserArena.h
index 2f5b447b1..45d4b158e 100644
--- a/Source/JavaScriptCore/parser/ParserArena.h
+++ b/Source/JavaScriptCore/parser/ParserArena.h
@@ -43,10 +43,10 @@ namespace JSC {
}
template <typename T>
- ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const T* characters, size_t length);
- ALWAYS_INLINE const Identifier& makeIdentifierLCharFromUChar(JSGlobalData*, const UChar* characters, size_t length);
+ ALWAYS_INLINE const Identifier& makeIdentifier(VM*, const T* characters, size_t length);
+ ALWAYS_INLINE const Identifier& makeIdentifierLCharFromUChar(VM*, const UChar* characters, size_t length);
- const Identifier& makeNumericIdentifier(JSGlobalData*, double number);
+ const Identifier& makeNumericIdentifier(VM*, double number);
bool isEmpty() const { return m_identifiers.isEmpty(); }
@@ -69,51 +69,51 @@ namespace JSC {
};
template <typename T>
- ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(JSGlobalData* globalData, const T* characters, size_t length)
+ ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(VM* vm, const T* characters, size_t length)
{
if (characters[0] >= MaximumCachableCharacter) {
- m_identifiers.append(Identifier(globalData, characters, length));
+ m_identifiers.append(Identifier(vm, characters, length));
return m_identifiers.last();
}
if (length == 1) {
if (Identifier* ident = m_shortIdentifiers[characters[0]])
return *ident;
- m_identifiers.append(Identifier(globalData, characters, length));
+ m_identifiers.append(Identifier(vm, characters, length));
m_shortIdentifiers[characters[0]] = &m_identifiers.last();
return m_identifiers.last();
}
Identifier* ident = m_recentIdentifiers[characters[0]];
if (ident && Identifier::equal(ident->impl(), characters, length))
return *ident;
- m_identifiers.append(Identifier(globalData, characters, length));
+ m_identifiers.append(Identifier(vm, characters, length));
m_recentIdentifiers[characters[0]] = &m_identifiers.last();
return m_identifiers.last();
}
- ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifierLCharFromUChar(JSGlobalData* globalData, const UChar* characters, size_t length)
+ ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifierLCharFromUChar(VM* vm, const UChar* characters, size_t length)
{
if (characters[0] >= MaximumCachableCharacter) {
- m_identifiers.append(Identifier::createLCharFromUChar(globalData, characters, length));
+ m_identifiers.append(Identifier::createLCharFromUChar(vm, characters, length));
return m_identifiers.last();
}
if (length == 1) {
if (Identifier* ident = m_shortIdentifiers[characters[0]])
return *ident;
- m_identifiers.append(Identifier(globalData, characters, length));
+ m_identifiers.append(Identifier(vm, characters, length));
m_shortIdentifiers[characters[0]] = &m_identifiers.last();
return m_identifiers.last();
}
Identifier* ident = m_recentIdentifiers[characters[0]];
if (ident && Identifier::equal(ident->impl(), characters, length))
return *ident;
- m_identifiers.append(Identifier::createLCharFromUChar(globalData, characters, length));
+ m_identifiers.append(Identifier::createLCharFromUChar(vm, characters, length));
m_recentIdentifiers[characters[0]] = &m_identifiers.last();
return m_identifiers.last();
}
- inline const Identifier& IdentifierArena::makeNumericIdentifier(JSGlobalData* globalData, double number)
+ inline const Identifier& IdentifierArena::makeNumericIdentifier(VM* vm, double number)
{
- m_identifiers.append(Identifier(globalData, String::numberToStringECMAScript(number)));
+ m_identifiers.append(Identifier(vm, String::numberToStringECMAScript(number)));
return m_identifiers.last();
}
diff --git a/Source/JavaScriptCore/parser/ParserError.h b/Source/JavaScriptCore/parser/ParserError.h
new file mode 100644
index 000000000..baa4465d0
--- /dev/null
+++ b/Source/JavaScriptCore/parser/ParserError.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ParserError_h
+#define ParserError_h
+
+#include "Error.h"
+#include "ExceptionHelpers.h"
+#include "ParserTokens.h"
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+struct ParserError {
+ enum SyntaxErrorType {
+ SyntaxErrorNone,
+ SyntaxErrorIrrecoverable,
+ SyntaxErrorUnterminatedLiteral,
+ SyntaxErrorRecoverable
+ };
+
+ enum ErrorType {
+ ErrorNone,
+ StackOverflow,
+ EvalError,
+ OutOfMemory,
+ SyntaxError
+ };
+
+ ErrorType m_type;
+ SyntaxErrorType m_syntaxErrorType;
+ JSToken m_token;
+ String m_message;
+ int m_line;
+ ParserError()
+ : m_type(ErrorNone)
+ , m_syntaxErrorType(SyntaxErrorNone)
+ , m_line(-1)
+ {
+ }
+
+ explicit ParserError(ErrorType type)
+ : m_type(type)
+ , m_syntaxErrorType(SyntaxErrorNone)
+ , m_line(-1)
+ {
+ }
+
+ ParserError(ErrorType type, SyntaxErrorType syntaxError, JSToken token)
+ : m_type(type)
+ , m_syntaxErrorType(syntaxError)
+ , m_token(token)
+ , m_line(-1)
+ {
+ }
+
+ ParserError(ErrorType type, SyntaxErrorType syntaxError, JSToken token, String msg, int line)
+ : m_type(type)
+ , m_syntaxErrorType(syntaxError)
+ , m_token(token)
+ , m_message(msg)
+ , m_line(line)
+ {
+ }
+
+ JSObject* toErrorObject(JSGlobalObject* globalObject, const SourceCode& source)
+ {
+ switch (m_type) {
+ case ErrorNone:
+ return 0;
+ case SyntaxError:
+ return addErrorInfo(globalObject->globalExec(), createSyntaxError(globalObject, m_message), m_line, source);
+ case EvalError:
+ return createSyntaxError(globalObject, m_message);
+ case StackOverflow:
+ return createStackOverflowError(globalObject);
+ case OutOfMemory:
+ return createOutOfMemoryError(globalObject);
+ }
+ CRASH();
+ return createOutOfMemoryError(globalObject); // Appease Qt bot
+ }
+#undef GET_ERROR_CODE
+};
+
+} // namespace JSC
+
+#endif // ParserError_h
diff --git a/Source/JavaScriptCore/parser/ParserModes.h b/Source/JavaScriptCore/parser/ParserModes.h
index 41fb7fdf9..a7383a3e1 100644
--- a/Source/JavaScriptCore/parser/ParserModes.h
+++ b/Source/JavaScriptCore/parser/ParserModes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,6 +35,21 @@ enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
enum ProfilerMode { ProfilerOff, ProfilerOn };
enum DebuggerMode { DebuggerOff, DebuggerOn };
-}
+enum FunctionNameIsInScopeToggle { FunctionNameIsNotInScope, FunctionNameIsInScope };
-#endif
+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;
+
+const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
+
+} // namespace JSC
+
+#endif // ParserModes_h
diff --git a/Source/JavaScriptCore/parser/ParserTokens.h b/Source/JavaScriptCore/parser/ParserTokens.h
index 14191b95d..ed9780b52 100644
--- a/Source/JavaScriptCore/parser/ParserTokens.h
+++ b/Source/JavaScriptCore/parser/ParserTokens.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,8 @@
#define ParserTokens_h
#include "ParserModes.h"
+#include <limits.h>
+#include <stdint.h>
namespace JSC {
@@ -38,6 +40,8 @@ enum {
BinaryOpTokenPrecedenceShift = 8,
BinaryOpTokenAllowsInPrecedenceAdditionalShift = 4,
BinaryOpTokenPrecedenceMask = 15 << BinaryOpTokenPrecedenceShift,
+ ErrorTokenFlag = 1 << (BinaryOpTokenAllowsInPrecedenceAdditionalShift + BinaryOpTokenPrecedenceShift + 7),
+ UnterminatedErrorTokenFlag = ErrorTokenFlag << 1
};
#define BINARY_OP_PRECEDENCE(prec) (((prec) << BinaryOpTokenPrecedenceShift) | ((prec) << (BinaryOpTokenPrecedenceShift + BinaryOpTokenAllowsInPrecedenceAdditionalShift)))
@@ -85,7 +89,6 @@ enum JSTokenType {
SEMICOLON,
COLON,
DOT,
- ERRORTOK,
EOFTOK,
EQUAL,
PLUSEQUAL,
@@ -133,28 +136,44 @@ enum JSTokenType {
MINUS = 19 | BINARY_OP_PRECEDENCE(9) | UnaryOpTokenFlag,
TIMES = 20 | BINARY_OP_PRECEDENCE(10),
DIVIDE = 21 | BINARY_OP_PRECEDENCE(10),
- MOD = 22 | BINARY_OP_PRECEDENCE(10)
+ MOD = 22 | BINARY_OP_PRECEDENCE(10),
+ ERRORTOK = 0 | ErrorTokenFlag,
+ UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK = 0 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+ INVALID_IDENTIFIER_ESCAPE_ERRORTOK = 1 | ErrorTokenFlag,
+ UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK = 2 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+ INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK = 3 | ErrorTokenFlag,
+ UNTERMINATED_MULTILINE_COMMENT_ERRORTOK = 4 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+ UNTERMINATED_NUMERIC_LITERAL_ERRORTOK = 5 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+ INVALID_OCTAL_NUMBER_ERRORTOK = 6 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+ INVALID_NUMERIC_LITERAL_ERRORTOK = 7 | ErrorTokenFlag,
+ UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
+ INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag,
};
union JSTokenData {
- int intValue;
+ struct {
+ uint32_t line;
+ uint32_t offset;
+ uint32_t lineStartOffset;
+ };
double doubleValue;
const Identifier* ident;
};
struct JSTokenLocation {
- JSTokenLocation() : line(0), column(0) { }
+ JSTokenLocation() : line(0), lineStartOffset(0), startOffset(0) { }
JSTokenLocation(const JSTokenLocation& location)
{
line = location.line;
+ lineStartOffset = location.lineStartOffset;
startOffset = location.startOffset;
endOffset = location.endOffset;
- column = location.column;
}
+
int line;
- int startOffset;
- int endOffset;
- int column;
+ unsigned lineStartOffset;
+ unsigned startOffset;
+ unsigned endOffset;
};
struct JSToken {
@@ -163,7 +182,6 @@ struct JSToken {
JSTokenLocation m_location;
};
-}
-
+} // namespace JSC
#endif // ParserTokens_h
diff --git a/Source/JavaScriptCore/parser/ResultType.h b/Source/JavaScriptCore/parser/ResultType.h
index 8f30e5b64..de4bde66b 100644
--- a/Source/JavaScriptCore/parser/ResultType.h
+++ b/Source/JavaScriptCore/parser/ResultType.h
@@ -62,6 +62,11 @@ namespace JSC {
return (m_type & TypeBits) == TypeMaybeString;
}
+ bool definitelyIsBoolean()
+ {
+ return (m_type & TypeBits) == TypeMaybeBool;
+ }
+
bool mightBeNumber()
{
return m_type & TypeMaybeNumber;
diff --git a/Source/JavaScriptCore/parser/SourceCode.h b/Source/JavaScriptCore/parser/SourceCode.h
index a094469a2..f221f9244 100644
--- a/Source/JavaScriptCore/parser/SourceCode.h
+++ b/Source/JavaScriptCore/parser/SourceCode.h
@@ -41,25 +41,44 @@ namespace JSC {
, m_startChar(0)
, m_endChar(0)
, m_firstLine(0)
+ , m_startColumn(0)
{
}
- SourceCode(PassRefPtr<SourceProvider> provider, int firstLine = 1)
+ SourceCode(WTF::HashTableDeletedValueType)
+ : m_provider(WTF::HashTableDeletedValue)
+ {
+ }
+
+ SourceCode(PassRefPtr<SourceProvider> provider)
+ : m_provider(provider)
+ , m_startChar(0)
+ , m_endChar(m_provider->source().length())
+ , m_firstLine(1)
+ , m_startColumn(1)
+ {
+ }
+
+ SourceCode(PassRefPtr<SourceProvider> provider, int firstLine, int startColumn)
: m_provider(provider)
, m_startChar(0)
, m_endChar(m_provider->source().length())
, m_firstLine(std::max(firstLine, 1))
+ , m_startColumn(std::max(startColumn, 1))
{
}
- SourceCode(PassRefPtr<SourceProvider> provider, int start, int end, int firstLine)
+ SourceCode(PassRefPtr<SourceProvider> provider, int start, int end, int firstLine, int startColumn)
: m_provider(provider)
, m_startChar(start)
, m_endChar(end)
, m_firstLine(std::max(firstLine, 1))
+ , m_startColumn(std::max(startColumn, 1))
{
}
+ bool isHashTableDeletedValue() const { return m_provider.isHashTableDeletedValue(); }
+
String toString() const
{
if (!m_provider)
@@ -77,29 +96,32 @@ namespace JSC {
bool isNull() const { return !m_provider; }
SourceProvider* provider() const { return m_provider.get(); }
int firstLine() const { return m_firstLine; }
+ int startColumn() const { return m_startColumn; }
int startOffset() const { return m_startChar; }
int endOffset() const { return m_endChar; }
int length() const { return m_endChar - m_startChar; }
- SourceCode subExpression(unsigned openBrace, unsigned closeBrace, int firstLine);
+ SourceCode subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn);
private:
RefPtr<SourceProvider> m_provider;
int m_startChar;
int m_endChar;
int m_firstLine;
+ int m_startColumn;
};
inline SourceCode makeSource(const String& source, const String& url = String(), const TextPosition& startPosition = TextPosition::minimumPosition())
{
- return SourceCode(StringSourceProvider::create(source, url, startPosition), startPosition.m_line.oneBasedInt());
+ return SourceCode(StringSourceProvider::create(source, url, startPosition), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt());
}
- inline SourceCode SourceCode::subExpression(unsigned openBrace, unsigned closeBrace, int firstLine)
+ inline SourceCode SourceCode::subExpression(unsigned openBrace, unsigned closeBrace, int firstLine, int startColumn)
{
ASSERT(provider()->source()[openBrace] == '{');
ASSERT(provider()->source()[closeBrace] == '}');
- return SourceCode(provider(), openBrace, closeBrace + 1, firstLine);
+ startColumn += 1; // Convert to base 1.
+ return SourceCode(provider(), openBrace, closeBrace + 1, firstLine, startColumn);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.cpp b/Source/JavaScriptCore/parser/SourceProvider.cpp
index 59de3ff48..47b29aa37 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.cpp
+++ b/Source/JavaScriptCore/parser/SourceProvider.cpp
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 STMicroelectronics. All rights reserved.
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,31 +21,42 @@
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
#include "config.h"
-
-#if ENABLE(ASSEMBLER) && CPU(SH4)
-
-#include "MacroAssemblerSH4.h"
+#include "SourceProvider.h"
+#include <wtf/StdLibExtras.h>
+#include <wtf/TCSpinLock.h>
namespace JSC {
-void MacroAssemblerSH4::linkCall(void* code, Call call, FunctionPtr function)
+SourceProvider::SourceProvider(const String& url, const TextPosition& startPosition)
+ : m_url(url)
+ , m_startPosition(startPosition)
+ , m_validated(false)
+ , m_id(0)
+{
+}
+
+SourceProvider::~SourceProvider()
{
- SH4Assembler::linkCall(code, call.m_label, function.value());
}
-void MacroAssemblerSH4::repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+static inline size_t charPositionExtractor(const size_t* value)
{
- SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+ return *value;
}
-void MacroAssemblerSH4::repatchCall(CodeLocationCall call, FunctionPtr destination)
+static TCMalloc_SpinLock providerIdLock = SPINLOCK_INITIALIZER;
+
+void SourceProvider::getID()
{
- SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+ SpinLockHolder lock(&providerIdLock);
+ if (!m_id) {
+ static intptr_t nextProviderID = 0;
+ m_id = ++nextProviderID;
+ }
}
} // namespace JSC
-#endif // ENABLE(ASSEMBLER)
diff --git a/Source/JavaScriptCore/parser/SourceProvider.h b/Source/JavaScriptCore/parser/SourceProvider.h
index 145b2dd16..4ced9d9c7 100644
--- a/Source/JavaScriptCore/parser/SourceProvider.h
+++ b/Source/JavaScriptCore/parser/SourceProvider.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,11 +29,10 @@
#ifndef SourceProvider_h
#define SourceProvider_h
-#include "SourceProviderCache.h"
#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/UnusedParam.h>
#include <wtf/text/TextPosition.h>
+#include <wtf/text/WTFString.h>
namespace JSC {
@@ -41,20 +40,9 @@ namespace JSC {
public:
static const intptr_t nullID = 1;
- SourceProvider(const String& url, const TextPosition& startPosition, SourceProviderCache* cache = 0)
- : m_url(url)
- , m_startPosition(startPosition)
- , m_validated(false)
- , m_cache(cache ? cache : new SourceProviderCache)
- , m_cacheOwned(!cache)
- {
- }
+ JS_EXPORT_PRIVATE SourceProvider(const String& url, const TextPosition& startPosition);
- virtual ~SourceProvider()
- {
- if (m_cacheOwned)
- delete m_cache;
- }
+ JS_EXPORT_PRIVATE virtual ~SourceProvider();
virtual const String& source() const = 0;
String getRange(int start, int end) const
@@ -69,23 +57,23 @@ namespace JSC {
ASSERT(this);
if (!this) // Be defensive in release mode.
return nullID;
- return reinterpret_cast<intptr_t>(this);
+ if (!m_id)
+ getID();
+ return m_id;
}
bool isValid() const { return m_validated; }
void setValid() { m_validated = true; }
- SourceProviderCache* cache() const { return m_cache; }
- void notifyCacheSizeChanged(int delta) { if (!m_cacheOwned) cacheSizeChanged(delta); }
-
private:
- virtual void cacheSizeChanged(int delta) { UNUSED_PARAM(delta); }
+
+ JS_EXPORT_PRIVATE void getID();
+ Vector<size_t>& lineStarts();
String m_url;
TextPosition m_startPosition;
- bool m_validated;
- SourceProviderCache* m_cache;
- bool m_cacheOwned;
+ bool m_validated : 1;
+ uintptr_t m_id : sizeof(uintptr_t) * 8 - 1;
};
class StringSourceProvider : public SourceProvider {
diff --git a/Source/JavaScriptCore/parser/SourceProviderCache.cpp b/Source/JavaScriptCore/parser/SourceProviderCache.cpp
index ad1cbe02e..f284ee63a 100644
--- a/Source/JavaScriptCore/parser/SourceProviderCache.cpp
+++ b/Source/JavaScriptCore/parser/SourceProviderCache.cpp
@@ -36,18 +36,11 @@ SourceProviderCache::~SourceProviderCache()
void SourceProviderCache::clear()
{
m_map.clear();
- m_contentByteSize = 0;
}
-unsigned SourceProviderCache::byteSize() const
-{
- return m_contentByteSize + sizeof(*this) + m_map.capacity() * sizeof(SourceProviderCacheItem*);
-}
-
-void SourceProviderCache::add(int sourcePosition, PassOwnPtr<SourceProviderCacheItem> item, unsigned size)
+void SourceProviderCache::add(int sourcePosition, PassOwnPtr<SourceProviderCacheItem> item)
{
m_map.add(sourcePosition, item);
- m_contentByteSize += size;
}
}
diff --git a/Source/JavaScriptCore/parser/SourceProviderCache.h b/Source/JavaScriptCore/parser/SourceProviderCache.h
index c346fba0c..06b6c45a2 100644
--- a/Source/JavaScriptCore/parser/SourceProviderCache.h
+++ b/Source/JavaScriptCore/parser/SourceProviderCache.h
@@ -30,23 +30,22 @@
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
namespace JSC {
-class SourceProviderCache {
+class SourceProviderCache : public RefCounted<SourceProviderCache> {
WTF_MAKE_FAST_ALLOCATED;
public:
- SourceProviderCache() : m_contentByteSize(0) {}
+ SourceProviderCache() { }
JS_EXPORT_PRIVATE ~SourceProviderCache();
JS_EXPORT_PRIVATE void clear();
- JS_EXPORT_PRIVATE unsigned byteSize() const;
- void add(int sourcePosition, PassOwnPtr<SourceProviderCacheItem>, unsigned size);
+ void add(int sourcePosition, PassOwnPtr<SourceProviderCacheItem>);
const SourceProviderCacheItem* get(int sourcePosition) const { return m_map.get(sourcePosition); }
private:
HashMap<int, OwnPtr<SourceProviderCacheItem> > m_map;
- unsigned m_contentByteSize;
};
}
diff --git a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
index ec3890560..8d35a3d27 100644
--- a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
+++ b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
@@ -27,37 +27,46 @@
#define SourceProviderCacheItem_h
#include "ParserTokens.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace JSC {
+struct SourceProviderCacheItemCreationParameters {
+ unsigned functionStart;
+ unsigned closeBraceLine;
+ unsigned closeBraceOffset;
+ unsigned closeBraceLineStartOffset;
+ bool needsFullActivation;
+ bool usesEval;
+ bool strictMode;
+ Vector<RefPtr<StringImpl> > usedVariables;
+ Vector<RefPtr<StringImpl> > writtenVariables;
+};
+
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
+#endif
+
class SourceProviderCacheItem {
WTF_MAKE_FAST_ALLOCATED;
public:
- SourceProviderCacheItem(unsigned functionStart, unsigned closeBraceLine, unsigned closeBracePos)
- : functionStart(functionStart)
- , closeBraceLine(closeBraceLine)
- , closeBracePos(closeBracePos)
- {
- }
- unsigned approximateByteSize() const
- {
- // The identifiers are uniqued strings so most likely there are few names that actually use any additional memory.
- static const unsigned assummedAverageIdentifierSize = sizeof(RefPtr<StringImpl>) + 2;
- unsigned size = sizeof(*this);
- size += usedVariables.size() * assummedAverageIdentifierSize;
- size += writtenVariables.size() * assummedAverageIdentifierSize;
- return size;
- }
+ static PassOwnPtr<SourceProviderCacheItem> create(const SourceProviderCacheItemCreationParameters&);
+ ~SourceProviderCacheItem();
+
JSToken closeBraceToken() const
{
JSToken token;
token.m_type = CLOSEBRACE;
- token.m_data.intValue = closeBracePos;
- token.m_location.startOffset = closeBracePos;
- token.m_location.endOffset = closeBracePos + 1;
+ token.m_data.offset = closeBraceOffset;
+ token.m_location.startOffset = closeBraceOffset;
+ token.m_location.endOffset = closeBraceOffset + 1;
token.m_location.line = closeBraceLine;
+ token.m_location.lineStartOffset = closeBraceLineStartOffset;
+ // token.m_location.sourceOffset is initialized once by the client. So,
+ // we do not need to set it here.
return token;
}
@@ -67,13 +76,62 @@ public:
unsigned closeBraceLine : 31;
bool usesEval : 1;
- unsigned closeBracePos : 31;
+ unsigned closeBraceOffset : 31;
bool strictMode : 1;
- Vector<RefPtr<StringImpl> > usedVariables;
- Vector<RefPtr<StringImpl> > writtenVariables;
+ unsigned closeBraceLineStartOffset;
+ unsigned usedVariablesCount;
+ unsigned writtenVariablesCount;
+
+ StringImpl** usedVariables() const { return const_cast<StringImpl**>(m_variables); }
+ StringImpl** writtenVariables() const { return const_cast<StringImpl**>(&m_variables[usedVariablesCount]); }
+
+private:
+ SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters&);
+
+ StringImpl* m_variables[0];
};
+inline SourceProviderCacheItem::~SourceProviderCacheItem()
+{
+ for (unsigned i = 0; i < usedVariablesCount + writtenVariablesCount; ++i)
+ m_variables[i]->deref();
+}
+
+inline PassOwnPtr<SourceProviderCacheItem> SourceProviderCacheItem::create(const SourceProviderCacheItemCreationParameters& parameters)
+{
+ size_t variableCount = parameters.writtenVariables.size() + parameters.usedVariables.size();
+ size_t objectSize = sizeof(SourceProviderCacheItem) + sizeof(StringImpl*) * variableCount;
+ void* slot = fastMalloc(objectSize);
+ return adoptPtr(new (slot) SourceProviderCacheItem(parameters));
+}
+
+inline SourceProviderCacheItem::SourceProviderCacheItem(const SourceProviderCacheItemCreationParameters& parameters)
+ : functionStart(parameters.functionStart)
+ , needsFullActivation(parameters.needsFullActivation)
+ , closeBraceLine(parameters.closeBraceLine)
+ , usesEval(parameters.usesEval)
+ , closeBraceOffset(parameters.closeBraceOffset)
+ , strictMode(parameters.strictMode)
+ , closeBraceLineStartOffset(parameters.closeBraceLineStartOffset)
+ , usedVariablesCount(parameters.usedVariables.size())
+ , writtenVariablesCount(parameters.writtenVariables.size())
+{
+ unsigned j = 0;
+ for (unsigned i = 0; i < usedVariablesCount; ++i, ++j) {
+ m_variables[j] = parameters.usedVariables[i].get();
+ m_variables[j]->ref();
+ }
+ for (unsigned i = 0; i < writtenVariablesCount; ++i, ++j) {
+ m_variables[j] = parameters.writtenVariables[i].get();
+ m_variables[j]->ref();
+ }
+}
+
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
}
#endif // SourceProviderCacheItem_h
diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h
index 0e6889752..7f902c0fd 100644
--- a/Source/JavaScriptCore/parser/SyntaxChecker.h
+++ b/Source/JavaScriptCore/parser/SyntaxChecker.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -64,7 +64,7 @@ public:
SyntaxChecker* m_context;
};
- SyntaxChecker(JSGlobalData* , void*)
+ SyntaxChecker(VM* , void*)
{
}
@@ -119,21 +119,21 @@ public:
static const unsigned DontBuildStrings = LexerFlagsDontBuildStrings;
int createSourceElements() { return 1; }
- ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int) { return CallExpr; }
+ ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int, int, int) { return CallExpr; }
void appendToComma(ExpressionType& base, ExpressionType right) { base = right; }
ExpressionType createCommaExpr(const JSTokenLocation&, ExpressionType, ExpressionType right) { return right; }
- ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
- ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PreExpr; }
- ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PostExpr; }
+ ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int, int, int) { return AssignmentExpr; }
+ ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int, int, int) { return PreExpr; }
+ ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int, int, int) { return PostExpr; }
ExpressionType makeTypeOfNode(const JSTokenLocation&, ExpressionType) { return TypeofExpr; }
- ExpressionType makeDeleteNode(const JSTokenLocation&, ExpressionType, int, int, int) { return DeleteExpr; }
+ ExpressionType makeDeleteNode(const JSTokenLocation&, ExpressionType, int, int, int, int, int) { return DeleteExpr; }
ExpressionType makeNegateNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType makeBitwiseNotNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType createLogicalNot(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType createUnaryPlus(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; }
- ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; }
+ ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int, int, int) { return ResolveExpr; }
ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; }
ExpressionType createObjectLiteral(const JSTokenLocation&, int) { return ObjectLiteralExpr; }
ExpressionType createArray(const JSTokenLocation&, int) { return ArrayLiteralExpr; }
@@ -142,15 +142,16 @@ public:
ExpressionType createString(const JSTokenLocation&, const Identifier*) { return StringExpr; }
ExpressionType createBoolean(const JSTokenLocation&, bool) { return BoolExpr; }
ExpressionType createNull(const JSTokenLocation&) { return NullExpr; }
- ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
- ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int) { return DotExpr; }
- ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.string()) ? 0 : RegExpExpr; }
+ ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int, int, int) { return BracketExpr; }
+ ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int, int, int) { return DotExpr; }
+ ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier&, int, int, int) { return Yarr::checkSyntax(pattern.string()) ? 0 : RegExpExpr; }
+ ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int, int, int) { return NewExpr; }
ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int) { return NewExpr; }
- ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int) { return NewExpr; }
ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
- ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
- ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int) { return FunctionExpr; }
- int createFunctionBody(const JSTokenLocation&, bool) { return 1; }
+ ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int, int, int) { return AssignmentExpr; }
+ ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return FunctionExpr; }
+ int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, bool) { return 1; }
+ void setFunctionStart(int, int) { }
int createArguments() { return 1; }
int createArguments(int) { return 1; }
int createArgumentsList(const JSTokenLocation&, int) { return 1; }
@@ -162,11 +163,11 @@ public:
ASSERT(name);
return Property(name, type);
}
- template <bool complete> Property createProperty(JSGlobalData* globalData, double name, int, PropertyNode::Type type)
+ template <bool complete> Property createProperty(VM* vm, double name, int, PropertyNode::Type type)
{
if (!complete)
return Property(type);
- return Property(&globalData->parserArena->identifierArena().makeNumericIdentifier(globalData, name), type);
+ return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
}
int createPropertyList(const JSTokenLocation&, Property) { return 1; }
int createPropertyList(const JSTokenLocation&, Property, int) { return 1; }
@@ -178,50 +179,50 @@ public:
int createClauseList(int) { return 1; }
int createClauseList(int, int) { return 1; }
void setUsesArguments(int) { }
- int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int) { return 1; }
+ int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return 1; }
int createBlockStatement(const JSTokenLocation&, int, int, int) { return 1; }
int createExprStatement(const JSTokenLocation&, int, int, int) { return 1; }
int createIfStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
int createForLoop(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
- int createForInLoop(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; }
- int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
+ int createForInLoop(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int, int, int, int, int) { return 1; }
+ int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int, int, int) { return 1; }
int createEmptyStatement(const JSTokenLocation&) { return 1; }
int createVarStatement(const JSTokenLocation&, int, int, int) { return 1; }
- int createReturnStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
- int createBreakStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
- int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int, int, int) { return 1; }
- int createContinueStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
- int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int, int, int) { return 1; }
+ int createReturnStatement(const JSTokenLocation&, int, int, int, int, int, int, int) { return 1; }
+ int createBreakStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
+ int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int) { return 1; }
+ int createContinueStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
+ int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int) { return 1; }
int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int) { return 1; }
int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
- int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
+ int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
int createDoWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
- int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int) { return 1; }
- int createThrowStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
+ int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int) { return 1; }
+ int createThrowStatement(const JSTokenLocation&, int, int, int, int, int, int, int) { return 1; }
int createDebugger(const JSTokenLocation&, int, int) { return 1; }
int createConstStatement(const JSTokenLocation&, int, int, int) { return 1; }
int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return 1; }
- template <bool strict> Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int)
+ template <bool strict> Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int, int)
{
ASSERT(name);
if (!strict)
return Property(type);
return Property(name, type);
}
- template <bool strict> Property createGetterOrSetterProperty(JSGlobalData* globalData, const JSTokenLocation&, PropertyNode::Type type, double name, int, int, int, int, int, int)
+ template <bool strict> Property createGetterOrSetterProperty(VM* vm, const JSTokenLocation&, PropertyNode::Type type, double name, int, int, int, int, int, int, int)
{
if (!strict)
return Property(type);
- return Property(&globalData->parserArena->identifierArena().makeNumericIdentifier(globalData, name), type);
+ return Property(&vm->parserArena->identifierArena().makeNumericIdentifier(vm, name), type);
}
void appendStatement(int, int) { }
void addVar(const Identifier*, bool) { }
int combineCommaNodes(const JSTokenLocation&, int, int) { return 1; }
int evalCount() const { return 0; }
- void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
+ void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, int, int, bool)
{
if (!m_topBinaryExpr)
m_topBinaryExpr = expr;
@@ -239,13 +240,14 @@ public:
void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; }
int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; }
- void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; }
+ void appendUnaryToken(int& stackDepth, int tok, int, int, int) { stackDepth = 1; m_topUnaryToken = tok; }
int unaryTokenStackLastType(int&) { return m_topUnaryToken; }
- int unaryTokenStackLastStart(int&) { return 0; }
+ unsigned unaryTokenStackLastStart(int&) { return 0; }
+ unsigned unaryTokenStackLastLineStartPosition(int&) { return 0; }
void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; }
- void assignmentStackAppend(int, int, int, int, int, Operator) { }
- int createAssignment(const JSTokenLocation&, int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; }
+ void assignmentStackAppend(int, int, int, int, int, int, int, Operator) { }
+ int createAssignment(const JSTokenLocation&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return 1; }
const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; }
PropertyNode::Type getType(const Property& property) const { return property.type; }
bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; }
diff --git a/Source/JavaScriptCore/profiler/Profiler.cpp b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp
index 9642a0684..1db2e625e 100644
--- a/Source/JavaScriptCore/profiler/Profiler.cpp
+++ b/Source/JavaScriptCore/profiler/LegacyProfiler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,15 +27,16 @@
*/
#include "config.h"
-#include "Profiler.h"
+#include "LegacyProfiler.h"
-#include "CommonIdentifiers.h"
#include "CallFrame.h"
#include "CodeBlock.h"
+#include "CommonIdentifiers.h"
#include "InternalFunction.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Nodes.h"
+#include "Operations.h"
#include "Profile.h"
#include "ProfileGenerator.h"
#include "ProfileNode.h"
@@ -49,22 +50,25 @@ static unsigned ProfilesUID = 0;
static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSObject*, const String& defaultSourceURL, int defaultLineNumber);
-Profiler* Profiler::s_sharedProfiler = 0;
+LegacyProfiler* LegacyProfiler::s_sharedLegacyProfiler = 0;
-Profiler* Profiler::profiler()
+LegacyProfiler* LegacyProfiler::profiler()
{
- if (!s_sharedProfiler)
- s_sharedProfiler = new Profiler();
- return s_sharedProfiler;
+ if (!s_sharedLegacyProfiler)
+ s_sharedLegacyProfiler = new LegacyProfiler();
+ return s_sharedLegacyProfiler;
}
-void Profiler::startProfiling(ExecState* exec, const String& title)
+void LegacyProfiler::startProfiling(ExecState* exec, const String& title)
{
ASSERT_ARG(title, !title.isNull());
+ if (!exec)
+ return;
+
// Check if we currently have a Profile for this global ExecState and title.
// If so return early and don't create a new Profile.
- JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
+ JSGlobalObject* origin = exec->lexicalGlobalObject();
for (size_t i = 0; i < m_currentProfiles.size(); ++i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
@@ -72,14 +76,17 @@ void Profiler::startProfiling(ExecState* exec, const String& title)
return;
}
- exec->globalData().m_enabledProfiler = this;
+ exec->vm().m_enabledProfiler = this;
RefPtr<ProfileGenerator> profileGenerator = ProfileGenerator::create(exec, title, ++ProfilesUID);
m_currentProfiles.append(profileGenerator);
}
-PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title)
+PassRefPtr<Profile> LegacyProfiler::stopProfiling(ExecState* exec, const String& title)
{
- JSGlobalObject* origin = exec ? exec->lexicalGlobalObject() : 0;
+ if (!exec)
+ return 0;
+
+ JSGlobalObject* origin = exec->lexicalGlobalObject();
for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
if (profileGenerator->origin() == origin && (title.isNull() || profileGenerator->title() == title)) {
@@ -88,7 +95,7 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title
m_currentProfiles.remove(i);
if (!m_currentProfiles.size())
- exec->globalData().m_enabledProfiler = 0;
+ exec->vm().m_enabledProfiler = 0;
return returnProfile;
}
@@ -97,7 +104,7 @@ PassRefPtr<Profile> Profiler::stopProfiling(ExecState* exec, const String& title
return 0;
}
-void Profiler::stopProfiling(JSGlobalObject* origin)
+void LegacyProfiler::stopProfiling(JSGlobalObject* origin)
{
for (ptrdiff_t i = m_currentProfiles.size() - 1; i >= 0; --i) {
ProfileGenerator* profileGenerator = m_currentProfiles[i].get();
@@ -105,7 +112,7 @@ void Profiler::stopProfiling(JSGlobalObject* origin)
profileGenerator->stopProfiling();
m_currentProfiles.remove(i);
if (!m_currentProfiles.size())
- origin->globalData().m_enabledProfiler = 0;
+ origin->vm().m_enabledProfiler = 0;
}
}
}
@@ -118,14 +125,14 @@ static inline void dispatchFunctionToProfiles(ExecState* callerOrHandlerCallFram
}
}
-void Profiler::willExecute(ExecState* callerCallFrame, JSValue function)
+void LegacyProfiler::willExecute(ExecState* callerCallFrame, JSValue function)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
+void LegacyProfiler::willExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
{
ASSERT(!m_currentProfiles.isEmpty());
@@ -134,28 +141,28 @@ void Profiler::willExecute(ExecState* callerCallFrame, const String& sourceURL,
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::didExecute(ExecState* callerCallFrame, JSValue function)
+void LegacyProfiler::didExecute(ExecState* callerCallFrame, JSValue function)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, function, "", 0), callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
+void LegacyProfiler::didExecute(ExecState* callerCallFrame, const String& sourceURL, int startingLineNumber)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(callerCallFrame, m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(callerCallFrame, JSValue(), sourceURL, startingLineNumber), callerCallFrame->lexicalGlobalObject()->profileGroup());
}
-void Profiler::exceptionUnwind(ExecState* handlerCallFrame)
+void LegacyProfiler::exceptionUnwind(ExecState* handlerCallFrame)
{
ASSERT(!m_currentProfiles.isEmpty());
dispatchFunctionToProfiles(handlerCallFrame, m_currentProfiles, &ProfileGenerator::exceptionUnwind, createCallIdentifier(handlerCallFrame, JSValue(), "", 0), handlerCallFrame->lexicalGlobalObject()->profileGroup());
}
-CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber)
+CallIdentifier LegacyProfiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const String& defaultSourceURL, int defaultLineNumber)
{
if (!functionValue)
return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber);
diff --git a/Source/JavaScriptCore/profiler/Profiler.h b/Source/JavaScriptCore/profiler/LegacyProfiler.h
index 6852457c7..6db57cbf2 100644
--- a/Source/JavaScriptCore/profiler/Profiler.h
+++ b/Source/JavaScriptCore/profiler/LegacyProfiler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,8 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Profiler_h
-#define Profiler_h
+#ifndef LegacyProfiler_h
+#define LegacyProfiler_h
#include "Profile.h"
#include <wtf/PassRefPtr.h>
@@ -36,38 +36,38 @@
namespace JSC {
- class ExecState;
- class JSGlobalData;
- class JSGlobalObject;
- class JSObject;
- class JSValue;
- class ProfileGenerator;
- struct CallIdentifier;
+class ExecState;
+class VM;
+class JSGlobalObject;
+class JSObject;
+class JSValue;
+class ProfileGenerator;
+struct CallIdentifier;
- class Profiler {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- JS_EXPORT_PRIVATE static Profiler* profiler();
- static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, int lineNumber);
+class LegacyProfiler {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ JS_EXPORT_PRIVATE static LegacyProfiler* profiler();
+ static CallIdentifier createCallIdentifier(ExecState*, JSValue, const WTF::String& sourceURL, int lineNumber);
- JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title);
- JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title);
- void stopProfiling(JSGlobalObject*);
+ JS_EXPORT_PRIVATE void startProfiling(ExecState*, const WTF::String& title);
+ JS_EXPORT_PRIVATE PassRefPtr<Profile> stopProfiling(ExecState*, const WTF::String& title);
+ void stopProfiling(JSGlobalObject*);
- void willExecute(ExecState* callerCallFrame, JSValue function);
- void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
- void didExecute(ExecState* callerCallFrame, JSValue function);
- void didExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
+ void willExecute(ExecState* callerCallFrame, JSValue function);
+ void willExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
+ void didExecute(ExecState* callerCallFrame, JSValue function);
+ void didExecute(ExecState* callerCallFrame, const WTF::String& sourceURL, int startingLineNumber);
- void exceptionUnwind(ExecState* handlerCallFrame);
+ void exceptionUnwind(ExecState* handlerCallFrame);
- const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; };
+ const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; };
- private:
- Vector<RefPtr<ProfileGenerator> > m_currentProfiles;
- static Profiler* s_sharedProfiler;
- };
+private:
+ Vector<RefPtr<ProfileGenerator> > m_currentProfiles;
+ static LegacyProfiler* s_sharedLegacyProfiler;
+};
} // namespace JSC
-#endif // Profiler_h
+#endif // LegacyProfiler_h
diff --git a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
index 09877d3c8..d240aff34 100644
--- a/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/Source/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -32,8 +32,9 @@
#include "JSStringRef.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "LegacyProfiler.h"
+#include "Operations.h"
#include "Profile.h"
-#include "Profiler.h"
#include "Tracing.h"
namespace JSC {
@@ -63,7 +64,7 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
JSValue function;
exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
- m_currentNode = ProfileNode::create(exec, Profiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
+ m_currentNode = ProfileNode::create(exec, LegacyProfiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
m_head->insertNode(m_currentNode.get());
}
diff --git a/Source/JavaScriptCore/profiler/ProfileNode.cpp b/Source/JavaScriptCore/profiler/ProfileNode.cpp
index 6c36e47d0..5b6a25411 100644
--- a/Source/JavaScriptCore/profiler/ProfileNode.cpp
+++ b/Source/JavaScriptCore/profiler/ProfileNode.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "ProfileNode.h"
-#include "Profiler.h"
+#include "LegacyProfiler.h"
#include <stdio.h>
#include <wtf/DateMath.h>
#include <wtf/DataLog.h>
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
new file mode 100644
index 000000000..ca602e42f
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 "ProfilerBytecode.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+JSValue Bytecode::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
+ result->putDirect(exec->vm(), exec->propertyNames().opcode, jsString(exec, String::fromUTF8(opcodeNames[m_opcodeID])));
+ result->putDirect(exec->vm(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description)));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecode.h b/Source/JavaScriptCore/profiler/ProfilerBytecode.h
new file mode 100644
index 000000000..8e99c9a09
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecode.h
@@ -0,0 +1,65 @@
+/*
+ * 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 ProfilerBytecode_h
+#define ProfilerBytecode_h
+
+#include "JSCJSValue.h"
+#include "Opcode.h"
+#include <wtf/text/CString.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecode {
+public:
+ Bytecode()
+ : m_bytecodeIndex(std::numeric_limits<unsigned>::max())
+ {
+ }
+
+ Bytecode(unsigned bytecodeIndex, OpcodeID opcodeID, const CString& description)
+ : m_bytecodeIndex(bytecodeIndex)
+ , m_opcodeID(opcodeID)
+ , m_description(description)
+ {
+ }
+
+ unsigned bytecodeIndex() const { return m_bytecodeIndex; }
+ OpcodeID opcodeID() const { return m_opcodeID; }
+ const CString& description() const { return m_description; }
+
+ JSValue toJS(ExecState*) const;
+private:
+ unsigned m_bytecodeIndex;
+ OpcodeID m_opcodeID;
+ CString m_description;
+};
+
+inline unsigned getBytecodeIndexForBytecode(Bytecode* bytecode) { return bytecode->bytecodeIndex(); }
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerBytecode_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
new file mode 100644
index 000000000..a98b8bace
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 "ProfilerBytecodeSequence.h"
+
+#include "CodeBlock.h"
+#include "JSGlobalObject.h"
+#include "Operands.h"
+#include "Operations.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+BytecodeSequence::BytecodeSequence(CodeBlock* codeBlock)
+{
+ StringPrintStream out;
+
+#if ENABLE(VALUE_PROFILER)
+ for (unsigned i = 0; i < codeBlock->numberOfArgumentValueProfiles(); ++i) {
+ CString description = codeBlock->valueProfileForArgument(i)->briefDescription();
+ if (!description.length())
+ continue;
+ out.reset();
+ out.print("arg", i, " (r", argumentToOperand(i), "): ", description);
+ m_header.append(out.toCString());
+ }
+#endif // ENABLE(VALUE_PROFILER)
+
+ for (unsigned bytecodeIndex = 0; bytecodeIndex < codeBlock->instructions().size();) {
+ out.reset();
+ codeBlock->dumpBytecode(out, bytecodeIndex);
+ m_sequence.append(Bytecode(bytecodeIndex, codeBlock->vm()->interpreter->getOpcodeID(codeBlock->instructions()[bytecodeIndex].u.opcode), out.toCString()));
+ bytecodeIndex += opcodeLength(
+ codeBlock->vm()->interpreter->getOpcodeID(
+ codeBlock->instructions()[bytecodeIndex].u.opcode));
+ }
+}
+
+BytecodeSequence::~BytecodeSequence()
+{
+}
+
+unsigned BytecodeSequence::indexForBytecodeIndex(unsigned bytecodeIndex) const
+{
+ return binarySearch<Bytecode, unsigned>(m_sequence, m_sequence.size(), bytecodeIndex, getBytecodeIndexForBytecode) - m_sequence.begin();
+}
+
+const Bytecode& BytecodeSequence::forBytecodeIndex(unsigned bytecodeIndex) const
+{
+ return at(indexForBytecodeIndex(bytecodeIndex));
+}
+
+void BytecodeSequence::addSequenceProperties(ExecState* exec, JSObject* result) const
+{
+ JSArray* header = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_header.size(); ++i)
+ header->putDirectIndex(exec, i, jsString(exec, String::fromUTF8(m_header[i])));
+ result->putDirect(exec->vm(), exec->propertyNames().header, header);
+
+ JSArray* sequence = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_sequence.size(); ++i)
+ sequence->putDirectIndex(exec, i, m_sequence[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecode, sequence);
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
new file mode 100644
index 000000000..1d5c82a18
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.h
@@ -0,0 +1,65 @@
+/*
+ * 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 ProfilerBytecodeSequence_h
+#define ProfilerBytecodeSequence_h
+
+#include "JSCJSValue.h"
+#include "ProfilerBytecode.h"
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+namespace Profiler {
+
+class BytecodeSequence {
+public:
+ BytecodeSequence(CodeBlock*);
+ ~BytecodeSequence();
+
+ // Note that this data structure is not indexed by bytecode index.
+ unsigned size() const { return m_sequence.size(); }
+ const Bytecode& at(unsigned i) const { return m_sequence[i]; }
+
+ unsigned indexForBytecodeIndex(unsigned bytecodeIndex) const;
+ const Bytecode& forBytecodeIndex(unsigned bytecodeIndex) const;
+
+protected:
+ void addSequenceProperties(ExecState*, JSObject*) const;
+
+private:
+ Vector<CString> m_header;
+ Vector<Bytecode> m_sequence;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerBytecodeSequence_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
new file mode 100644
index 000000000..3ae35dcc0
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "ProfilerBytecodes.h"
+
+#include "CodeBlock.h"
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+Bytecodes::Bytecodes(size_t id, CodeBlock* codeBlock)
+ : BytecodeSequence(codeBlock)
+ , m_id(id)
+ , m_inferredName(codeBlock->inferredName())
+ , m_sourceCode(codeBlock->sourceCodeForTools())
+ , m_hash(codeBlock->hash())
+ , m_instructionCount(codeBlock->instructionCount())
+{
+}
+
+Bytecodes::~Bytecodes() { }
+
+void Bytecodes::dump(PrintStream& out) const
+{
+ out.print("#", m_hash, "(", m_id, ")");
+}
+
+JSValue Bytecodes::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_id));
+ result->putDirect(exec->vm(), exec->propertyNames().inferredName, jsString(exec, m_inferredName));
+ result->putDirect(exec->vm(), exec->propertyNames().sourceCode, jsString(exec, m_sourceCode));
+ result->putDirect(exec->vm(), exec->propertyNames().hash, jsString(exec, String::fromUTF8(toCString(m_hash))));
+ result->putDirect(exec->vm(), exec->propertyNames().instructionCount, jsNumber(m_instructionCount));
+ addSequenceProperties(exec, result);
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
new file mode 100644
index 000000000..47d856cb4
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerBytecodes.h
@@ -0,0 +1,63 @@
+/*
+ * 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 ProfilerBytecodes_h
+#define ProfilerBytecodes_h
+
+#include "CodeBlockHash.h"
+#include "JSCJSValue.h"
+#include "ProfilerBytecodeSequence.h"
+#include <wtf/PrintStream.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecodes : public BytecodeSequence {
+public:
+ Bytecodes(size_t id, CodeBlock*);
+ ~Bytecodes();
+
+ size_t id() const { return m_id; }
+ const String& inferredName() const { return m_inferredName; }
+ const String& sourceCode() const { return m_sourceCode; }
+ unsigned instructionCount() const { return m_instructionCount; }
+ CodeBlockHash hash() const { return m_hash; }
+
+ void dump(PrintStream&) const;
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ size_t m_id;
+ String m_inferredName;
+ String m_sourceCode;
+ CodeBlockHash m_hash;
+ unsigned m_instructionCount;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerBytecodes_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
new file mode 100644
index 000000000..f82414ffa
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerCompilation.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include "ProfilerDatabase.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+Compilation::Compilation(Bytecodes* bytecodes, CompilationKind kind)
+ : m_bytecodes(bytecodes)
+ , m_kind(kind)
+ , m_numInlinedGetByIds(0)
+ , m_numInlinedPutByIds(0)
+ , m_numInlinedCalls(0)
+{
+}
+
+Compilation::~Compilation() { }
+
+void Compilation::addProfiledBytecodes(Database& database, CodeBlock* profiledBlock)
+{
+ Bytecodes* bytecodes = database.ensureBytecodesFor(profiledBlock);
+
+ // First make sure that we haven't already added profiled bytecodes for this code
+ // block. We do this using an O(N) search because I suspect that this list will
+ // tend to be fairly small, and the additional space costs of having a HashMap/Set
+ // would be greater than the time cost of occasionally doing this search.
+
+ for (unsigned i = m_profiledBytecodes.size(); i--;) {
+ if (m_profiledBytecodes[i].bytecodes() == bytecodes)
+ return;
+ }
+
+ m_profiledBytecodes.append(ProfiledBytecodes(bytecodes, profiledBlock));
+}
+
+void Compilation::addDescription(const CompiledBytecode& compiledBytecode)
+{
+ m_descriptions.append(compiledBytecode);
+}
+
+ExecutionCounter* Compilation::executionCounterFor(const OriginStack& origin)
+{
+ HashMap<OriginStack, OwnPtr<ExecutionCounter> >::iterator iter = m_counters.find(origin);
+ if (iter != m_counters.end())
+ return iter->value.get();
+
+ OwnPtr<ExecutionCounter> counter = adoptPtr(new ExecutionCounter());
+ ExecutionCounter* result = counter.get();
+ m_counters.add(origin, counter.release());
+ return result;
+}
+
+void Compilation::addOSRExitSite(const Vector<const void*>& codeAddresses)
+{
+ m_osrExitSites.append(OSRExitSite(codeAddresses));
+}
+
+OSRExit* Compilation::addOSRExit(unsigned id, const OriginStack& originStack, ExitKind exitKind, bool isWatchpoint)
+{
+ m_osrExits.append(OSRExit(id, originStack, exitKind, isWatchpoint));
+ return &m_osrExits.last();
+}
+
+JSValue Compilation::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ result->putDirect(exec->vm(), exec->propertyNames().compilationKind, jsString(exec, String::fromUTF8(toCString(m_kind))));
+
+ JSArray* profiledBytecodes = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i)
+ profiledBytecodes->putDirectIndex(exec, i, m_profiledBytecodes[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().profiledBytecodes, profiledBytecodes);
+
+ JSArray* descriptions = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_descriptions.size(); ++i)
+ descriptions->putDirectIndex(exec, i, m_descriptions[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().descriptions, descriptions);
+
+ JSArray* counters = constructEmptyArray(exec, 0);
+ HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator end = m_counters.end();
+ for (HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator iter = m_counters.begin(); iter != end; ++iter) {
+ JSObject* counterEntry = constructEmptyObject(exec);
+ counterEntry->putDirect(exec->vm(), exec->propertyNames().origin, iter->key.toJS(exec));
+ counterEntry->putDirect(exec->vm(), exec->propertyNames().executionCount, jsNumber(iter->value->count()));
+ counters->push(exec, counterEntry);
+ }
+ result->putDirect(exec->vm(), exec->propertyNames().counters, counters);
+
+ JSArray* exitSites = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_osrExitSites.size(); ++i)
+ exitSites->putDirectIndex(exec, i, m_osrExitSites[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().osrExitSites, exitSites);
+
+ JSArray* exits = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_osrExits.size(); ++i)
+ exits->putDirectIndex(exec, i, m_osrExits[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().osrExits, exits);
+
+ result->putDirect(exec->vm(), exec->propertyNames().numInlinedGetByIds, jsNumber(m_numInlinedGetByIds));
+ result->putDirect(exec->vm(), exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
+ result->putDirect(exec->vm(), exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilation.h b/Source/JavaScriptCore/profiler/ProfilerCompilation.h
new file mode 100644
index 000000000..b3183fa02
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilation.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerCompilation_h
+#define ProfilerCompilation_h
+
+#include "ExitKind.h"
+#include "JSCJSValue.h"
+#include "ProfilerCompilationKind.h"
+#include "ProfilerCompiledBytecode.h"
+#include "ProfilerExecutionCounter.h"
+#include "ProfilerOSRExit.h"
+#include "ProfilerOSRExitSite.h"
+#include "ProfilerOriginStack.h"
+#include "ProfilerProfiledBytecodes.h"
+#include <wtf/RefCounted.h>
+#include <wtf/SegmentedVector.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecodes;
+class Database;
+
+// Represents the act of executing some bytecodes in some engine, and does
+// all of the counting for those executions.
+
+class Compilation : public RefCounted<Compilation> {
+public:
+ Compilation(Bytecodes*, CompilationKind);
+ ~Compilation();
+
+ void addProfiledBytecodes(Database&, CodeBlock*);
+ unsigned profiledBytecodesSize() const { return m_profiledBytecodes.size(); }
+ const ProfiledBytecodes& profiledBytecodesAt(unsigned i) const { return m_profiledBytecodes[i]; }
+
+ void noticeInlinedGetById() { m_numInlinedGetByIds++; }
+ void noticeInlinedPutById() { m_numInlinedPutByIds++; }
+ void noticeInlinedCall() { m_numInlinedCalls++; }
+
+ Bytecodes* bytecodes() const { return m_bytecodes; }
+ CompilationKind kind() const { return m_kind; }
+
+ void addDescription(const CompiledBytecode&);
+ ExecutionCounter* executionCounterFor(const OriginStack&);
+ void addOSRExitSite(const Vector<const void*>& codeAddresses);
+ OSRExit* addOSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint);
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ Bytecodes* m_bytecodes;
+ CompilationKind m_kind;
+ Vector<ProfiledBytecodes> m_profiledBytecodes;
+ Vector<CompiledBytecode> m_descriptions;
+ HashMap<OriginStack, OwnPtr<ExecutionCounter> > m_counters;
+ Vector<OSRExitSite> m_osrExitSites;
+ SegmentedVector<OSRExit> m_osrExits;
+ unsigned m_numInlinedGetByIds;
+ unsigned m_numInlinedPutByIds;
+ unsigned m_numInlinedCalls;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerCompilation_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
new file mode 100644
index 000000000..78ce70586
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "ProfilerCompilationKind.h"
+
+#include <wtf/PrintStream.h>
+
+namespace WTF {
+
+void printInternal(PrintStream& out, JSC::Profiler::CompilationKind kind)
+{
+ switch (kind) {
+ case JSC::Profiler::LLInt:
+ out.print("LLInt");
+ return;
+ case JSC::Profiler::Baseline:
+ out.print("Baseline");
+ return;
+ case JSC::Profiler::DFG:
+ out.print("DFG");
+ return;
+ default:
+ CRASH();
+ return;
+ }
+}
+
+} // namespace WTF
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
new file mode 100644
index 000000000..4806d39b9
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompilationKind.h
@@ -0,0 +1,47 @@
+/*
+ * 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 ProfilerCompilationKind_h
+#define ProfilerCompilationKind_h
+
+namespace JSC { namespace Profiler {
+
+enum CompilationKind {
+ LLInt,
+ Baseline,
+ DFG
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+class PrintStream;
+void printInternal(PrintStream&, JSC::Profiler::CompilationKind);
+
+} // namespace WTF
+
+#endif // ProfilerCompilationKind_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp
new file mode 100644
index 000000000..455a48ed9
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "ProfilerCompiledBytecode.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+CompiledBytecode::CompiledBytecode(const OriginStack& origin, const CString& description)
+ : m_origin(origin)
+ , m_description(description)
+{
+}
+
+CompiledBytecode::~CompiledBytecode()
+{
+}
+
+JSValue CompiledBytecode::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().origin, m_origin.toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description)));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
new file mode 100644
index 000000000..84044445a
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerCompiledBytecode.h
@@ -0,0 +1,55 @@
+/*
+ * 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 ProfilerCompiledBytecode_h
+#define ProfilerCompiledBytecode_h
+
+#include "JSCJSValue.h"
+#include "ProfilerOriginStack.h"
+#include <wtf/text/CString.h>
+
+namespace JSC { namespace Profiler {
+
+class CompiledBytecode {
+public:
+ // It's valid to have an empty OriginStack, which indicates that this is some
+ // sort of non-bytecode-related machine code.
+ CompiledBytecode(const OriginStack&, const CString& description);
+ ~CompiledBytecode();
+
+ const OriginStack& originStack() const { return m_origin; }
+ const CString& description() const { return m_description; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ OriginStack m_origin;
+ CString m_description;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerCompiledBytecode_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
new file mode 100644
index 000000000..a2fffd955
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ProfilerDatabase.h"
+
+#include "CodeBlock.h"
+#include "JSONObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
+static int databaseCounter;
+#else
+static volatile int databaseCounter;
+#endif
+static SpinLock registrationLock = SPINLOCK_INITIALIZER;
+static int didRegisterAtExit;
+static Database* firstDatabase;
+
+Database::Database(VM& vm)
+ : m_databaseID(atomicIncrement(&databaseCounter))
+ , m_vm(vm)
+ , m_shouldSaveAtExit(false)
+ , m_nextRegisteredDatabase(0)
+{
+}
+
+Database::~Database()
+{
+ if (m_shouldSaveAtExit) {
+ removeDatabaseFromAtExit();
+ performAtExitSave();
+ }
+}
+
+Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
+{
+ codeBlock = codeBlock->baselineVersion();
+
+ HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
+ if (iter != m_bytecodesMap.end())
+ return iter->value;
+
+ m_bytecodes.append(Bytecodes(m_bytecodes.size(), codeBlock));
+ Bytecodes* result = &m_bytecodes.last();
+
+ m_bytecodesMap.add(codeBlock, result);
+
+ return result;
+}
+
+void Database::notifyDestruction(CodeBlock* codeBlock)
+{
+ m_bytecodesMap.remove(codeBlock);
+}
+
+PassRefPtr<Compilation> Database::newCompilation(Bytecodes* bytecodes, CompilationKind kind)
+{
+ RefPtr<Compilation> compilation = adoptRef(new Compilation(bytecodes, kind));
+ m_compilations.append(compilation);
+ return compilation.release();
+}
+
+PassRefPtr<Compilation> Database::newCompilation(CodeBlock* codeBlock, CompilationKind kind)
+{
+ return newCompilation(ensureBytecodesFor(codeBlock), kind);
+}
+
+JSValue Database::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ JSArray* bytecodes = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_bytecodes.size(); ++i)
+ bytecodes->putDirectIndex(exec, i, m_bytecodes[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodes, bytecodes);
+
+ JSArray* compilations = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_compilations.size(); ++i)
+ compilations->putDirectIndex(exec, i, m_compilations[i]->toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().compilations, compilations);
+
+ return result;
+}
+
+String Database::toJSON() const
+{
+ JSGlobalObject* globalObject = JSGlobalObject::create(
+ m_vm, JSGlobalObject::createStructure(m_vm, jsNull()));
+
+ return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0);
+}
+
+bool Database::save(const char* filename) const
+{
+ OwnPtr<FilePrintStream> out = FilePrintStream::open(filename, "w");
+ if (!out)
+ return false;
+
+ out->print(toJSON());
+ return true;
+}
+
+void Database::registerToSaveAtExit(const char* filename)
+{
+ m_atExitSaveFilename = filename;
+
+ if (m_shouldSaveAtExit)
+ return;
+
+ addDatabaseToAtExit();
+ m_shouldSaveAtExit = true;
+}
+
+void Database::addDatabaseToAtExit()
+{
+ if (atomicIncrement(&didRegisterAtExit) == 1)
+ atexit(atExitCallback);
+
+ TCMalloc_SpinLockHolder holder(&registrationLock);
+ m_nextRegisteredDatabase = firstDatabase;
+ firstDatabase = this;
+}
+
+void Database::removeDatabaseFromAtExit()
+{
+ TCMalloc_SpinLockHolder holder(&registrationLock);
+ for (Database** current = &firstDatabase; *current; current = &(*current)->m_nextRegisteredDatabase) {
+ if (*current != this)
+ continue;
+ *current = m_nextRegisteredDatabase;
+ m_nextRegisteredDatabase = 0;
+ m_shouldSaveAtExit = false;
+ break;
+ }
+}
+
+void Database::performAtExitSave() const
+{
+ save(m_atExitSaveFilename.data());
+}
+
+Database* Database::removeFirstAtExitDatabase()
+{
+ TCMalloc_SpinLockHolder holder(&registrationLock);
+ Database* result = firstDatabase;
+ if (result) {
+ firstDatabase = result->m_nextRegisteredDatabase;
+ result->m_nextRegisteredDatabase = 0;
+ result->m_shouldSaveAtExit = false;
+ }
+ return result;
+}
+
+void Database::atExitCallback()
+{
+ while (Database* database = removeFirstAtExitDatabase())
+ database->performAtExitSave();
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerDatabase.h b/Source/JavaScriptCore/profiler/ProfilerDatabase.h
new file mode 100644
index 000000000..172c8eeac
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerDatabase.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ProfilerDatabase_h
+#define ProfilerDatabase_h
+
+#include "JSCJSValue.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerCompilation.h"
+#include "ProfilerCompilationKind.h"
+#include <wtf/FastAllocBase.h>
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/SegmentedVector.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Profiler {
+
+class Database {
+ WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(Database);
+public:
+ JS_EXPORT_PRIVATE Database(VM&);
+ JS_EXPORT_PRIVATE ~Database();
+
+ int databaseID() const { return m_databaseID; }
+
+ Bytecodes* ensureBytecodesFor(CodeBlock*);
+ void notifyDestruction(CodeBlock*);
+
+ PassRefPtr<Compilation> newCompilation(CodeBlock*, CompilationKind);
+ PassRefPtr<Compilation> newCompilation(Bytecodes*, CompilationKind);
+
+ // Converts the database to a JavaScript object that is suitable for JSON stringification.
+ // Note that it's probably a good idea to use an ExecState* associated with a global
+ // object that is "clean" - i.e. array and object prototypes haven't had strange things
+ // done to them. And yes, it should be appropriate to just use a globalExec here.
+ JS_EXPORT_PRIVATE JSValue toJS(ExecState*) const;
+
+ // Converts the database to a JavaScript object using a private temporary global object,
+ // and then returns the JSON representation of that object.
+ JS_EXPORT_PRIVATE String toJSON() const;
+
+ // Saves the JSON representation (from toJSON()) to the given file. Returns false if the
+ // save failed.
+ JS_EXPORT_PRIVATE bool save(const char* filename) const;
+
+ void registerToSaveAtExit(const char* filename);
+
+private:
+
+ void addDatabaseToAtExit();
+ void removeDatabaseFromAtExit();
+ void performAtExitSave() const;
+ static Database* removeFirstAtExitDatabase();
+ static void atExitCallback();
+
+ int m_databaseID;
+ VM& m_vm;
+ SegmentedVector<Bytecodes> m_bytecodes;
+ HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap;
+ Vector<RefPtr<Compilation> > m_compilations;
+ bool m_shouldSaveAtExit;
+ CString m_atExitSaveFilename;
+ Database* m_nextRegisteredDatabase;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerDatabase_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
new file mode 100644
index 000000000..2884bc5dc
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerExecutionCounter.h
@@ -0,0 +1,50 @@
+/*
+ * 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 ProfilerExecutionCounter_h
+#define ProfilerExecutionCounter_h
+
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC { namespace Profiler {
+
+class ExecutionCounter {
+ WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(ExecutionCounter);
+public:
+ ExecutionCounter() : m_counter(0) { }
+
+ uint64_t* address() { return &m_counter; }
+
+ uint64_t count() const { return m_counter; }
+
+private:
+ uint64_t m_counter;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerExecutionCounter_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
new file mode 100644
index 000000000..0024791b4
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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 "ProfilerOSRExit.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+OSRExit::OSRExit(unsigned id, const OriginStack& origin, ExitKind kind, bool isWatchpoint)
+ : m_id(id)
+ , m_origin(origin)
+ , m_exitKind(kind)
+ , m_isWatchpoint(isWatchpoint)
+ , m_counter(0)
+{
+}
+
+OSRExit::~OSRExit()
+{
+}
+
+JSValue OSRExit::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), exec->propertyNames().id, jsNumber(m_id));
+ result->putDirect(exec->vm(), exec->propertyNames().origin, m_origin.toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().exitKind, jsString(exec, exitKindToString(m_exitKind)));
+ result->putDirect(exec->vm(), exec->propertyNames().isWatchpoint, jsBoolean(m_isWatchpoint));
+ result->putDirect(exec->vm(), exec->propertyNames().count, jsNumber(m_counter));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExit.h b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
new file mode 100644
index 000000000..2a23d0b2c
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExit.h
@@ -0,0 +1,61 @@
+/*
+ * 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 ProfilerOSRExit_h
+#define ProfilerOSRExit_h
+
+#include "ExitKind.h"
+#include "JSCJSValue.h"
+#include "ProfilerOriginStack.h"
+
+namespace JSC { namespace Profiler {
+
+class OSRExit {
+public:
+ OSRExit(unsigned id, const OriginStack&, ExitKind, bool isWatchpoint);
+ ~OSRExit();
+
+ unsigned id() const { return m_id; }
+ const OriginStack& origin() const { return m_origin; }
+ ExitKind exitKind() const { return m_exitKind; }
+ bool isWatchpoint() const { return m_isWatchpoint; }
+
+ uint64_t* counterAddress() { return &m_counter; }
+ uint64_t count() const { return m_counter; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ unsigned m_id;
+ OriginStack m_origin;
+ ExitKind m_exitKind;
+ bool m_isWatchpoint;
+ uint64_t m_counter;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerOSRExit_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
new file mode 100644
index 000000000..d54f7a275
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "ProfilerOSRExitSite.h"
+
+#include "JSGlobalObject.h"
+#include "JSScope.h"
+#include "JSString.h"
+#include "Operations.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+JSValue OSRExitSite::toJS(ExecState* exec) const
+{
+ JSArray* result = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_codeAddresses.size(); ++i)
+ result->putDirectIndex(exec, i, jsString(exec, toString(RawPointer(m_codeAddresses[i]))));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
new file mode 100644
index 000000000..fa418e9b8
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOSRExitSite.h
@@ -0,0 +1,52 @@
+/*
+ * 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 ProfilerOSRExitSite_h
+#define ProfilerOSRExitSite_h
+
+#include "JSCJSValue.h"
+#include <wtf/Vector.h>
+
+namespace JSC { namespace Profiler {
+
+class OSRExitSite {
+public:
+ explicit OSRExitSite(const Vector<const void*>& codeAddresses)
+ : m_codeAddresses(codeAddresses)
+ {
+ }
+
+ const Vector<const void*>& codeAddress() const { return m_codeAddresses; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ Vector<const void*> m_codeAddresses;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerOSRExitSite_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
new file mode 100644
index 000000000..1ac29d1cc
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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 "ProfilerOrigin.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerDatabase.h"
+
+namespace JSC { namespace Profiler {
+
+Origin::Origin(Database& database, CodeBlock* codeBlock, unsigned bytecodeIndex)
+ : m_bytecodes(database.ensureBytecodesFor(codeBlock))
+ , m_bytecodeIndex(bytecodeIndex)
+{
+}
+
+void Origin::dump(PrintStream& out) const
+{
+ out.print(*m_bytecodes, ":bc#", m_bytecodeIndex);
+}
+
+JSValue Origin::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOrigin.h b/Source/JavaScriptCore/profiler/ProfilerOrigin.h
new file mode 100644
index 000000000..09b388451
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOrigin.h
@@ -0,0 +1,120 @@
+/*
+ * 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 ProfilerOrigin_h
+#define ProfilerOrigin_h
+
+#include "CodeBlockHash.h"
+#include "JSCJSValue.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+namespace Profiler {
+
+class Bytecodes;
+class Database;
+
+class Origin {
+public:
+ Origin()
+ : m_bytecodeIndex(std::numeric_limits<unsigned>::max())
+ {
+ }
+
+ Origin(WTF::HashTableDeletedValueType)
+ : m_bytecodeIndex(std::numeric_limits<unsigned>::max() - 1)
+ {
+ }
+
+ Origin(Bytecodes* bytecodes, unsigned bytecodeIndex)
+ : m_bytecodes(bytecodes)
+ , m_bytecodeIndex(bytecodeIndex)
+ {
+ ASSERT(m_bytecodeIndex < std::numeric_limits<unsigned>::max() - 1);
+ }
+
+ Origin(Database&, CodeBlock*, unsigned bytecodeIndex);
+
+ bool operator!() const { return m_bytecodeIndex == std::numeric_limits<unsigned>::max(); }
+
+ Bytecodes* bytecodes() const { return m_bytecodes; }
+ unsigned bytecodeIndex() const { return m_bytecodeIndex; }
+
+ bool operator==(const Origin&) const;
+ bool operator!=(const Origin& other) const { return !(*this == other); }
+ unsigned hash() const;
+
+ bool isHashTableDeletedValue() const;
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ Bytecodes* m_bytecodes;
+ unsigned m_bytecodeIndex;
+};
+
+inline bool Origin::operator==(const Origin& other) const
+{
+ return m_bytecodes == other.m_bytecodes
+ && m_bytecodeIndex == other.m_bytecodeIndex;
+}
+
+inline unsigned Origin::hash() const
+{
+ return WTF::PtrHash<Bytecodes*>::hash(m_bytecodes) + m_bytecodeIndex;
+}
+
+inline bool Origin::isHashTableDeletedValue() const
+{
+ return m_bytecodeIndex == std::numeric_limits<unsigned>::max();
+}
+
+struct OriginHash {
+ static unsigned hash(const Origin& key) { return key.hash(); }
+ static bool equal(const Origin& a, const Origin& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Profiler::Origin> {
+ typedef JSC::Profiler::OriginHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Profiler::Origin> : SimpleClassHashTraits<JSC::Profiler::Origin> { };
+
+} // namespace WTF
+
+#endif // ProfilerOrigin_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp
new file mode 100644
index 000000000..018ceeb8c
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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 "ProfilerOriginStack.h"
+
+#include "CodeOrigin.h"
+#include "JSGlobalObject.h"
+#include "Operations.h"
+#include "ProfilerDatabase.h"
+
+namespace JSC { namespace Profiler {
+
+OriginStack::OriginStack(WTF::HashTableDeletedValueType)
+{
+ m_stack.append(Origin(WTF::HashTableDeletedValue));
+}
+
+OriginStack::OriginStack(const Origin& origin)
+{
+ m_stack.append(origin);
+}
+
+OriginStack::OriginStack(Database& database, CodeBlock* codeBlock, const CodeOrigin& codeOrigin)
+{
+ Vector<CodeOrigin> stack = codeOrigin.inlineStack();
+
+ append(Origin(database, codeBlock, stack[0].bytecodeIndex));
+
+ for (unsigned i = 1; i < stack.size(); ++i) {
+ append(Origin(
+ database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock()),
+ stack[i].bytecodeIndex));
+ }
+}
+
+OriginStack::~OriginStack() { }
+
+void OriginStack::append(const Origin& origin)
+{
+ m_stack.append(origin);
+}
+
+bool OriginStack::operator==(const OriginStack& other) const
+{
+ if (m_stack.size() != other.m_stack.size())
+ return false;
+
+ for (unsigned i = m_stack.size(); i--;) {
+ if (m_stack[i] != other.m_stack[i])
+ return false;
+ }
+
+ return true;
+}
+
+unsigned OriginStack::hash() const
+{
+ unsigned result = m_stack.size();
+
+ for (unsigned i = m_stack.size(); i--;) {
+ result *= 3;
+ result += m_stack[i].hash();
+ }
+
+ return result;
+}
+
+void OriginStack::dump(PrintStream& out) const
+{
+ for (unsigned i = 0; i < m_stack.size(); ++i) {
+ if (i)
+ out.print(" --> ");
+ out.print(m_stack[i]);
+ }
+}
+
+JSValue OriginStack::toJS(ExecState* exec) const
+{
+ JSArray* result = constructEmptyArray(exec, 0);
+
+ for (unsigned i = 0; i < m_stack.size(); ++i)
+ result->putDirectIndex(exec, i, m_stack[i].toJS(exec));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerOriginStack.h b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
new file mode 100644
index 000000000..415e8d9b0
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerOriginStack.h
@@ -0,0 +1,102 @@
+/*
+ * 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 ProfilerOriginStack_h
+#define ProfilerOriginStack_h
+
+#include "JSCJSValue.h"
+#include "ProfilerOrigin.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class CodeBlock;
+struct CodeOrigin;
+
+namespace Profiler {
+
+class Database;
+
+class OriginStack {
+public:
+ OriginStack() { }
+
+ OriginStack(WTF::HashTableDeletedValueType);
+
+ explicit OriginStack(const Origin&);
+
+ explicit OriginStack(Database&, CodeBlock*, const CodeOrigin&);
+
+ ~OriginStack();
+
+ void append(const Origin&);
+
+ bool operator!() const { return m_stack.isEmpty(); }
+
+ unsigned size() const { return m_stack.size(); }
+ const Origin& fromBottom(unsigned i) const { return m_stack[i]; }
+ const Origin& fromTop(unsigned i) const { return m_stack[m_stack.size() - i - 1]; }
+
+ bool operator==(const OriginStack&) const;
+ unsigned hash() const;
+
+ bool isHashTableDeletedValue() const;
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ Vector<Origin, 1> m_stack;
+};
+
+inline bool OriginStack::isHashTableDeletedValue() const
+{
+ return m_stack.size() == 1 && m_stack[0].isHashTableDeletedValue();
+}
+
+struct OriginStackHash {
+ static unsigned hash(const OriginStack& key) { return key.hash(); }
+ static bool equal(const OriginStack& a, const OriginStack& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Profiler::OriginStack> {
+ typedef JSC::Profiler::OriginStackHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Profiler::OriginStack> : SimpleClassHashTraits<JSC::Profiler::OriginStack> { };
+
+} // namespace WTF
+
+#endif // ProfilerOriginStack_h
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp
new file mode 100644
index 000000000..6ca6c9f15
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "ProfilerProfiledBytecodes.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+
+namespace JSC { namespace Profiler {
+
+ProfiledBytecodes::ProfiledBytecodes(Bytecodes* bytecodes, CodeBlock* profiledBlock)
+ : BytecodeSequence(profiledBlock)
+ , m_bytecodes(bytecodes)
+{
+}
+
+ProfiledBytecodes::~ProfiledBytecodes()
+{
+}
+
+JSValue ProfiledBytecodes::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ addSequenceProperties(exec, result);
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
diff --git a/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
new file mode 100644
index 000000000..d7cb6ffa8
--- /dev/null
+++ b/Source/JavaScriptCore/profiler/ProfilerProfiledBytecodes.h
@@ -0,0 +1,51 @@
+/*
+ * 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 ProfilerProfiledBytecodes_h
+#define ProfilerProfiledBytecodes_h
+
+#include "ProfilerBytecodeSequence.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerOriginStack.h"
+
+namespace JSC { namespace Profiler {
+
+class ProfiledBytecodes : public BytecodeSequence {
+public:
+ ProfiledBytecodes(Bytecodes*, CodeBlock*);
+ ~ProfiledBytecodes();
+
+ const Bytecodes* bytecodes() const { return m_bytecodes; }
+
+ JSValue toJS(ExecState*) const;
+
+private:
+ Bytecodes* m_bytecodes;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerProfiledBytecodes_h
+
diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp
index 301abd530..74240418c 100644
--- a/Source/JavaScriptCore/runtime/ArgList.cpp
+++ b/Source/JavaScriptCore/runtime/ArgList.cpp
@@ -22,9 +22,9 @@
#include "ArgList.h"
#include "HeapRootVisitor.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "JSObject.h"
-
+#include "Operations.h"
using std::min;
diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h
index 1fb1ce911..84a0cdd8b 100644
--- a/Source/JavaScriptCore/runtime/ArgList.h
+++ b/Source/JavaScriptCore/runtime/ArgList.h
@@ -33,12 +33,11 @@ class SlotVisitor;
class MarkedArgumentBuffer {
WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
- friend class JSGlobalData;
+ friend class VM;
friend class ArgList;
private:
static const size_t inlineCapacity = 8;
- typedef Vector<Register, inlineCapacity> VectorType;
typedef HashSet<MarkedArgumentBuffer*> ListSet;
public:
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index ba73b2cf2..a188885e6 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -28,6 +28,7 @@
#include "JSActivation.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
using namespace std;
@@ -126,7 +127,7 @@ bool Arguments::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName p
Arguments* thisObject = jsCast<Arguments*>(cell);
unsigned i = propertyName.asIndex();
if (JSValue value = thisObject->tryGetArgument(i)) {
- ASSERT(i < PropertyName::NotAnIndex);
+ RELEASE_ASSERT(i < PropertyName::NotAnIndex);
slot.setValue(value);
return true;
}
@@ -155,7 +156,7 @@ bool Arguments::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prop
Arguments* thisObject = jsCast<Arguments*>(object);
unsigned i = propertyName.asIndex();
if (JSValue value = thisObject->tryGetArgument(i)) {
- ASSERT(i < PropertyName::NotAnIndex);
+ RELEASE_ASSERT(i < PropertyName::NotAnIndex);
descriptor.setDescriptor(value, None);
return true;
}
@@ -197,7 +198,7 @@ void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyN
void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
- if (thisObject->trySetArgument(exec->globalData(), i, value))
+ if (thisObject->trySetArgument(exec->vm(), i, value))
return;
PutPropertySlot slot(shouldThrow);
@@ -208,19 +209,19 @@ void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JS
{
Arguments* thisObject = jsCast<Arguments*>(cell);
unsigned i = propertyName.asIndex();
- if (thisObject->trySetArgument(exec->globalData(), i, value))
+ if (thisObject->trySetArgument(exec->vm(), i, value))
return;
if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
thisObject->m_overrodeLength = true;
- thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
+ thisObject->putDirect(exec->vm(), propertyName, value, DontEnum);
return;
}
if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
if (!thisObject->m_isStrictMode) {
thisObject->m_overrodeCallee = true;
- thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
+ thisObject->putDirect(exec->vm(), propertyName, value, DontEnum);
return;
}
thisObject->createStrictModeCalleeIfNecessary(exec);
@@ -246,13 +247,13 @@ bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
{
- if (exec->globalData().isInDefineOwnProperty())
+ if (exec->vm().isInDefineOwnProperty())
return Base::deleteProperty(cell, exec, propertyName);
Arguments* thisObject = jsCast<Arguments*>(cell);
unsigned i = propertyName.asIndex();
if (i < thisObject->m_numArguments) {
- ASSERT(i < PropertyName::NotAnIndex);
+ RELEASE_ASSERT(i < PropertyName::NotAnIndex);
if (!Base::deleteProperty(cell, exec, propertyName))
return false;
if (thisObject->tryDeleteArgument(i))
@@ -283,7 +284,7 @@ bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNam
Arguments* thisObject = jsCast<Arguments*>(object);
unsigned i = propertyName.asIndex();
if (i < thisObject->m_numArguments) {
- ASSERT(i < PropertyName::NotAnIndex);
+ RELEASE_ASSERT(i < PropertyName::NotAnIndex);
// If the property is not yet present on the object, and is not yet marked as deleted, then add it now.
PropertySlot slot;
if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
@@ -305,7 +306,7 @@ bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNam
// i. If Desc.[[Value]] is present, then
// 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
if (descriptor.value())
- thisObject->trySetArgument(exec->globalData(), i, descriptor.value());
+ thisObject->trySetArgument(exec->vm(), i, descriptor.value());
// ii. If Desc.[[Writable]] is present and its value is false, then
// 1. Call the [[Delete]] internal method of map passing P and false as arguments.
if (descriptor.writablePresent() && !descriptor.writable())
@@ -316,10 +317,10 @@ bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNam
}
if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
- thisObject->putDirect(exec->globalData(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum);
+ thisObject->putDirect(exec->vm(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum);
thisObject->m_overrodeLength = true;
} else if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
- thisObject->putDirect(exec->globalData(), propertyName, thisObject->m_callee.get(), DontEnum);
+ thisObject->putDirect(exec->vm(), propertyName, thisObject->m_callee.get(), DontEnum);
thisObject->m_overrodeCallee = true;
} else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
@@ -355,24 +356,24 @@ void Arguments::tearOff(CallFrame* callFrame)
if (!callFrame->isInlineCallFrame()) {
for (size_t i = 0; i < m_numArguments; ++i)
- trySetArgument(callFrame->globalData(), i, callFrame->argumentAfterCapture(i));
+ trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
return;
}
tearOffForInlineCallFrame(
- callFrame->globalData(), callFrame->registers(), callFrame->inlineCallFrame());
+ callFrame->vm(), callFrame->registers(), callFrame->inlineCallFrame());
}
void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)
{
- ASSERT(activation);
+ RELEASE_ASSERT(activation);
if (isTornOff())
return;
if (!m_numArguments)
return;
- m_activation.set(exec->globalData(), this, activation);
+ m_activation.set(exec->vm(), this, activation);
tearOff(exec);
}
@@ -388,11 +389,11 @@ void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
m_registers = m_registerArray.get() + CallFrame::offsetFor(m_numArguments + 1);
tearOffForInlineCallFrame(
- callFrame->globalData(), callFrame->registers() + inlineCallFrame->stackOffset,
+ callFrame->vm(), callFrame->registers() + inlineCallFrame->stackOffset,
inlineCallFrame);
}
-void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* registers, InlineCallFrame* inlineCallFrame)
+void Arguments::tearOffForInlineCallFrame(VM& vm, Register* registers, InlineCallFrame* inlineCallFrame)
{
for (size_t i = 0; i < m_numArguments; ++i) {
ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
@@ -427,10 +428,10 @@ void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* re
value = recovery.constant();
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
- trySetArgument(globalData, i, value);
+ trySetArgument(vm, i, value);
}
}
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index 8ae991422..58ac782b6 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -40,16 +40,16 @@ class Arguments : public JSDestructibleObject {
public:
typedef JSDestructibleObject Base;
- static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame)
+ static Arguments* create(VM& vm, CallFrame* callFrame)
{
- Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
+ Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap)) Arguments(callFrame);
arguments->finishCreation(callFrame);
return arguments;
}
- static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
+ static Arguments* create(VM& vm, CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
{
- Arguments* arguments = new (NotNull, allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);
+ Arguments* arguments = new (NotNull, allocateCell<Arguments>(vm.heap)) Arguments(callFrame);
arguments->finishCreation(callFrame, inlineCallFrame);
return arguments;
}
@@ -62,7 +62,7 @@ private:
Arguments(CallFrame*);
Arguments(CallFrame*, NoParametersType);
- void tearOffForInlineCallFrame(JSGlobalData& globalData, Register*, InlineCallFrame*);
+ void tearOffForInlineCallFrame(VM& vm, Register*, InlineCallFrame*);
public:
static const ClassInfo s_info;
@@ -84,9 +84,9 @@ public:
bool isTornOff() const { return m_registerArray; }
void didTearOffActivation(ExecState*, JSActivation*);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
@@ -110,7 +110,7 @@ private:
void createStrictModeCalleeIfNecessary(ExecState*);
bool isArgument(size_t);
- bool trySetArgument(JSGlobalData&, size_t argument, JSValue);
+ bool trySetArgument(VM&, size_t argument, JSValue);
JSValue tryGetArgument(size_t argument);
bool isDeletedArgument(size_t);
bool tryDeleteArgument(size_t);
@@ -148,12 +148,12 @@ inline Arguments* asArguments(JSValue value)
}
inline Arguments::Arguments(CallFrame* callFrame)
- : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
+ : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
{
}
inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
- : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
+ : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
{
}
@@ -177,11 +177,11 @@ inline bool Arguments::tryDeleteArgument(size_t argument)
return true;
}
-inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value)
+inline bool Arguments::trySetArgument(VM& vm, size_t argument, JSValue value)
{
if (!isArgument(argument))
return false;
- this->argument(argument).set(globalData, this, value);
+ this->argument(argument).set(vm, this, value);
return true;
}
@@ -227,13 +227,13 @@ inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
inline void Arguments::finishCreation(CallFrame* callFrame)
{
- Base::finishCreation(callFrame->globalData());
+ Base::finishCreation(callFrame->vm());
ASSERT(inherits(&s_info));
JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
m_numArguments = callFrame->argumentCount();
m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
- m_callee.set(callFrame->globalData(), this, callee);
+ m_callee.set(callFrame->vm(), this, callee);
m_overrodeLength = false;
m_overrodeCallee = false;
m_overrodeCaller = false;
@@ -256,13 +256,13 @@ inline void Arguments::finishCreation(CallFrame* callFrame)
inline void Arguments::finishCreation(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
{
- Base::finishCreation(callFrame->globalData());
+ Base::finishCreation(callFrame->vm());
ASSERT(inherits(&s_info));
- JSFunction* callee = inlineCallFrame->callee.get();
+ JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
m_numArguments = inlineCallFrame->arguments.size() - 1;
m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
- m_callee.set(callFrame->globalData(), this, callee);
+ m_callee.set(callFrame->vm(), this, callee);
m_overrodeLength = false;
m_overrodeCallee = false;
m_overrodeCaller = false;
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
index a3fce45f2..752055716 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -32,6 +32,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "Lookup.h"
+#include "Operations.h"
namespace JSC {
@@ -60,9 +61,9 @@ ArrayConstructor::ArrayConstructor(JSGlobalObject* globalObject, Structure* stru
void ArrayConstructor::finishCreation(ExecState* exec, ArrayPrototype* arrayPrototype)
{
- Base::finishCreation(exec->globalData(), arrayPrototype->classInfo()->className);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ Base::finishCreation(exec->vm(), arrayPrototype->classInfo()->className);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
bool ArrayConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.h b/Source/JavaScriptCore/runtime/ArrayConstructor.h
index f9f35c491..727475b47 100644
--- a/Source/JavaScriptCore/runtime/ArrayConstructor.h
+++ b/Source/JavaScriptCore/runtime/ArrayConstructor.h
@@ -42,9 +42,9 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index e6d37fb02..ba1c7b725 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2003 Peter Kelly (pmk@post.com)
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
@@ -28,6 +28,7 @@
#include "CachedCall.h"
#include "CodeBlock.h"
#include "CopiedSpaceInlines.h"
+#include "Error.h"
#include "Interpreter.h"
#include "JIT.h"
#include "JSStringBuilder.h"
@@ -123,16 +124,16 @@ ArrayPrototype* ArrayPrototype::create(ExecState* exec, JSGlobalObject* globalOb
// ECMA 15.4.4
ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, Structure* structure)
- : JSArray(globalObject->globalData(), structure, 0)
+ : JSArray(globalObject->vm(), structure, 0)
{
}
void ArrayPrototype::finishCreation(JSGlobalObject* globalObject)
{
- JSGlobalData& globalData = globalObject->globalData();
- Base::finishCreation(globalData);
+ VM& vm = globalObject->vm();
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
- notifyUsedAsPrototype(globalData);
+ vm.prototypeMap.addPrototype(this);
}
bool ArrayPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -194,11 +195,11 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument
template<JSArray::ShiftCountMode shiftCountMode>
void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
{
- ASSERT(currentCount > resultCount);
+ RELEASE_ASSERT(currentCount > resultCount);
unsigned count = currentCount - resultCount;
- ASSERT(header <= length);
- ASSERT(currentCount <= (length - header));
+ RELEASE_ASSERT(header <= length);
+ RELEASE_ASSERT(currentCount <= (length - header));
if (isJSArray(thisObj)) {
JSArray* array = asArray(thisObj);
@@ -232,11 +233,11 @@ void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned current
template<JSArray::ShiftCountMode shiftCountMode>
void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length)
{
- ASSERT(resultCount > currentCount);
+ RELEASE_ASSERT(resultCount > currentCount);
unsigned count = resultCount - currentCount;
- ASSERT(header <= length);
- ASSERT(currentCount <= (length - header));
+ RELEASE_ASSERT(header <= length);
+ RELEASE_ASSERT(currentCount <= (length - header));
// Guard against overflow.
if (count > (UINT_MAX - length)) {
@@ -303,64 +304,27 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
if (JSValue earlyReturnValue = checker.earlyReturnValue())
return JSValue::encode(earlyReturnValue);
- unsigned totalSize = length ? length - 1 : 0;
- Vector<RefPtr<StringImpl>, 256> strBuffer(length);
- bool allStrings8Bit = true;
-
+ String separator(",", String::ConstructFromLiteral);
+ JSStringJoiner stringJoiner(separator, length);
for (unsigned k = 0; k < length; k++) {
JSValue element;
if (thisObj->canGetIndexQuickly(k))
element = thisObj->getIndexQuickly(k);
- else
+ else {
element = thisObj->get(exec, k);
-
- if (element.isUndefinedOrNull())
- continue;
-
- String str = element.toWTFString(exec);
- strBuffer[k] = str.impl();
- totalSize += str.length();
- allStrings8Bit = allStrings8Bit && str.is8Bit();
-
- if (!strBuffer.data()) {
- throwOutOfMemoryError(exec);
- }
-
- if (exec->hadException())
- break;
- }
- if (!totalSize)
- return JSValue::encode(jsEmptyString(exec));
-
- if (allStrings8Bit) {
- Vector<LChar> buffer;
- buffer.reserveCapacity(totalSize);
- if (!buffer.data())
- return JSValue::encode(throwOutOfMemoryError(exec));
-
- for (unsigned i = 0; i < length; i++) {
- if (i)
- buffer.append(',');
- if (RefPtr<StringImpl> rep = strBuffer[i])
- buffer.append(rep->characters8(), rep->length());
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
}
- ASSERT(buffer.size() == totalSize);
- return JSValue::encode(jsString(exec, String::adopt(buffer)));
- }
- Vector<UChar> buffer;
- buffer.reserveCapacity(totalSize);
- if (!buffer.data())
- return JSValue::encode(throwOutOfMemoryError(exec));
-
- for (unsigned i = 0; i < length; i++) {
- if (i)
- buffer.append(',');
- if (RefPtr<StringImpl> rep = strBuffer[i])
- buffer.append(rep->characters(), rep->length());
+ if (element.isUndefinedOrNull())
+ stringJoiner.append(String());
+ else
+ stringJoiner.append(element.toWTFString(exec));
+
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
}
- ASSERT(buffer.size() == totalSize);
- return JSValue::encode(jsString(exec, String::adopt(buffer)));
+ return JSValue::encode(stringJoiner.join(exec));
}
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
@@ -403,7 +367,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
}
}
- return JSValue::encode(stringJoiner.build(exec));
+ return JSValue::encode(stringJoiner.join(exec));
}
EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
@@ -449,7 +413,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
stringJoiner.append(String());
}
- return JSValue::encode(stringJoiner.build(exec));
+ return JSValue::encode(stringJoiner.join(exec));
}
EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
@@ -644,39 +608,36 @@ inline JSValue getOrHole(JSObject* obj, ExecState* exec, unsigned propertyName)
return JSValue();
}
-EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
+static bool attemptFastSort(ExecState* exec, JSObject* thisObj, JSValue function, CallData& callData, CallType& callType)
{
- JSObject* thisObj = exec->hostThisValue().toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
- if (!length || exec->hadException())
- return JSValue::encode(thisObj);
-
- JSValue function = exec->argument(0);
- CallData callData;
- CallType callType = getCallData(function, callData);
-
- if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->hasSparseMap() && !shouldUseSlowPut(thisObj->structure()->indexingType())) {
- if (isNumericCompareFunction(exec, callType, callData))
- asArray(thisObj)->sortNumeric(exec, function, callType, callData);
- else if (callType != CallTypeNone)
- asArray(thisObj)->sort(exec, function, callType, callData);
- else
- asArray(thisObj)->sort(exec);
- return JSValue::encode(thisObj);
- }
+ if (thisObj->classInfo() != &JSArray::s_info
+ || asArray(thisObj)->hasSparseMap()
+ || shouldUseSlowPut(thisObj->structure()->indexingType()))
+ return false;
+
+ if (isNumericCompareFunction(exec, callType, callData))
+ asArray(thisObj)->sortNumeric(exec, function, callType, callData);
+ else if (callType != CallTypeNone)
+ asArray(thisObj)->sort(exec, function, callType, callData);
+ else
+ asArray(thisObj)->sort(exec);
+ return true;
+}
+static bool performSlowSort(ExecState* exec, JSObject* thisObj, unsigned length, JSValue function, CallData& callData, CallType& callType)
+{
// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
JSValue iObj = getOrHole(thisObj, exec, i);
if (exec->hadException())
- return JSValue::encode(jsUndefined());
+ return false;
unsigned themin = i;
JSValue minObj = iObj;
for (unsigned j = i + 1; j < length; ++j) {
JSValue jObj = getOrHole(thisObj, exec, j);
if (exec->hadException())
- return JSValue::encode(jsUndefined());
+ return false;
double compareResult;
if (!jObj)
compareResult = 1;
@@ -704,21 +665,94 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
if (minObj) {
thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true);
if (exec->hadException())
- return JSValue::encode(jsUndefined());
+ return false;
} else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, i)) {
throwTypeError(exec, "Unable to delete property.");
- return JSValue::encode(jsUndefined());
+ return false;
}
if (iObj) {
thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true);
if (exec->hadException())
- return JSValue::encode(jsUndefined());
+ return false;
} else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, themin)) {
throwTypeError(exec, "Unable to delete property.");
- return JSValue::encode(jsUndefined());
+ return false;
}
}
}
+ return true;
+}
+
+EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
+{
+ JSObject* thisObj = exec->hostThisValue().toObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (!length || exec->hadException())
+ return JSValue::encode(thisObj);
+
+ JSValue function = exec->argument(0);
+ CallData callData;
+ CallType callType = getCallData(function, callData);
+
+ if (attemptFastSort(exec, thisObj, function, callData, callType))
+ return JSValue::encode(thisObj);
+
+ // Assume that for small-ish arrays, doing the slow sort directly is better.
+ if (length < 1000)
+ return performSlowSort(exec, thisObj, length, function, callData, callType) ? JSValue::encode(thisObj) : JSValue::encode(jsUndefined());
+
+ JSGlobalObject* globalObject = JSGlobalObject::create(
+ exec->vm(), JSGlobalObject::createStructure(exec->vm(), jsNull()));
+ JSArray* flatArray = constructEmptyArray(globalObject->globalExec(), 0);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ PropertyNameArray nameArray(exec);
+ thisObj->methodTable()->getPropertyNames(thisObj, exec, nameArray, IncludeDontEnumProperties);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ Vector<uint32_t, 0, UnsafeVectorOverflow> keys;
+ for (size_t i = 0; i < nameArray.size(); ++i) {
+ PropertyName name = nameArray[i];
+ uint32_t index = name.asIndex();
+ if (index == PropertyName::NotAnIndex)
+ continue;
+
+ JSValue value = getOrHole(thisObj, exec, index);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ if (!value)
+ continue;
+ keys.append(index);
+ flatArray->push(exec, value);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ }
+
+ if (!attemptFastSort(exec, flatArray, function, callData, callType)
+ && !performSlowSort(exec, flatArray, flatArray->length(), function, callData, callType))
+ return JSValue::encode(jsUndefined());
+
+ for (size_t i = 0; i < keys.size(); ++i) {
+ size_t index = keys[i];
+ if (index < flatArray->length())
+ continue;
+
+ if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, index)) {
+ throwTypeError(exec, "Unable to delete property.");
+ return JSValue::encode(jsUndefined());
+ }
+ }
+
+ for (size_t i = flatArray->length(); i--;) {
+ JSValue value = getOrHole(flatArray, exec, i);
+ RELEASE_ASSERT(value);
+ thisObj->methodTable()->putByIndex(thisObj, exec, i, value, true);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+ }
+
return JSValue::encode(thisObj);
}
@@ -747,17 +781,17 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
deleteCount = static_cast<unsigned>(deleteDouble);
}
- JSArray* resObj = JSArray::tryCreateUninitialized(exec->globalData(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount);
+ JSArray* resObj = JSArray::tryCreateUninitialized(exec->vm(), exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), deleteCount);
if (!resObj)
return JSValue::encode(throwOutOfMemoryError(exec));
JSValue result = resObj;
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
for (unsigned k = 0; k < deleteCount; k++) {
JSValue v = getProperty(exec, thisObj, k + begin);
if (exec->hadException())
return JSValue::encode(jsUndefined());
- resObj->initializeIndex(globalData, k, v);
+ resObj->initializeIndex(vm, k, v);
}
unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
@@ -1290,7 +1324,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec)
JSValue searchElement = exec->argument(0);
do {
- ASSERT(index < length);
+ RELEASE_ASSERT(index < length);
JSValue e = getProperty(exec, thisObj, index);
if (exec->hadException())
return JSValue::encode(jsUndefined());
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.h b/Source/JavaScriptCore/runtime/ArrayPrototype.h
index c23bcdec1..37ba6eb7e 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.h
@@ -40,9 +40,9 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayClass);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayClass);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/ArrayStorage.h b/Source/JavaScriptCore/runtime/ArrayStorage.h
index ffd84b281..a0287c921 100644
--- a/Source/JavaScriptCore/runtime/ArrayStorage.h
+++ b/Source/JavaScriptCore/runtime/ArrayStorage.h
@@ -49,7 +49,7 @@ private:
ArrayStorage() { } // Not directly instantiable. Can only be created as part of a Butterfly.
public:
- static ArrayStorage* from(Butterfly* butterfly) { return reinterpret_cast<ArrayStorage*>(butterfly); }
+ static ArrayStorage* from(Butterfly* butterfly) { return reinterpret_cast_ptr<ArrayStorage*>(butterfly); }
static ArrayStorage* from(IndexingHeader* indexingHeader) { return indexingHeader->arrayStorage(); }
Butterfly* butterfly() { return reinterpret_cast<Butterfly*>(this); }
@@ -72,7 +72,9 @@ public:
{
return m_sparseMap && m_sparseMap->sparseMode();
}
-
+
+ ContiguousJSValues vector() { return ContiguousJSValues(m_vector, vectorLength()); }
+
WriteBarrier<SparseArrayValueMap> m_sparseMap;
unsigned m_indexBias;
unsigned m_numValuesInVector;
diff --git a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
index 178bf3fe9..76def7138 100644
--- a/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
+++ b/Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -34,8 +34,8 @@ namespace JSC {
class BatchedTransitionOptimizer {
WTF_MAKE_NONCOPYABLE(BatchedTransitionOptimizer);
public:
- BatchedTransitionOptimizer(JSGlobalData& globalData, JSObject* object)
- : m_globalData(&globalData)
+ BatchedTransitionOptimizer(VM& vm, JSObject* object)
+ : m_vm(&vm)
, m_object(object)
{
}
@@ -43,11 +43,11 @@ public:
~BatchedTransitionOptimizer()
{
if (m_object->structure()->isDictionary())
- m_object->flattenDictionaryObject(*m_globalData);
+ m_object->flattenDictionaryObject(*m_vm);
}
private:
- JSGlobalData* m_globalData;
+ VM* m_vm;
JSObject* m_object;
};
diff --git a/Source/JavaScriptCore/runtime/BigInteger.h b/Source/JavaScriptCore/runtime/BigInteger.h
index 833829df6..0a0c477c2 100644
--- a/Source/JavaScriptCore/runtime/BigInteger.h
+++ b/Source/JavaScriptCore/runtime/BigInteger.h
@@ -35,7 +35,7 @@ class BigInteger {
public:
BigInteger(double number)
{
- ASSERT(isfinite(number) && !signbit(number));
+ ASSERT(std::isfinite(number) && !std::signbit(number));
ASSERT(number == floor(number));
bool sign;
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
index 0485350ce..453983b7a 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -23,6 +23,7 @@
#include "BooleanPrototype.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
namespace JSC {
@@ -37,18 +38,18 @@ BooleanConstructor::BooleanConstructor(JSGlobalObject* globalObject, Structure*
void BooleanConstructor::finishCreation(ExecState* exec, BooleanPrototype* booleanPrototype)
{
- Base::finishCreation(exec->globalData(), booleanPrototype->classInfo()->className);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
+ Base::finishCreation(exec->vm(), booleanPrototype->classInfo()->className);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
}
// ECMA 15.6.2
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
- BooleanObject* obj = BooleanObject::create(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure());
- obj->setInternalValue(exec->globalData(), jsBoolean(args.at(0).toBoolean(exec)));
+ BooleanObject* obj = BooleanObject::create(exec->vm(), asInternalFunction(exec->callee())->globalObject()->booleanObjectStructure());
+ obj->setInternalValue(exec->vm(), jsBoolean(args.at(0).toBoolean(exec)));
return obj;
}
@@ -78,8 +79,8 @@ CallType BooleanConstructor::getCallData(JSCell*, CallData& callData)
JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSGlobalObject* globalObject, JSValue immediateBooleanValue)
{
- BooleanObject* obj = BooleanObject::create(exec->globalData(), globalObject->booleanObjectStructure());
- obj->setInternalValue(exec->globalData(), immediateBooleanValue);
+ BooleanObject* obj = BooleanObject::create(exec->vm(), globalObject->booleanObjectStructure());
+ obj->setInternalValue(exec->vm(), immediateBooleanValue);
return obj;
}
diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.h b/Source/JavaScriptCore/runtime/BooleanConstructor.h
index f395374ae..760d5d3b1 100644
--- a/Source/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/Source/JavaScriptCore/runtime/BooleanConstructor.h
@@ -40,9 +40,9 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp
index 355993864..3f7f2f621 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp
@@ -22,6 +22,7 @@
#include "BooleanObject.h"
#include "JSScope.h"
+#include "Operations.h"
namespace JSC {
@@ -29,14 +30,14 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanObject);
const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) };
-BooleanObject::BooleanObject(JSGlobalData& globalData, Structure* structure)
- : JSWrapperObject(globalData, structure)
+BooleanObject::BooleanObject(VM& vm, Structure* structure)
+ : JSWrapperObject(vm, structure)
{
}
-void BooleanObject::finishCreation(JSGlobalData& globalData)
+void BooleanObject::finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/BooleanObject.h b/Source/JavaScriptCore/runtime/BooleanObject.h
index b6fcccdcf..299f34174 100644
--- a/Source/JavaScriptCore/runtime/BooleanObject.h
+++ b/Source/JavaScriptCore/runtime/BooleanObject.h
@@ -27,24 +27,24 @@ namespace JSC {
class BooleanObject : public JSWrapperObject {
protected:
- JS_EXPORT_PRIVATE BooleanObject(JSGlobalData&, Structure*);
- JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&);
+ JS_EXPORT_PRIVATE BooleanObject(VM&, Structure*);
+ JS_EXPORT_PRIVATE void finishCreation(VM&);
public:
typedef JSWrapperObject Base;
- static BooleanObject* create(JSGlobalData& globalData, Structure* structure)
+ static BooleanObject* create(VM& vm, Structure* structure)
{
- BooleanObject* boolean = new (NotNull, allocateCell<BooleanObject>(globalData.heap)) BooleanObject(globalData, structure);
- boolean->finishCreation(globalData);
+ BooleanObject* boolean = new (NotNull, allocateCell<BooleanObject>(vm.heap)) BooleanObject(vm, structure);
+ boolean->finishCreation(vm);
return boolean;
}
static JS_EXPORTDATA const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
};
diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
index a331c6c15..a5b8390a8 100644
--- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -26,6 +26,7 @@
#include "JSFunction.h"
#include "JSString.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
namespace JSC {
@@ -50,14 +51,14 @@ const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info,
ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanPrototype);
BooleanPrototype::BooleanPrototype(ExecState* exec, Structure* structure)
- : BooleanObject(exec->globalData(), structure)
+ : BooleanObject(exec->vm(), structure)
{
}
void BooleanPrototype::finishCreation(ExecState* exec, JSGlobalObject*)
{
- Base::finishCreation(exec->globalData());
- setInternalValue(exec->globalData(), jsBoolean(false));
+ Base::finishCreation(exec->vm());
+ setInternalValue(exec->vm(), jsBoolean(false));
ASSERT(inherits(&s_info));
}
@@ -76,22 +77,22 @@ bool BooleanPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exe
EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec)
{
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
JSValue thisValue = exec->hostThisValue();
if (thisValue == jsBoolean(false))
- return JSValue::encode(globalData->smallStrings.falseString(globalData));
+ return JSValue::encode(vm->smallStrings.falseString());
if (thisValue == jsBoolean(true))
- return JSValue::encode(globalData->smallStrings.trueString(globalData));
+ return JSValue::encode(vm->smallStrings.trueString());
if (!thisValue.inherits(&BooleanObject::s_info))
return throwVMTypeError(exec);
if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
- return JSValue::encode(globalData->smallStrings.falseString(globalData));
+ return JSValue::encode(vm->smallStrings.falseString());
ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true));
- return JSValue::encode(globalData->smallStrings.trueString(globalData));
+ return JSValue::encode(vm->smallStrings.trueString());
}
EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.h b/Source/JavaScriptCore/runtime/BooleanPrototype.h
index 05790a755..43b81cb61 100644
--- a/Source/JavaScriptCore/runtime/BooleanPrototype.h
+++ b/Source/JavaScriptCore/runtime/BooleanPrototype.h
@@ -38,9 +38,9 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h
index bbbda9461..eb6d82a76 100644
--- a/Source/JavaScriptCore/runtime/Butterfly.h
+++ b/Source/JavaScriptCore/runtime/Butterfly.h
@@ -34,10 +34,45 @@
namespace JSC {
-class JSGlobalData;
+class VM;
class CopyVisitor;
struct ArrayStorage;
+template <typename T> struct ContiguousData {
+ ContiguousData()
+ : m_data(0)
+#if !ASSERT_DISABLED
+ , m_length(0)
+#endif
+ {
+ }
+ ContiguousData(T* data, size_t length)
+ : m_data(data)
+#if !ASSERT_DISABLED
+ , m_length(length)
+#endif
+ {
+ UNUSED_PARAM(length);
+ }
+
+ const T& operator[](size_t index) const { ASSERT(index < m_length); return m_data[index]; }
+ T& operator[](size_t index) { ASSERT(index < m_length); return m_data[index]; }
+
+ T* data() const { return m_data; }
+#if !ASSERT_DISABLED
+ size_t length() const { return m_length; }
+#endif
+
+private:
+ T* m_data;
+#if !ASSERT_DISABLED
+ size_t m_length;
+#endif
+};
+
+typedef ContiguousData<double> ContiguousDoubles;
+typedef ContiguousData<WriteBarrier<Unknown> > ContiguousJSValues;
+
class Butterfly {
WTF_MAKE_NONCOPYABLE(Butterfly);
private:
@@ -69,10 +104,10 @@ public:
static ptrdiff_t offsetOfPublicLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfPublicLength(); }
static ptrdiff_t offsetOfVectorLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfVectorLength(); }
- static Butterfly* createUninitialized(JSGlobalData&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
+ static Butterfly* createUninitialized(VM&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
- static Butterfly* create(JSGlobalData&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes);
- static Butterfly* create(JSGlobalData&, Structure*);
+ static Butterfly* create(VM&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes);
+ static Butterfly* create(VM&, Structure*);
static Butterfly* createUninitializedDuringCollection(CopyVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes);
IndexingHeader* indexingHeader() { return IndexingHeader::from(this); }
@@ -86,11 +121,12 @@ public:
void setVectorLength(uint32_t value) { indexingHeader()->setVectorLength(value); }
template<typename T>
- T* indexingPayload() { return reinterpret_cast<T*>(this); }
+ T* indexingPayload() { return reinterpret_cast_ptr<T*>(this); }
ArrayStorage* arrayStorage() { return indexingPayload<ArrayStorage>(); }
- WriteBarrier<Unknown>* contiguousInt32() { return indexingPayload<WriteBarrier<Unknown> >(); }
- double* contiguousDouble() { return indexingPayload<double>(); }
- WriteBarrier<Unknown>* contiguous() { return indexingPayload<WriteBarrier<Unknown> >(); }
+ ContiguousJSValues contiguousInt32() { return ContiguousJSValues(indexingPayload<WriteBarrier<Unknown> >(), vectorLength()); }
+
+ ContiguousDoubles contiguousDouble() { return ContiguousDoubles(indexingPayload<double>(), vectorLength()); }
+ ContiguousJSValues contiguous() { return ContiguousJSValues(indexingPayload<WriteBarrier<Unknown> >(), vectorLength()); }
static Butterfly* fromContiguous(WriteBarrier<Unknown>* contiguous)
{
@@ -111,20 +147,20 @@ public:
void* base(size_t preCapacity, size_t propertyCapacity) { return propertyStorage() - propertyCapacity - preCapacity; }
void* base(Structure*);
- static Butterfly* createOrGrowArrayRight(Butterfly*, JSGlobalData&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes);
+ static Butterfly* createOrGrowArrayRight(Butterfly*, VM&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes);
// The butterfly reallocation methods perform the reallocation itself but do not change any
// of the meta-data to reflect that the reallocation occurred. Note that this set of
// methods is not exhaustive and is not intended to encapsulate all possible allocation
// modes of butterflies - there are code paths that allocate butterflies by calling
// directly into Heap::tryAllocateStorage.
- Butterfly* growPropertyStorage(JSGlobalData&, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity);
- Butterfly* growPropertyStorage(JSGlobalData&, Structure* oldStructure, size_t oldPropertyCapacity, size_t newPropertyCapacity);
- Butterfly* growPropertyStorage(JSGlobalData&, Structure* oldStructure, size_t newPropertyCapacity);
- Butterfly* growArrayRight(JSGlobalData&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much.
- Butterfly* growArrayRight(JSGlobalData&, Structure*, size_t newIndexingPayloadSizeInBytes);
- Butterfly* resizeArray(JSGlobalData&, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes);
- Butterfly* resizeArray(JSGlobalData&, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header.
+ Butterfly* growPropertyStorage(VM&, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity);
+ Butterfly* growPropertyStorage(VM&, Structure* oldStructure, size_t oldPropertyCapacity, size_t newPropertyCapacity);
+ Butterfly* growPropertyStorage(VM&, Structure* oldStructure, size_t newPropertyCapacity);
+ Butterfly* growArrayRight(VM&, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes); // Assumes that preCapacity is zero, and asserts as much.
+ Butterfly* growArrayRight(VM&, Structure*, size_t newIndexingPayloadSizeInBytes);
+ Butterfly* resizeArray(VM&, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes);
+ Butterfly* resizeArray(VM&, Structure*, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes); // Assumes that you're not changing whether or not the object has an indexing header.
Butterfly* unshift(Structure*, size_t numberOfSlots);
Butterfly* shift(Structure*, size_t numberOfSlots);
};
diff --git a/Source/JavaScriptCore/runtime/ButterflyInlines.h b/Source/JavaScriptCore/runtime/ButterflyInlines.h
index f01458950..a0e2af19d 100644
--- a/Source/JavaScriptCore/runtime/ButterflyInlines.h
+++ b/Source/JavaScriptCore/runtime/ButterflyInlines.h
@@ -30,33 +30,32 @@
#include "Butterfly.h"
#include "CopiedSpaceInlines.h"
#include "CopyVisitor.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "Structure.h"
namespace JSC {
-inline Butterfly* Butterfly::createUninitialized(JSGlobalData& globalData, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::createUninitialized(VM& vm, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
{
void* temp;
size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
- if (!globalData.heap.tryAllocateStorage(size, &temp))
- CRASH();
+ RELEASE_ASSERT(vm.heap.tryAllocateStorage(size, &temp));
Butterfly* result = fromBase(temp, preCapacity, propertyCapacity);
return result;
}
-inline Butterfly* Butterfly::create(JSGlobalData& globalData, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::create(VM& vm, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader& indexingHeader, size_t indexingPayloadSizeInBytes)
{
Butterfly* result = createUninitialized(
- globalData, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+ vm, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
if (hasIndexingHeader)
*result->indexingHeader() = indexingHeader;
return result;
}
-inline Butterfly* Butterfly::create(JSGlobalData& globalData, Structure* structure)
+inline Butterfly* Butterfly::create(VM& vm, Structure* structure)
{
- return create(globalData, 0, structure->outOfLineCapacity(), hasIndexingHeader(structure->indexingType()), IndexingHeader(), 0);
+ return create(vm, 0, structure->outOfLineCapacity(), hasIndexingHeader(structure->indexingType()), IndexingHeader(), 0);
}
inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes)
@@ -73,11 +72,11 @@ inline void* Butterfly::base(Structure* structure)
return base(indexingHeader()->preCapacity(structure), structure->outOfLineCapacity());
}
-inline Butterfly* Butterfly::growPropertyStorage(JSGlobalData& globalData, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity)
+inline Butterfly* Butterfly::growPropertyStorage(VM& vm, size_t preCapacity, size_t oldPropertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes, size_t newPropertyCapacity)
{
- ASSERT(newPropertyCapacity > oldPropertyCapacity);
+ RELEASE_ASSERT(newPropertyCapacity > oldPropertyCapacity);
Butterfly* result = createUninitialized(
- globalData, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
+ vm, preCapacity, newPropertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);
memcpy(
result->propertyStorage() - oldPropertyCapacity,
propertyStorage() - oldPropertyCapacity,
@@ -85,51 +84,51 @@ inline Butterfly* Butterfly::growPropertyStorage(JSGlobalData& globalData, size_
return result;
}
-inline Butterfly* Butterfly::growPropertyStorage(JSGlobalData& globalData, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity)
+inline Butterfly* Butterfly::growPropertyStorage(VM& vm, Structure* structure, size_t oldPropertyCapacity, size_t newPropertyCapacity)
{
return growPropertyStorage(
- globalData, indexingHeader()->preCapacity(structure), oldPropertyCapacity,
+ vm, indexingHeader()->preCapacity(structure), oldPropertyCapacity,
hasIndexingHeader(structure->indexingType()),
indexingHeader()->indexingPayloadSizeInBytes(structure), newPropertyCapacity);
}
-inline Butterfly* Butterfly::growPropertyStorage(JSGlobalData& globalData, Structure* oldStructure, size_t newPropertyCapacity)
+inline Butterfly* Butterfly::growPropertyStorage(VM& vm, Structure* oldStructure, size_t newPropertyCapacity)
{
return growPropertyStorage(
- globalData, oldStructure, oldStructure->outOfLineCapacity(), newPropertyCapacity);
+ vm, oldStructure, oldStructure->outOfLineCapacity(), newPropertyCapacity);
}
-inline Butterfly* Butterfly::createOrGrowArrayRight(Butterfly* oldButterfly, JSGlobalData& globalData, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::createOrGrowArrayRight(Butterfly* oldButterfly, VM& vm, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes)
{
if (!oldButterfly)
- return create(globalData, 0, propertyCapacity, true, IndexingHeader(), newIndexingPayloadSizeInBytes);
- return oldButterfly->growArrayRight(globalData, oldStructure, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes, newIndexingPayloadSizeInBytes);
+ return create(vm, 0, propertyCapacity, true, IndexingHeader(), newIndexingPayloadSizeInBytes);
+ return oldButterfly->growArrayRight(vm, oldStructure, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes, newIndexingPayloadSizeInBytes);
}
-inline Butterfly* Butterfly::growArrayRight(JSGlobalData& globalData, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::growArrayRight(VM& vm, Structure* oldStructure, size_t propertyCapacity, bool hadIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newIndexingPayloadSizeInBytes)
{
ASSERT_UNUSED(oldStructure, !indexingHeader()->preCapacity(oldStructure));
ASSERT_UNUSED(oldStructure, hadIndexingHeader == hasIndexingHeader(oldStructure->indexingType()));
void* theBase = base(0, propertyCapacity);
size_t oldSize = totalSize(0, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes);
size_t newSize = totalSize(0, propertyCapacity, true, newIndexingPayloadSizeInBytes);
- if (!globalData.heap.tryReallocateStorage(&theBase, oldSize, newSize))
+ if (!vm.heap.tryReallocateStorage(&theBase, oldSize, newSize))
return 0;
return fromBase(theBase, 0, propertyCapacity);
}
-inline Butterfly* Butterfly::growArrayRight(JSGlobalData& globalData, Structure* oldStructure, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::growArrayRight(VM& vm, Structure* oldStructure, size_t newIndexingPayloadSizeInBytes)
{
return growArrayRight(
- globalData, oldStructure, oldStructure->outOfLineCapacity(),
+ vm, oldStructure, oldStructure->outOfLineCapacity(),
hasIndexingHeader(oldStructure->indexingType()),
indexingHeader()->indexingPayloadSizeInBytes(oldStructure), newIndexingPayloadSizeInBytes);
}
-inline Butterfly* Butterfly::resizeArray(JSGlobalData& globalData, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::resizeArray(VM& vm, size_t propertyCapacity, bool oldHasIndexingHeader, size_t oldIndexingPayloadSizeInBytes, size_t newPreCapacity, bool newHasIndexingHeader, size_t newIndexingPayloadSizeInBytes)
{
Butterfly* result = createUninitialized(
- globalData, newPreCapacity, propertyCapacity, newHasIndexingHeader, newIndexingPayloadSizeInBytes);
+ vm, newPreCapacity, propertyCapacity, newHasIndexingHeader, newIndexingPayloadSizeInBytes);
// FIXME: This could be made much more efficient if we used the property size,
// not the capacity.
void* to = result->propertyStorage() - propertyCapacity;
@@ -141,11 +140,11 @@ inline Butterfly* Butterfly::resizeArray(JSGlobalData& globalData, size_t proper
return result;
}
-inline Butterfly* Butterfly::resizeArray(JSGlobalData& globalData, Structure* structure, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes)
+inline Butterfly* Butterfly::resizeArray(VM& vm, Structure* structure, size_t newPreCapacity, size_t newIndexingPayloadSizeInBytes)
{
bool hasIndexingHeader = JSC::hasIndexingHeader(structure->indexingType());
return resizeArray(
- globalData, structure->outOfLineCapacity(), hasIndexingHeader,
+ vm, structure->outOfLineCapacity(), hasIndexingHeader,
indexingHeader()->indexingPayloadSizeInBytes(structure), newPreCapacity,
hasIndexingHeader, newIndexingPayloadSizeInBytes);
}
diff --git a/Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h b/Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h
index 62a01dbcb..392d64fa5 100644
--- a/Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h
+++ b/Source/JavaScriptCore/runtime/CachedTranscendentalFunction.h
@@ -26,7 +26,7 @@
#ifndef CachedTranscendentalFunction_h
#define CachedTranscendentalFunction_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/CallData.cpp b/Source/JavaScriptCore/runtime/CallData.cpp
index ff71fa0cb..8e1d19486 100644
--- a/Source/JavaScriptCore/runtime/CallData.cpp
+++ b/Source/JavaScriptCore/runtime/CallData.cpp
@@ -29,6 +29,7 @@
#include "Executable.h"
#include "Interpreter.h"
#include "JSFunction.h"
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h
index 7df36c72a..3bbac734f 100644
--- a/Source/JavaScriptCore/runtime/CallData.h
+++ b/Source/JavaScriptCore/runtime/CallData.h
@@ -29,7 +29,7 @@
#ifndef CallData_h
#define CallData_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp
index 068919528..de904ae71 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.cpp
+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp
@@ -29,127 +29,129 @@
#include "BytecodeGenerator.h"
#include "CodeSpecializationKind.h"
+#include "Operations.h"
#include "Parser.h"
#include "StrongInlines.h"
#include "UnlinkedCodeBlock.h"
namespace JSC {
-CodeCache::CodeCache()
+const double CodeCacheMap::workingSetTime = 10.0;
+const int64_t CodeCacheMap::globalWorkingSetMaxBytes = 16000000;
+const size_t CodeCacheMap::globalWorkingSetMaxEntries = 2000;
+const unsigned CodeCacheMap::nonGlobalWorkingSetScale = 20;
+const int64_t CodeCacheMap::nonGlobalWorkingSetMaxBytes = CodeCacheMap::globalWorkingSetMaxBytes / CodeCacheMap::nonGlobalWorkingSetScale;
+const size_t CodeCacheMap::nonGlobalWorkingSetMaxEntries = CodeCacheMap::globalWorkingSetMaxEntries / CodeCacheMap::nonGlobalWorkingSetScale;
+
+void CodeCacheMap::pruneSlowCase()
{
+ m_minCapacity = std::max(m_size - m_sizeAtLastPrune, static_cast<int64_t>(0));
+ m_sizeAtLastPrune = m_size;
+ m_timeAtLastPrune = monotonicallyIncreasingTime();
+
+ if (m_capacity < m_minCapacity)
+ m_capacity = m_minCapacity;
+
+ while (m_size > m_capacity || !canPruneQuickly()) {
+ MapType::iterator it = m_map.begin();
+ m_size -= it->key.length();
+ m_map.remove(it);
+ }
}
-CodeCache::~CodeCache()
+CodeCache::CodeCache(CodeCacheKind kind)
+: m_sourceCode(kind == GlobalCodeCache ? CodeCacheMap::globalWorkingSetMaxBytes : CodeCacheMap::nonGlobalWorkingSetMaxBytes,
+ kind == GlobalCodeCache ? CodeCacheMap::globalWorkingSetMaxEntries : CodeCacheMap::nonGlobalWorkingSetMaxEntries)
{
}
-CodeCache::CodeBlockKey CodeCache::makeCodeBlockKey(const SourceCode& source, CodeCache::CodeType type, JSParserStrictness strictness)
+CodeCache::~CodeCache()
{
- return std::make_pair(source.toString(), (type << 1) | strictness);
}
template <typename T> struct CacheTypes { };
template <> struct CacheTypes<UnlinkedProgramCodeBlock> {
typedef JSC::ProgramNode RootNode;
- static const CodeCache::CodeType codeType = CodeCache::ProgramType;
+ static const SourceCodeKey::CodeType codeType = SourceCodeKey::ProgramType;
};
template <> struct CacheTypes<UnlinkedEvalCodeBlock> {
typedef JSC::EvalNode RootNode;
- static const CodeCache::CodeType codeType = CodeCache::EvalType;
+ static const SourceCodeKey::CodeType codeType = SourceCodeKey::EvalType;
};
template <class UnlinkedCodeBlockType, class ExecutableType>
-UnlinkedCodeBlockType* CodeCache::getCodeBlock(JSGlobalData& globalData, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+UnlinkedCodeBlockType* CodeCache::generateBytecode(VM& vm, JSScope* scope, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
{
- CodeBlockKey key = makeCodeBlockKey(source, CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
- bool storeInCache = false;
- if (debuggerMode == DebuggerOff && profilerMode == ProfilerOff) {
- const Strong<UnlinkedCodeBlock>* result = m_cachedCodeBlocks.find(key);
- if (result) {
- UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(result->get());
- unsigned firstLine = source.firstLine() + unlinkedCode->firstLine();
- executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount());
- return unlinkedCode;
- }
- storeInCache = true;
- }
-
typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
- RefPtr<RootNode> rootNode = parse<RootNode>(&globalData, source, 0, Identifier(), strictness, JSParseProgramCode, error);
+ RefPtr<RootNode> rootNode = parse<RootNode>(&vm, source, 0, Identifier(), strictness, JSParseProgramCode, error);
if (!rootNode)
return 0;
- executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine());
+ executable->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo(), rootNode->lastLine(), rootNode->startColumn());
- UnlinkedCodeBlockType* unlinkedCode = UnlinkedCodeBlockType::create(&globalData, executable->executableInfo());
+ UnlinkedCodeBlockType* unlinkedCode = UnlinkedCodeBlockType::create(&vm, executable->executableInfo());
unlinkedCode->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->lineNo() - source.firstLine(), rootNode->lastLine() - rootNode->lineNo());
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(globalData, rootNode.get(), unlinkedCode, debuggerMode, profilerMode)));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(vm, scope, rootNode.get(), unlinkedCode, debuggerMode, profilerMode)));
error = generator->generate();
rootNode->destroyData();
if (error.m_type != ParserError::ErrorNone)
return 0;
-
- if (storeInCache)
- m_cachedCodeBlocks.add(key, Strong<UnlinkedCodeBlock>(globalData, unlinkedCode));
-
return unlinkedCode;
}
-UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(JSGlobalData& globalData, ProgramExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+template <class UnlinkedCodeBlockType, class ExecutableType>
+UnlinkedCodeBlockType* CodeCache::getCodeBlock(VM& vm, JSScope* scope, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
{
- return getCodeBlock<UnlinkedProgramCodeBlock>(globalData, executable, source, strictness, debuggerMode, profilerMode, error);
-}
+ // We completely skip the cache if we're an eval that isn't at the top of the scope chain.
+ if (CacheTypes<UnlinkedCodeBlockType>::codeType == SourceCodeKey::EvalType) {
+ if (scope->next() && !scope->isActivationObject())
+ return generateBytecode<UnlinkedCodeBlockType, ExecutableType>(vm, scope, executable, source, strictness, debuggerMode, profilerMode, error);
+ }
-UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(JSGlobalData& globalData, EvalExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
-{
- return getCodeBlock<UnlinkedEvalCodeBlock>(globalData, executable, source, strictness, debuggerMode, profilerMode, error);
-}
+ SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
+ CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
+ bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff;
-UnlinkedFunctionCodeBlock* CodeCache::generateFunctionCodeBlock(JSGlobalData& globalData, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
-{
- RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(&globalData, source, executable->parameters(), executable->name(), executable->isInStrictContext() ? JSParseStrict : JSParseNormal, JSParseFunctionCode, error);
+ if (!addResult.isNewEntry && canCache) {
+ UnlinkedCodeBlockType* unlinkedCode = jsCast<UnlinkedCodeBlockType*>(addResult.iterator->value.cell.get());
+ unsigned firstLine = source.firstLine() + unlinkedCode->firstLine();
+ unsigned startColumn = source.firstLine() ? source.startColumn() : 0;
+ executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount(), startColumn);
+ return unlinkedCode;
+ }
+ UnlinkedCodeBlockType* unlinkedCode = generateBytecode<UnlinkedCodeBlockType, ExecutableType>(vm, scope, executable, source, strictness, debuggerMode, profilerMode, error);
- if (!body) {
- ASSERT(error.m_type != ParserError::ErrorNone);
- return 0;
+ if (!canCache || !unlinkedCode) {
+ m_sourceCode.remove(addResult.iterator);
+ return unlinkedCode;
}
- if (executable->forceUsesArguments())
- body->setUsesArguments();
- body->finishParsing(executable->parameters(), executable->name(), executable->functionNameIsInScopeToggle());
- executable->recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
-
- UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&globalData, FunctionCode, ExecutableInfo(body->needsActivation(), body->usesEval(), body->isStrictMode(), kind == CodeForConstruct));
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(globalData, body.get(), result, debuggerMode, profilerMode)));
- error = generator->generate();
- body->destroyData();
- if (error.m_type != ParserError::ErrorNone)
- return 0;
- m_cachedFunctionCode.add(result, Strong<UnlinkedFunctionCodeBlock>(globalData, result));
- return result;
+ addResult.iterator->value = SourceCodeValue(vm, unlinkedCode, m_sourceCode.age());
+ return unlinkedCode;
}
-UnlinkedFunctionCodeBlock* CodeCache::getFunctionCodeBlock(JSGlobalData& globalData, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
+UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
{
- return generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error);
+ return getCodeBlock<UnlinkedProgramCodeBlock>(vm, 0, executable, source, strictness, debuggerMode, profilerMode, error);
}
-CodeCache::GlobalFunctionKey CodeCache::makeGlobalFunctionKey(const SourceCode& source, const String& name)
+UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, JSScope* scope, EvalExecutable* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
{
- return GlobalFunctionKey(source.toString(), name);
+ return getCodeBlock<UnlinkedEvalCodeBlock>(vm, scope, executable, source, strictness, debuggerMode, profilerMode, error);
}
-UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlobalData& globalData, const Identifier& name, const SourceCode& source, ParserError& error)
+UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error)
{
- GlobalFunctionKey key = makeGlobalFunctionKey(source, name.string());
- const Strong<UnlinkedFunctionExecutable>* result = m_cachedGlobalFunctions.find(key);
- if (result)
- return result->get();
+ SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal);
+ CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
+ if (!addResult.isNewEntry)
+ return jsCast<UnlinkedFunctionExecutable*>(addResult.iterator->value.cell.get());
- RefPtr<ProgramNode> program = parse<ProgramNode>(&globalData, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
+ RefPtr<ProgramNode> program = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
if (!program) {
ASSERT(error.m_type != ParserError::ErrorNone);
+ m_sourceCode.remove(addResult.iterator);
return 0;
}
@@ -159,21 +161,16 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(JSGlo
ASSERT(exprStatement->isExprStatement());
ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
ASSERT(funcExpr);
- ASSERT(funcExpr->isFuncExprNode());
+ RELEASE_ASSERT(funcExpr->isFuncExprNode());
FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
ASSERT(body);
ASSERT(body->ident().isNull());
- UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&globalData, source, body);
- functionExecutable->m_nameValue.set(globalData, functionExecutable, jsString(&globalData, name.string()));
+ UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body);
+ functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
- m_cachedGlobalFunctions.add(key, Strong<UnlinkedFunctionExecutable>(globalData, functionExecutable));
+ addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age());
return functionExecutable;
}
-void CodeCache::usedFunctionCode(JSGlobalData& globalData, UnlinkedFunctionCodeBlock* codeBlock)
-{
- m_cachedFunctionCode.add(codeBlock, Strong<UnlinkedFunctionCodeBlock>(globalData, codeBlock));
-}
-
}
diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h
index 733de42d6..986b266c2 100644
--- a/Source/JavaScriptCore/runtime/CodeCache.h
+++ b/Source/JavaScriptCore/runtime/CodeCache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,9 +28,10 @@
#include "CodeSpecializationKind.h"
#include "ParserModes.h"
+#include "SourceCode.h"
#include "Strong.h"
#include "WeakRandom.h"
-
+#include <wtf/CurrentTime.h>
#include <wtf/FixedArray.h>
#include <wtf/Forward.h>
#include <wtf/PassOwnPtr.h>
@@ -40,88 +41,239 @@
namespace JSC {
class EvalExecutable;
+class FunctionBodyNode;
class Identifier;
+class JSScope;
class ProgramExecutable;
class UnlinkedCodeBlock;
class UnlinkedEvalCodeBlock;
class UnlinkedFunctionCodeBlock;
class UnlinkedFunctionExecutable;
class UnlinkedProgramCodeBlock;
-class JSGlobalData;
+class VM;
struct ParserError;
class SourceCode;
class SourceProvider;
-template <typename KeyType, typename EntryType, int CacheSize> class CacheMap {
- typedef typename HashMap<KeyType, unsigned>::iterator iterator;
+class SourceCodeKey {
public:
- CacheMap()
- : m_randomGenerator((static_cast<uint32_t>(randomNumber() * std::numeric_limits<uint32_t>::max())))
+ enum CodeType { EvalType, ProgramType, FunctionType };
+
+ SourceCodeKey()
{
}
- const EntryType* find(const KeyType& key)
+
+ SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserStrictness jsParserStrictness)
+ : m_sourceCode(sourceCode)
+ , m_name(name)
+ , m_flags((codeType << 1) | jsParserStrictness)
+ , m_hash(string().impl()->hash())
{
- iterator result = m_map.find(key);
- if (result == m_map.end())
- return 0;
- return &m_data[result->value].second;
}
- void add(const KeyType& key, const EntryType& value)
+
+ SourceCodeKey(WTF::HashTableDeletedValueType)
+ : m_sourceCode(WTF::HashTableDeletedValue)
{
- iterator result = m_map.find(key);
- if (result != m_map.end()) {
- m_data[result->value].second = value;
- return;
+ }
+
+ bool isHashTableDeletedValue() const { return m_sourceCode.isHashTableDeletedValue(); }
+
+ unsigned hash() const { return m_hash; }
+
+ size_t length() const { return m_sourceCode.length(); }
+
+ bool isNull() const { return m_sourceCode.isNull(); }
+
+ // To save memory, we compute our string on demand. It's expected that source
+ // providers cache their strings to make this efficient.
+ String string() const { return m_sourceCode.toString(); }
+
+ bool operator==(const SourceCodeKey& other) const
+ {
+ return m_hash == other.m_hash
+ && length() == other.length()
+ && m_flags == other.m_flags
+ && m_name == other.m_name
+ && string() == other.string();
+ }
+
+private:
+ SourceCode m_sourceCode;
+ String m_name;
+ unsigned m_flags;
+ unsigned m_hash;
+};
+
+struct SourceCodeKeyHash {
+ static unsigned hash(const SourceCodeKey& key) { return key.hash(); }
+ static bool equal(const SourceCodeKey& a, const SourceCodeKey& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+struct SourceCodeKeyHashTraits : SimpleClassHashTraits<SourceCodeKey> {
+ static const bool hasIsEmptyValueFunction = true;
+ static bool isEmptyValue(const SourceCodeKey& sourceCodeKey) { return sourceCodeKey.isNull(); }
+};
+
+struct SourceCodeValue {
+ SourceCodeValue()
+ {
+ }
+
+ SourceCodeValue(VM& vm, JSCell* cell, int64_t age)
+ : cell(vm, cell)
+ , age(age)
+ {
+ }
+
+ Strong<JSCell> cell;
+ int64_t age;
+};
+
+class CodeCacheMap {
+public:
+ typedef HashMap<SourceCodeKey, SourceCodeValue, SourceCodeKeyHash, SourceCodeKeyHashTraits> MapType;
+ typedef MapType::iterator iterator;
+ typedef MapType::AddResult AddResult;
+
+ CodeCacheMap(int64_t workingSetMaxBytes, size_t workingSetMaxEntries)
+ : m_size(0)
+ , m_sizeAtLastPrune(0)
+ , m_timeAtLastPrune(monotonicallyIncreasingTime())
+ , m_minCapacity(0)
+ , m_capacity(0)
+ , m_age(0)
+ , m_workingSetMaxBytes(workingSetMaxBytes)
+ , m_workingSetMaxEntries(workingSetMaxEntries)
+ {
+ }
+
+ AddResult add(const SourceCodeKey& key, const SourceCodeValue& value)
+ {
+ prune();
+
+ AddResult addResult = m_map.add(key, value);
+ if (addResult.isNewEntry) {
+ m_size += key.length();
+ m_age += key.length();
+ return addResult;
+ }
+
+ int64_t age = m_age - addResult.iterator->value.age;
+ if (age > m_capacity) {
+ // A requested object is older than the cache's capacity. We can
+ // infer that requested objects are subject to high eviction probability,
+ // so we grow the cache to improve our hit rate.
+ m_capacity += recencyBias * oldObjectSamplingMultiplier * key.length();
+ } else if (age < m_capacity / 2) {
+ // A requested object is much younger than the cache's capacity. We can
+ // infer that requested objects are subject to low eviction probability,
+ // so we shrink the cache to save memory.
+ m_capacity -= recencyBias * key.length();
+ if (m_capacity < m_minCapacity)
+ m_capacity = m_minCapacity;
}
- size_t newIndex = m_randomGenerator.getUint32() % CacheSize;
- if (m_data[newIndex].second)
- m_map.remove(m_data[newIndex].first);
- m_map.add(key, newIndex);
- m_data[newIndex].first = key;
- m_data[newIndex].second = value;
- ASSERT(m_map.size() <= CacheSize);
+
+ addResult.iterator->value.age = m_age;
+ m_age += key.length();
+ return addResult;
}
+
+ void remove(iterator it)
+ {
+ m_size -= it->key.length();
+ m_map.remove(it);
+ }
+
+ void clear()
+ {
+ m_size = 0;
+ m_age = 0;
+ m_map.clear();
+ }
+
+ int64_t age() { return m_age; }
+
+ static const int64_t globalWorkingSetMaxBytes;
+ static const size_t globalWorkingSetMaxEntries;
+
+ // We have a smaller cap for the per-codeblock CodeCache that approximates the
+ // linked EvalCodeCache limits, but still allows us to keep large string based
+ // evals at least partially cached.
+ static const unsigned nonGlobalWorkingSetScale;
+ static const int64_t nonGlobalWorkingSetMaxBytes;
+ static const size_t nonGlobalWorkingSetMaxEntries;
+
private:
- HashMap<KeyType, unsigned> m_map;
- FixedArray<std::pair<KeyType, EntryType>, CacheSize> m_data;
- WeakRandom m_randomGenerator;
+ // This constant factor biases cache capacity toward allowing a minimum
+ // working set to enter the cache before it starts evicting.
+ static const double workingSetTime;
+
+ // This constant factor biases cache capacity toward recent activity. We
+ // want to adapt to changing workloads.
+ static const int64_t recencyBias = 4;
+
+ // This constant factor treats a sampled event for one old object as if it
+ // happened for many old objects. Most old objects are evicted before we can
+ // sample them, so we need to extrapolate from the ones we do sample.
+ static const int64_t oldObjectSamplingMultiplier = 32;
+
+ size_t numberOfEntries() const { return static_cast<size_t>(m_map.size()); }
+ bool canPruneQuickly() const { return numberOfEntries() < m_workingSetMaxEntries; }
+
+ void pruneSlowCase();
+ void prune()
+ {
+ if (m_size <= m_capacity && canPruneQuickly())
+ return;
+
+ if (monotonicallyIncreasingTime() - m_timeAtLastPrune < workingSetTime
+ && m_size - m_sizeAtLastPrune < m_workingSetMaxBytes
+ && canPruneQuickly())
+ return;
+
+ pruneSlowCase();
+ }
+
+ MapType m_map;
+ int64_t m_size;
+ int64_t m_sizeAtLastPrune;
+ double m_timeAtLastPrune;
+ int64_t m_minCapacity;
+ int64_t m_capacity;
+ int64_t m_age;
+ const int64_t m_workingSetMaxBytes;
+ const size_t m_workingSetMaxEntries;
};
-class CodeCache {
+// Caches top-level code such as <script>, eval(), new Function, and JSEvaluateScript().
+class CodeCache : public RefCounted<CodeCache> {
public:
- static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); }
+ enum CodeCacheKind { GlobalCodeCache, NonGlobalCodeCache };
+ static PassRefPtr<CodeCache> create(CodeCacheKind kind) { return adoptRef(new CodeCache(kind)); }
- UnlinkedProgramCodeBlock* getProgramCodeBlock(JSGlobalData&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
- UnlinkedEvalCodeBlock* getEvalCodeBlock(JSGlobalData&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
- UnlinkedFunctionCodeBlock* getFunctionCodeBlock(JSGlobalData&, UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
- UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(JSGlobalData&, const Identifier&, const SourceCode&, ParserError&);
- void usedFunctionCode(JSGlobalData&, UnlinkedFunctionCodeBlock*);
+ UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+ UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, JSScope*, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+ UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);
~CodeCache();
- enum CodeType { EvalType, ProgramType, FunctionType };
- typedef std::pair<String, unsigned> CodeBlockKey;
- typedef std::pair<String, String> GlobalFunctionKey;
+ void clear()
+ {
+ m_sourceCode.clear();
+ }
private:
- CodeCache();
-
- UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(JSGlobalData&, UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
+ CodeCache(CodeCacheKind);
- template <class UnlinkedCodeBlockType, class ExecutableType> inline UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
- CodeBlockKey makeCodeBlockKey(const SourceCode&, CodeType, JSParserStrictness);
- GlobalFunctionKey makeGlobalFunctionKey(const SourceCode&, const String&);
+ template <class UnlinkedCodeBlockType, class ExecutableType>
+ UnlinkedCodeBlockType* getCodeBlock(VM&, JSScope*, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
- enum {
- kMaxCodeBlockEntries = 1024,
- kMaxGlobalFunctionEntries = 1024,
- kMaxFunctionCodeBlocks = 1024
- };
+ template <class UnlinkedCodeBlockType, class ExecutableType>
+ UnlinkedCodeBlockType* generateBytecode(VM&, JSScope*, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
- CacheMap<CodeBlockKey, Strong<UnlinkedCodeBlock>, kMaxCodeBlockEntries> m_cachedCodeBlocks;
- CacheMap<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable>, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions;
- CacheMap<UnlinkedFunctionCodeBlock*, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_cachedFunctionCode;
+ CodeCacheMap m_sourceCode;
};
}
-#endif
+#endif // CodeCache_h
diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp b/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
index e929d7a49..e19df1c64 100644
--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -23,15 +23,15 @@
namespace JSC {
-#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
-#define INITIALIZE_KEYWORD(name) , name##Keyword(globalData, #name)
+#define INITIALIZE_PROPERTY_NAME(name) , name(vm, #name)
+#define INITIALIZE_KEYWORD(name) , name##Keyword(vm, #name)
-CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
+CommonIdentifiers::CommonIdentifiers(VM* vm)
: nullIdentifier()
, emptyIdentifier(Identifier::EmptyIdentifier)
- , underscoreProto(globalData, "__proto__")
- , thisIdentifier(globalData, "this")
- , useStrictIdentifier(globalData, "use strict")
+ , underscoreProto(vm, "__proto__")
+ , thisIdentifier(vm, "this")
+ , useStrictIdentifier(vm, "use strict")
JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(INITIALIZE_KEYWORD)
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
{
diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
index ae3b45b8c..13cf037d5 100644
--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -27,40 +27,93 @@
// 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(Array) \
+ macro(Boolean) \
+ macro(Date) \
+ macro(Error) \
+ macro(EvalError) \
+ macro(Function) \
+ macro(Infinity) \
+ macro(JSON) \
+ macro(Math) \
+ macro(NaN) \
+ macro(Number) \
+ macro(Object) \
+ macro(RangeError) \
+ macro(ReferenceError) \
+ macro(RegExp) \
+ macro(String) \
+ macro(SyntaxError) \
+ macro(TypeError) \
+ macro(URIError) \
+ macro(UTC) \
+ macro(__defineGetter__) \
+ macro(__defineSetter__) \
+ macro(__lookupGetter__) \
+ macro(__lookupSetter__) \
+ macro(anonymous) \
macro(apply) \
macro(arguments) \
- macro(Array) \
macro(bind) \
+ macro(bytecode) \
+ macro(bytecodeIndex) \
+ macro(bytecodes) \
+ macro(bytecodesID) \
macro(call) \
macro(callee) \
macro(caller) \
+ macro(compilationKind) \
+ macro(compilations) \
macro(compile) \
macro(configurable) \
macro(constructor) \
+ macro(count) \
+ macro(counters) \
+ macro(description) \
+ macro(descriptions) \
+ macro(displayName) \
+ macro(document) \
macro(enumerable) \
macro(eval) \
macro(exec) \
+ macro(executionCount) \
+ macro(exitKind) \
macro(fromCharCode) \
- macro(global) \
macro(get) \
+ macro(global) \
macro(hasOwnProperty) \
+ macro(hash) \
+ macro(header) \
+ macro(id) \
macro(ignoreCase) \
macro(index) \
+ macro(inferredName) \
macro(input) \
+ macro(instructionCount) \
macro(isArray) \
macro(isPrototypeOf) \
+ macro(isWatchpoint) \
+ macro(join) \
macro(lastIndex) \
macro(length) \
macro(message) \
macro(multiline) \
macro(name) \
macro(now) \
- macro(Object) \
+ macro(numInlinedCalls) \
+ macro(numInlinedGetByIds) \
+ macro(numInlinedPutByIds) \
+ macro(opcode) \
+ macro(origin) \
+ macro(osrExitSites) \
+ macro(osrExits) \
macro(parse) \
+ macro(profiledBytecodes) \
macro(propertyIsEnumerable) \
macro(prototype) \
macro(set) \
macro(source) \
+ macro(sourceCode) \
macro(stack) \
macro(test) \
macro(toExponential) \
@@ -70,12 +123,10 @@
macro(toLocaleString) \
macro(toPrecision) \
macro(toString) \
- macro(UTC) \
macro(value) \
macro(valueOf) \
- macro(writable) \
- macro(displayName) \
- macro(join)
+ macro(window) \
+ macro(writable)
#define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
macro(null) \
@@ -130,8 +181,8 @@ namespace JSC {
class CommonIdentifiers {
WTF_MAKE_NONCOPYABLE(CommonIdentifiers); WTF_MAKE_FAST_ALLOCATED;
private:
- CommonIdentifiers(JSGlobalData*);
- friend class JSGlobalData;
+ CommonIdentifiers(VM*);
+ friend class VM;
public:
const Identifier nullIdentifier;
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
index 2f5159461..731b773f0 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h
@@ -78,7 +78,7 @@ ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, JSStack* stack, CodeSpec
inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
{
if (!baseVal.isObject()) {
- exec->globalData().exception = createInvalidParamError(exec, "in", baseVal);
+ exec->vm().exception = createInvalidParameterError(exec, "in", baseVal);
return false;
}
@@ -92,7 +92,7 @@ inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
return baseObj->hasProperty(exec, jsCast<NameInstance*>(propName.asCell())->privateName());
Identifier property(exec, propName.toString(exec)->value(exec));
- if (exec->globalData().exception)
+ if (exec->vm().exception)
return false;
return baseObj->hasProperty(exec, property);
}
diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp
index 3de8d4841..a2d8a6b5f 100644
--- a/Source/JavaScriptCore/runtime/Completion.cpp
+++ b/Source/JavaScriptCore/runtime/Completion.cpp
@@ -25,11 +25,12 @@
#include "CallFrame.h"
#include "CodeProfiling.h"
+#include "Debugger.h"
+#include "Interpreter.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
-#include "Interpreter.h"
+#include "Operations.h"
#include "Parser.h"
-#include "Debugger.h"
#include <wtf/WTFThreadData.h>
#include <stdio.h>
@@ -38,7 +39,7 @@ namespace JSC {
bool checkSyntax(ExecState* exec, const SourceCode& source, JSValue* returnedException)
{
JSLockHolder lock(exec);
- ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
+ RELEASE_ASSERT(exec->vm().identifierTable == wtfThreadData().currentIdentifierTable());
ProgramExecutable* program = ProgramExecutable::create(exec, source);
JSObject* error = program->checkSyntax(exec);
@@ -50,22 +51,29 @@ bool checkSyntax(ExecState* exec, const SourceCode& source, JSValue* returnedExc
return true;
}
+
+bool checkSyntax(VM& vm, const SourceCode& source, ParserError& error)
+{
+ JSLockHolder lock(vm);
+ RELEASE_ASSERT(vm.identifierTable == wtfThreadData().currentIdentifierTable());
+ RefPtr<ProgramNode> programNode = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error);
+ return programNode;
+}
JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, JSValue* returnedException)
{
JSLockHolder lock(exec);
- ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
- if (exec->globalData().isCollectorBusy())
- CRASH();
+ RELEASE_ASSERT(exec->vm().identifierTable == wtfThreadData().currentIdentifierTable());
+ RELEASE_ASSERT(!exec->vm().isCollectorBusy());
CodeProfiling profile(source);
ProgramExecutable* program = ProgramExecutable::create(exec, source);
if (!program) {
if (returnedException)
- *returnedException = exec->globalData().exception;
+ *returnedException = exec->vm().exception;
- exec->globalData().exception = JSValue();
+ exec->vm().exception = JSValue();
return jsUndefined();
}
@@ -82,7 +90,7 @@ JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, J
return jsUndefined();
}
- ASSERT(result);
+ RELEASE_ASSERT(result);
return result;
}
diff --git a/Source/JavaScriptCore/runtime/Completion.h b/Source/JavaScriptCore/runtime/Completion.h
index d150fcea2..78f8ac795 100644
--- a/Source/JavaScriptCore/runtime/Completion.h
+++ b/Source/JavaScriptCore/runtime/Completion.h
@@ -23,14 +23,17 @@
#ifndef Completion_h
#define Completion_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
-
+
+ struct ParserError;
class ExecState;
class JSScope;
class SourceCode;
+ class VM;
+ JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);
JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
diff --git a/Source/JavaScriptCore/runtime/ConstructData.cpp b/Source/JavaScriptCore/runtime/ConstructData.cpp
index 5da2a911c..3dc46180c 100644
--- a/Source/JavaScriptCore/runtime/ConstructData.cpp
+++ b/Source/JavaScriptCore/runtime/ConstructData.cpp
@@ -30,6 +30,7 @@
#include "Interpreter.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/ConstructData.h b/Source/JavaScriptCore/runtime/ConstructData.h
index 6426b044e..10317a2f9 100644
--- a/Source/JavaScriptCore/runtime/ConstructData.h
+++ b/Source/JavaScriptCore/runtime/ConstructData.h
@@ -30,7 +30,7 @@
#define ConstructData_h
#include "CallData.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index 9a162e9e7..b21a5d0c2 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -31,6 +31,7 @@
#include "JSString.h"
#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include <math.h>
#include <time.h>
#include <wtf/MathExtras.h>
@@ -80,9 +81,9 @@ DateConstructor::DateConstructor(JSGlobalObject* globalObject, Structure* struct
void DateConstructor::finishCreation(ExecState* exec, DatePrototype* datePrototype)
{
- Base::finishCreation(exec->globalData(), datePrototype->classInfo()->className);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, datePrototype, DontEnum | DontDelete | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(7), ReadOnly | DontEnum | DontDelete);
+ Base::finishCreation(exec->vm(), datePrototype->classInfo()->className);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, datePrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(7), ReadOnly | DontEnum | DontDelete);
}
bool DateConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
@@ -124,13 +125,13 @@ JSObject* constructDate(ExecState* exec, JSGlobalObject* globalObject, const Arg
args.at(5).toNumber(exec),
args.at(6).toNumber(exec)
};
- if (!isfinite(doubleArguments[0])
- || !isfinite(doubleArguments[1])
- || (numArgs >= 3 && !isfinite(doubleArguments[2]))
- || (numArgs >= 4 && !isfinite(doubleArguments[3]))
- || (numArgs >= 5 && !isfinite(doubleArguments[4]))
- || (numArgs >= 6 && !isfinite(doubleArguments[5]))
- || (numArgs >= 7 && !isfinite(doubleArguments[6])))
+ if (!std::isfinite(doubleArguments[0])
+ || !std::isfinite(doubleArguments[1])
+ || (numArgs >= 3 && !std::isfinite(doubleArguments[2]))
+ || (numArgs >= 4 && !std::isfinite(doubleArguments[3]))
+ || (numArgs >= 5 && !std::isfinite(doubleArguments[4]))
+ || (numArgs >= 6 && !std::isfinite(doubleArguments[5]))
+ || (numArgs >= 7 && !std::isfinite(doubleArguments[6])))
value = QNaN;
else {
GregorianDateTime t;
@@ -198,13 +199,13 @@ static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec)
exec->argument(6).toNumber(exec)
};
int n = exec->argumentCount();
- if (isnan(doubleArguments[0])
- || isnan(doubleArguments[1])
- || (n >= 3 && isnan(doubleArguments[2]))
- || (n >= 4 && isnan(doubleArguments[3]))
- || (n >= 5 && isnan(doubleArguments[4]))
- || (n >= 6 && isnan(doubleArguments[5]))
- || (n >= 7 && isnan(doubleArguments[6])))
+ if (std::isnan(doubleArguments[0])
+ || std::isnan(doubleArguments[1])
+ || (n >= 3 && std::isnan(doubleArguments[2]))
+ || (n >= 4 && std::isnan(doubleArguments[3]))
+ || (n >= 5 && std::isnan(doubleArguments[4]))
+ || (n >= 6 && std::isnan(doubleArguments[5]))
+ || (n >= 7 && std::isnan(doubleArguments[6])))
return JSValue::encode(jsNaN());
GregorianDateTime t;
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.h b/Source/JavaScriptCore/runtime/DateConstructor.h
index f089e036c..5a6200e99 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.h
+++ b/Source/JavaScriptCore/runtime/DateConstructor.h
@@ -40,9 +40,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/DateInstance.cpp b/Source/JavaScriptCore/runtime/DateInstance.cpp
index 47a19df47..db7b84634 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.cpp
+++ b/Source/JavaScriptCore/runtime/DateInstance.cpp
@@ -24,7 +24,7 @@
#include "JSDateMath.h"
#include "JSGlobalObject.h"
-
+#include "Operations.h"
#include <math.h>
#include <wtf/MathExtras.h>
@@ -35,22 +35,22 @@ namespace JSC {
const ClassInfo DateInstance::s_info = {"Date", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(DateInstance)};
DateInstance::DateInstance(ExecState* exec, Structure* structure)
- : JSWrapperObject(exec->globalData(), structure)
+ : JSWrapperObject(exec->vm(), structure)
{
}
-void DateInstance::finishCreation(JSGlobalData& globalData)
+void DateInstance::finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
- setInternalValue(globalData, jsNaN());
+ setInternalValue(vm, jsNaN());
}
-void DateInstance::finishCreation(JSGlobalData& globalData, double time)
+void DateInstance::finishCreation(VM& vm, double time)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
- setInternalValue(globalData, jsNumber(timeClip(time)));
+ setInternalValue(vm, jsNumber(timeClip(time)));
}
void DateInstance::destroy(JSCell* cell)
@@ -61,11 +61,11 @@ void DateInstance::destroy(JSCell* cell)
const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exec) const
{
double milli = internalNumber();
- if (isnan(milli))
+ if (std::isnan(milli))
return 0;
if (!m_data)
- m_data = exec->globalData().dateInstanceCache.add(milli);
+ m_data = exec->vm().dateInstanceCache.add(milli);
if (m_data->m_gregorianDateTimeCachedForMS != milli) {
msToGregorianDateTime(exec, milli, false, m_data->m_cachedGregorianDateTime);
@@ -77,11 +77,11 @@ const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exe
const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(ExecState* exec) const
{
double milli = internalNumber();
- if (isnan(milli))
+ if (std::isnan(milli))
return 0;
if (!m_data)
- m_data = exec->globalData().dateInstanceCache.add(milli);
+ m_data = exec->vm().dateInstanceCache.add(milli);
if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
msToGregorianDateTime(exec, milli, true, m_data->m_cachedGregorianDateTimeUTC);
diff --git a/Source/JavaScriptCore/runtime/DateInstance.h b/Source/JavaScriptCore/runtime/DateInstance.h
index 9742e6889..870777240 100644
--- a/Source/JavaScriptCore/runtime/DateInstance.h
+++ b/Source/JavaScriptCore/runtime/DateInstance.h
@@ -28,8 +28,8 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
protected:
JS_EXPORT_PRIVATE DateInstance(ExecState*, Structure*);
- void finishCreation(JSGlobalData&);
- JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, double);
+ void finishCreation(VM&);
+ JS_EXPORT_PRIVATE void finishCreation(VM&, double);
static void destroy(JSCell*);
@@ -39,14 +39,14 @@ namespace JSC {
static DateInstance* create(ExecState* exec, Structure* structure, double date)
{
DateInstance* instance = new (NotNull, allocateCell<DateInstance>(*exec->heap())) DateInstance(exec, structure);
- instance->finishCreation(exec->globalData(), date);
+ instance->finishCreation(exec->vm(), date);
return instance;
}
static DateInstance* create(ExecState* exec, Structure* structure)
{
DateInstance* instance = new (NotNull, allocateCell<DateInstance>(*exec->heap())) DateInstance(exec, structure);
- instance->finishCreation(exec->globalData());
+ instance->finishCreation(exec->vm());
return instance;
}
@@ -68,9 +68,9 @@ namespace JSC {
return calculateGregorianDateTimeUTC(exec);
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
private:
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 75da466fb..9cbaf7480 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -33,6 +33,7 @@
#include "JSStringBuilder.h"
#include "Lookup.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#if !PLATFORM(MAC) && HAVE(LANGINFO_H)
#include <langinfo.h>
@@ -46,7 +47,6 @@
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/StringExtras.h>
-#include <wtf/UnusedParam.h>
#if HAVE(SYS_PARAM_H)
#include <sys/param.h>
@@ -60,7 +60,7 @@
#include <sys/timeb.h>
#endif
-#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WX) && OS(DARWIN)) || (PLATFORM(QT) && OS(DARWIN))
+#if OS(DARWIN) && USE(CF)
#include <CoreFoundation/CoreFoundation.h>
#elif USE(ICU_UNICODE)
#include <unicode/udat.h>
@@ -124,9 +124,9 @@ namespace JSC {
enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
-#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WX) && OS(DARWIN)) || (PLATFORM(QT) && OS(DARWIN))
+#if OS(DARWIN) && USE(CF)
-// FIXME: Since this is superior to the strftime-based version, why limit this to PLATFORM(MAC)?
+// FIXME: Since this is superior to the strftime-based version, why limit this to OS(DARWIN)?
// Instead we should consider using this whenever USE(CF) is true.
static CFDateFormatterStyle styleFromArgString(const String& string, CFDateFormatterStyle defaultStyle)
@@ -245,7 +245,7 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L
length += GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systemTime, 0, buffer.data() + length, buffer.size() - length);
}
} else
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
// Remove terminating null character.
if (length)
@@ -336,7 +336,7 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, doubl
return formatLocaleDate(exec, *gregorianDateTime, format);
}
-#endif // !PLATFORM(MAC) && !PLATFORM(IOS)
+#endif // OS(DARWIN) && USE(CF)
static EncodedJSValue formateDateInstance(ExecState* exec, DateTimeFormat format, bool asUTCVariant)
{
@@ -374,7 +374,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms
if (maxArgs >= 4 && idx < numArgs) {
t->setHour(0);
double hours = exec->argument(idx++).toIntegerPreserveNaN(exec);
- ok = isfinite(hours);
+ ok = std::isfinite(hours);
milliseconds += hours * msPerHour;
}
@@ -382,7 +382,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms
if (maxArgs >= 3 && idx < numArgs && ok) {
t->setMinute(0);
double minutes = exec->argument(idx++).toIntegerPreserveNaN(exec);
- ok = isfinite(minutes);
+ ok = std::isfinite(minutes);
milliseconds += minutes * msPerMinute;
}
@@ -390,7 +390,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms
if (maxArgs >= 2 && idx < numArgs && ok) {
t->setSecond(0);
double seconds = exec->argument(idx++).toIntegerPreserveNaN(exec);
- ok = isfinite(seconds);
+ ok = std::isfinite(seconds);
milliseconds += seconds * msPerSecond;
}
@@ -400,7 +400,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms
// milliseconds
if (idx < numArgs) {
double millis = exec->argument(idx).toIntegerPreserveNaN(exec);
- ok = isfinite(millis);
+ ok = std::isfinite(millis);
milliseconds += millis;
} else
milliseconds += *ms;
@@ -426,19 +426,19 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, int maxArgs, double *ms
// years
if (maxArgs >= 3 && idx < numArgs) {
double years = exec->argument(idx++).toIntegerPreserveNaN(exec);
- ok = isfinite(years);
+ ok = std::isfinite(years);
t->setYear(toInt32(years));
}
// months
if (maxArgs >= 2 && idx < numArgs && ok) {
double months = exec->argument(idx++).toIntegerPreserveNaN(exec);
- ok = isfinite(months);
+ ok = std::isfinite(months);
t->setMonth(toInt32(months));
}
// days
if (idx < numArgs && ok) {
double days = exec->argument(idx++).toIntegerPreserveNaN(exec);
- ok = isfinite(days);
+ ok = std::isfinite(days);
t->setMonthDay(0);
*ms += days * msPerDay;
}
@@ -508,7 +508,7 @@ DatePrototype::DatePrototype(ExecState* exec, Structure* structure)
void DatePrototype::finishCreation(ExecState* exec, JSGlobalObject*)
{
- Base::finishCreation(exec->globalData());
+ Base::finishCreation(exec->vm());
ASSERT(inherits(&s_info));
// The constructor will be added later, after DateConstructor has been built.
@@ -545,7 +545,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec)
return throwVMTypeError(exec);
DateInstance* thisDateObj = asDateInstance(thisValue);
- if (!isfinite(thisDateObj->internalNumber()))
+ if (!std::isfinite(thisDateObj->internalNumber()))
return throwVMError(exec, createRangeError(exec, ASCIILiteral("Invalid Date")));
const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
@@ -833,7 +833,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec)
DateInstance* thisDateObj = asDateInstance(thisValue);
double milli = thisDateObj->internalNumber();
- if (isnan(milli))
+ if (std::isnan(milli))
return JSValue::encode(jsNaN());
double secs = floor(milli / msPerSecond);
@@ -849,7 +849,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec)
DateInstance* thisDateObj = asDateInstance(thisValue);
double milli = thisDateObj->internalNumber();
- if (isnan(milli))
+ if (std::isnan(milli))
return JSValue::encode(jsNaN());
double secs = floor(milli / msPerSecond);
@@ -881,7 +881,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec)
double milli = timeClip(exec->argument(0).toNumber(exec));
JSValue result = jsNumber(milli);
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -894,9 +894,9 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
DateInstance* thisDateObj = asDateInstance(thisValue);
double milli = thisDateObj->internalNumber();
- if (!exec->argumentCount() || isnan(milli)) {
+ if (!exec->argumentCount() || std::isnan(milli)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -913,12 +913,12 @@ static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse,
gregorianDateTime.copyFrom(*other);
if (!fillStructuresUsingTimeArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -931,7 +931,7 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
DateInstance* thisDateObj = asDateInstance(thisValue);
if (!exec->argumentCount()) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -939,7 +939,7 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
double ms = 0;
GregorianDateTime gregorianDateTime;
- if (numArgsToUse == 3 && isnan(milli))
+ if (numArgsToUse == 3 && std::isnan(milli))
msToGregorianDateTime(exec, 0, true, gregorianDateTime);
else {
ms = milli - floor(milli / msPerSecond) * msPerSecond;
@@ -953,12 +953,12 @@ static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse,
if (!fillStructuresUsingDateArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -1055,7 +1055,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
DateInstance* thisDateObj = asDateInstance(thisValue);
if (!exec->argumentCount()) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -1063,7 +1063,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
double ms = 0;
GregorianDateTime gregorianDateTime;
- if (isnan(milli))
+ if (std::isnan(milli))
// Based on ECMA 262 B.2.5 (setYear)
// the time must be reset to +0 if it is NaN.
msToGregorianDateTime(exec, 0, true, gregorianDateTime);
@@ -1075,15 +1075,15 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec)
}
double year = exec->argument(0).toIntegerPreserveNaN(exec);
- if (!isfinite(year)) {
+ if (!std::isfinite(year)) {
JSValue result = jsNaN();
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
gregorianDateTime.setYear(toInt32((year >= 0 && year <= 99) ? (year + 1900) : year));
JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, false));
- thisDateObj->setInternalValue(exec->globalData(), result);
+ thisDateObj->setInternalValue(exec->vm(), result);
return JSValue::encode(result);
}
@@ -1110,7 +1110,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec)
if (exec->hadException())
return JSValue::encode(jsNull());
- JSValue toISOValue = object->get(exec, exec->globalData().propertyNames->toISOString);
+ JSValue toISOValue = object->get(exec, exec->vm().propertyNames->toISOString);
if (exec->hadException())
return JSValue::encode(jsNull());
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.h b/Source/JavaScriptCore/runtime/DatePrototype.h
index c4f6d6916..85f7d46d7 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.h
+++ b/Source/JavaScriptCore/runtime/DatePrototype.h
@@ -46,9 +46,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp
index 68ae12d90..9cbe20b97 100644
--- a/Source/JavaScriptCore/runtime/Error.cpp
+++ b/Source/JavaScriptCore/runtime/Error.cpp
@@ -34,6 +34,7 @@
#include "JSObject.h"
#include "JSString.h"
#include "NativeErrorConstructor.h"
+#include "Operations.h"
#include "SourceCode.h"
#include <wtf/text/StringBuilder.h>
@@ -46,37 +47,37 @@ static const char* sourceURLPropertyName = "sourceURL";
JSObject* createError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->errorStructure(), message);
}
JSObject* createEvalError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->evalErrorConstructor()->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->evalErrorConstructor()->errorStructure(), message);
}
JSObject* createRangeError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->rangeErrorConstructor()->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->rangeErrorConstructor()->errorStructure(), message);
}
JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->referenceErrorConstructor()->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->referenceErrorConstructor()->errorStructure(), message);
}
JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->syntaxErrorConstructor()->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->syntaxErrorConstructor()->errorStructure(), message);
}
JSObject* createTypeError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->typeErrorConstructor()->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->typeErrorConstructor()->errorStructure(), message);
}
JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject)
@@ -87,7 +88,7 @@ JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject)
JSObject* createURIError(JSGlobalObject* globalObject, const String& message)
{
ASSERT(!message.isEmpty());
- return ErrorInstance::create(globalObject->globalData(), globalObject->URIErrorConstructor()->errorStructure(), message);
+ return ErrorInstance::create(globalObject->vm(), globalObject->URIErrorConstructor()->errorStructure(), message);
}
JSObject* createError(ExecState* exec, const String& message)
@@ -132,15 +133,15 @@ JSObject* createURIError(ExecState* exec, const String& message)
JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const SourceCode& source)
{
- JSGlobalData* globalData = &callFrame->globalData();
+ VM* vm = &callFrame->vm();
const String& sourceURL = source.provider()->url();
if (line != -1)
- error->putDirect(*globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
+ error->putDirect(*vm, Identifier(vm, linePropertyName), jsNumber(line), ReadOnly | DontDelete);
if (!sourceURL.isNull())
- error->putDirect(*globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete);
+ error->putDirect(*vm, Identifier(vm, sourceURLPropertyName), jsString(vm, sourceURL), ReadOnly | DontDelete);
- globalData->interpreter->addStackTraceIfNecessary(callFrame, error);
+ vm->interpreter->addStackTraceIfNecessary(callFrame, error);
return error;
}
@@ -154,16 +155,15 @@ bool hasErrorInfo(ExecState* exec, JSObject* error)
JSValue throwError(ExecState* exec, JSValue error)
{
- if (error.isObject())
- return throwError(exec, asObject(error));
- exec->globalData().exception = error;
+ Interpreter::addStackTraceIfNecessary(exec, error);
+ exec->vm().exception = error;
return error;
}
JSObject* throwError(ExecState* exec, JSObject* error)
{
Interpreter::addStackTraceIfNecessary(exec, error);
- exec->globalData().exception = error;
+ exec->vm().exception = error;
return error;
}
diff --git a/Source/JavaScriptCore/runtime/Error.h b/Source/JavaScriptCore/runtime/Error.h
index 9c34a0574..36e425d7e 100644
--- a/Source/JavaScriptCore/runtime/Error.h
+++ b/Source/JavaScriptCore/runtime/Error.h
@@ -31,7 +31,7 @@
namespace JSC {
class ExecState;
- class JSGlobalData;
+ class VM;
class JSGlobalObject;
class JSObject;
class SourceCode;
@@ -89,7 +89,7 @@ namespace JSC {
static StrictModeTypeErrorFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const String& message)
{
StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(*exec->heap())) StrictModeTypeErrorFunction(globalObject, structure, message);
- function->finishCreation(exec->globalData(), String());
+ function->finishCreation(exec->vm(), String());
return function;
}
@@ -119,9 +119,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
private:
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
index f2578a497..b143f5a18 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -24,6 +24,7 @@
#include "ErrorPrototype.h"
#include "JSGlobalObject.h"
#include "JSString.h"
+#include "Operations.h"
namespace JSC {
@@ -38,10 +39,10 @@ ErrorConstructor::ErrorConstructor(JSGlobalObject* globalObject, Structure* stru
void ErrorConstructor::finishCreation(ExecState* exec, ErrorPrototype* errorPrototype)
{
- Base::finishCreation(exec->globalData(), errorPrototype->classInfo()->className);
+ Base::finishCreation(exec->vm(), errorPrototype->classInfo()->className);
// ECMA 15.11.3.1 Error.prototype
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
}
// ECMA 15.9.3
diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.h b/Source/JavaScriptCore/runtime/ErrorConstructor.h
index 58399a9bc..b8e3b841b 100644
--- a/Source/JavaScriptCore/runtime/ErrorConstructor.h
+++ b/Source/JavaScriptCore/runtime/ErrorConstructor.h
@@ -41,9 +41,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
index 9c0fe3e8b..e8f7ac162 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -22,6 +22,7 @@
#include "ErrorInstance.h"
#include "JSScope.h"
+#include "Operations.h"
namespace JSC {
@@ -29,8 +30,8 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorInstance);
const ClassInfo ErrorInstance::s_info = { "Error", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorInstance) };
-ErrorInstance::ErrorInstance(JSGlobalData& globalData, Structure* structure)
- : JSNonFinalObject(globalData, structure)
+ErrorInstance::ErrorInstance(VM& vm, Structure* structure)
+ : JSNonFinalObject(vm, structure)
, m_appendSourceToMessage(false)
{
}
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h
index 894676361..26a8b31ea 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.h
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.h
@@ -31,21 +31,21 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), &s_info);
}
- static ErrorInstance* create(JSGlobalData& globalData, Structure* structure, const String& message)
+ static ErrorInstance* create(VM& vm, Structure* structure, const String& message)
{
- ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(globalData.heap)) ErrorInstance(globalData, structure);
- instance->finishCreation(globalData, message);
+ ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
+ instance->finishCreation(vm, message);
return instance;
}
static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message)
{
- return create(exec->globalData(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec));
+ return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec));
}
bool appendSourceToMessage() { return m_appendSourceToMessage; }
@@ -53,14 +53,14 @@ namespace JSC {
void clearAppendSourceToMessage() { m_appendSourceToMessage = false; }
protected:
- explicit ErrorInstance(JSGlobalData&, Structure*);
+ explicit ErrorInstance(VM&, Structure*);
- void finishCreation(JSGlobalData& globalData, const String& message)
+ void finishCreation(VM& vm, const String& message)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
if (!message.isNull())
- putDirect(globalData, globalData.propertyNames->message, jsString(&globalData, message), DontEnum);
+ putDirect(vm, vm.propertyNames->message, jsString(&vm, message), DontEnum);
}
bool m_appendSourceToMessage;
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
index a30efdc31..bab3a7440 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -26,6 +26,7 @@
#include "JSString.h"
#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "StringRecursionChecker.h"
namespace JSC {
@@ -49,15 +50,15 @@ const ClassInfo ErrorPrototype::s_info = { "Error", &ErrorInstance::s_info, 0, E
*/
ErrorPrototype::ErrorPrototype(ExecState* exec, Structure* structure)
- : ErrorInstance(exec->globalData(), structure)
+ : ErrorInstance(exec->vm(), structure)
{
}
void ErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject*)
{
- Base::finishCreation(exec->globalData(), "");
+ Base::finishCreation(exec->vm(), "");
ASSERT(inherits(&s_info));
- putDirect(exec->globalData(), exec->propertyNames().name, jsNontrivialString(exec, String(ASCIILiteral("Error"))), DontEnum);
+ putDirect(exec->vm(), exec->propertyNames().name, jsNontrivialString(exec, String(ASCIILiteral("Error"))), DontEnum);
}
bool ErrorPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.h b/Source/JavaScriptCore/runtime/ErrorPrototype.h
index e961946df..9401b2220 100644
--- a/Source/JavaScriptCore/runtime/ErrorPrototype.h
+++ b/Source/JavaScriptCore/runtime/ErrorPrototype.h
@@ -40,9 +40,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
index a4368a2bb..ccd7a02cb 100644
--- a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -37,36 +37,10 @@
#include "JSNotAnObject.h"
#include "Interpreter.h"
#include "Nodes.h"
+#include "Operations.h"
namespace JSC {
-ASSERT_HAS_TRIVIAL_DESTRUCTOR(InterruptedExecutionError);
-
-const ClassInfo InterruptedExecutionError::s_info = { "InterruptedExecutionError", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InterruptedExecutionError) };
-
-JSValue InterruptedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint)
-{
- if (hint == PreferString)
- return jsNontrivialString(exec, String(ASCIILiteral("JavaScript execution exceeded timeout.")));
- return JSValue(QNaN);
-}
-
-JSObject* createInterruptedExecutionException(JSGlobalData* globalData)
-{
- return InterruptedExecutionError::create(*globalData);
-}
-
-bool isInterruptedExecutionException(JSObject* object)
-{
- return object->inherits(&InterruptedExecutionError::s_info);
-}
-
-bool isInterruptedExecutionException(JSValue value)
-{
- return value.inherits(&InterruptedExecutionError::s_info);
-}
-
-
ASSERT_HAS_TRIVIAL_DESTRUCTOR(TerminatedExecutionError);
const ClassInfo TerminatedExecutionError::s_info = { "TerminatedExecutionError", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(TerminatedExecutionError) };
@@ -78,9 +52,9 @@ JSValue TerminatedExecutionError::defaultValue(const JSObject*, ExecState* exec,
return JSValue(QNaN);
}
-JSObject* createTerminatedExecutionException(JSGlobalData* globalData)
+JSObject* createTerminatedExecutionException(VM* vm)
{
- return TerminatedExecutionError::create(*globalData);
+ return TerminatedExecutionError::create(*vm);
}
bool isTerminatedExecutionException(JSObject* object)
@@ -110,40 +84,59 @@ JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
return createReferenceError(exec, message);
}
-JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value)
+JSString* errorDescriptionForValue(ExecState* exec, JSValue v)
+{
+ VM& vm = exec->vm();
+ if (v.isNull())
+ return vm.smallStrings.nullString();
+ if (v.isUndefined())
+ return vm.smallStrings.undefinedString();
+ if (v.isInt32())
+ return jsString(&vm, vm.numericStrings.add(v.asInt32()));
+ if (v.isDouble())
+ return jsString(&vm, vm.numericStrings.add(v.asDouble()));
+ if (v.isTrue())
+ return vm.smallStrings.trueString();
+ if (v.isFalse())
+ return vm.smallStrings.falseString();
+ if (v.isString())
+ return jsCast<JSString*>(v.asCell());
+ if (v.isObject()) {
+ CallData callData;
+ JSObject* object = asObject(v);
+ if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
+ return vm.smallStrings.functionString();
+ }
+ return jsString(exec, asObject(v)->methodTable()->className(asObject(v)));
+}
+
+JSObject* createError(ExecState* exec, ErrorFactory errorFactory, JSValue value, const String& message)
{
- String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not a valid argument for '", op, "'");
- JSObject* exception = createTypeError(exec, errorMessage);
+ String errorMessage = makeString(errorDescriptionForValue(exec, value)->value(exec), " ", message);
+ JSObject* exception = errorFactory(exec, errorMessage);
ASSERT(exception->isErrorInstance());
static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
return exception;
}
+JSObject* createInvalidParameterError(ExecState* exec, const char* op, JSValue value)
+{
+ return createError(exec, createTypeError, value, makeString("is not a valid argument for '", op, "'"));
+}
+
JSObject* createNotAConstructorError(ExecState* exec, JSValue value)
{
- String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not a constructor");
- JSObject* exception = createTypeError(exec, errorMessage);
- ASSERT(exception->isErrorInstance());
- static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
- return exception;
+ return createError(exec, createTypeError, value, "is not a constructor");
}
JSObject* createNotAFunctionError(ExecState* exec, JSValue value)
{
- String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not a function");
- JSObject* exception = createTypeError(exec, errorMessage);
- ASSERT(exception->isErrorInstance());
- static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
- return exception;
+ return createError(exec, createTypeError, value, "is not a function");
}
JSObject* createNotAnObjectError(ExecState* exec, JSValue value)
{
- String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not an object");
- JSObject* exception = createTypeError(exec, errorMessage);
- ASSERT(exception->isErrorInstance());
- static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage();
- return exception;
+ return createError(exec, createTypeError, value, "is not an object");
}
JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const String& propertyName)
@@ -167,4 +160,10 @@ JSObject* throwStackOverflowError(ExecState* exec)
return throwError(exec, createStackOverflowError(exec));
}
+JSObject* throwTerminatedExecutionException(ExecState* exec)
+{
+ Interpreter::ErrorHandlingMode mode(exec);
+ return throwError(exec, createTerminatedExecutionException(&exec->vm()));
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.h b/Source/JavaScriptCore/runtime/ExceptionHelpers.h
index d2daaa044..bfe1d66af 100644
--- a/Source/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -33,59 +33,32 @@
namespace JSC {
-JS_EXPORT_PRIVATE JSObject* createInterruptedExecutionException(JSGlobalData*);
-bool isInterruptedExecutionException(JSObject*);
-bool isInterruptedExecutionException(JSValue);
+typedef JSObject* (*ErrorFactory)(ExecState*, const String&);
-JSObject* createTerminatedExecutionException(JSGlobalData*);
+JSObject* createTerminatedExecutionException(VM*);
bool isTerminatedExecutionException(JSObject*);
JS_EXPORT_PRIVATE bool isTerminatedExecutionException(JSValue);
-
+JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorFactory, JSValue, const String&);
JS_EXPORT_PRIVATE JSObject* createStackOverflowError(ExecState*);
JSObject* createStackOverflowError(JSGlobalObject*);
JSObject* createOutOfMemoryError(JSGlobalObject*);
JSObject* createUndefinedVariableError(ExecState*, const Identifier&);
JSObject* createNotAnObjectError(ExecState*, JSValue);
-JSObject* createInvalidParamError(ExecState*, const char* op, JSValue);
+JSObject* createInvalidParameterError(ExecState*, const char* op, JSValue);
JSObject* createNotAConstructorError(ExecState*, JSValue);
JSObject* createNotAFunctionError(ExecState*, JSValue);
JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const String&);
+JSString* errorDescriptionForValue(ExecState*, JSValue);
JSObject* throwOutOfMemoryError(ExecState*);
JSObject* throwStackOverflowError(ExecState*);
+JSObject* throwTerminatedExecutionException(ExecState*);
-class InterruptedExecutionError : public JSNonFinalObject {
-private:
- InterruptedExecutionError(JSGlobalData& globalData)
- : JSNonFinalObject(globalData, globalData.interruptedExecutionErrorStructure.get())
- {
- }
-
- static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
-
-public:
- typedef JSNonFinalObject Base;
-
- static InterruptedExecutionError* create(JSGlobalData& globalData)
- {
- InterruptedExecutionError* error = new (NotNull, allocateCell<InterruptedExecutionError>(globalData.heap)) InterruptedExecutionError(globalData);
- error->finishCreation(globalData);
- return error;
- }
-
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
- }
-
- static const ClassInfo s_info;
-};
-
class TerminatedExecutionError : public JSNonFinalObject {
private:
- TerminatedExecutionError(JSGlobalData& globalData)
- : JSNonFinalObject(globalData, globalData.terminatedExecutionErrorStructure.get())
+ TerminatedExecutionError(VM& vm)
+ : JSNonFinalObject(vm, vm.terminatedExecutionErrorStructure.get())
{
}
@@ -94,16 +67,16 @@ private:
public:
typedef JSNonFinalObject Base;
- static TerminatedExecutionError* create(JSGlobalData& globalData)
+ static TerminatedExecutionError* create(VM& vm)
{
- TerminatedExecutionError* error = new (NotNull, allocateCell<TerminatedExecutionError>(globalData.heap)) TerminatedExecutionError(globalData);
- error->finishCreation(globalData);
+ TerminatedExecutionError* error = new (NotNull, allocateCell<TerminatedExecutionError>(vm.heap)) TerminatedExecutionError(vm);
+ error->finishCreation(vm);
return error;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static JS_EXPORTDATA const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index ff4c2ff76..918537650 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -33,6 +33,7 @@
#include "ExecutionHarness.h"
#include "JIT.h"
#include "JITDriver.h"
+#include "Operations.h"
#include "Parser.h"
#include <wtf/Vector.h>
#include <wtf/text/StringBuilder.h>
@@ -67,6 +68,11 @@ Intrinsic ExecutableBase::intrinsic() const
return nativeExecutable->intrinsic();
return NoIntrinsic;
}
+#else
+Intrinsic ExecutableBase::intrinsic() const
+{
+ return NoIntrinsic;
+}
#endif
const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, 0, CREATE_METHOD_TABLE(NativeExecutable) };
@@ -88,14 +94,14 @@ Intrinsic NativeExecutable::intrinsic() const
#if ENABLE(JIT)
// Utility method used for jettisoning code blocks.
template<typename T>
-static void jettisonCodeBlock(JSGlobalData& globalData, OwnPtr<T>& codeBlock)
+static void jettisonCodeBlock(VM& vm, OwnPtr<T>& codeBlock)
{
ASSERT(JITCode::isOptimizingJIT(codeBlock->getJITType()));
ASSERT(codeBlock->alternative());
OwnPtr<T> codeBlockToJettison = codeBlock.release();
codeBlock = static_pointer_cast<T>(codeBlockToJettison->releaseAlternative());
codeBlockToJettison->unlinkIncomingCalls();
- globalData.heap.jettisonDFGCodeBlock(static_pointer_cast<CodeBlock>(codeBlockToJettison.release()));
+ vm.heap.jettisonDFGCodeBlock(static_pointer_cast<CodeBlock>(codeBlockToJettison.release()));
}
#endif
@@ -110,8 +116,9 @@ void ScriptExecutable::destroy(JSCell* cell)
const ClassInfo EvalExecutable::s_info = { "EvalExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(EvalExecutable) };
-EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
- : ScriptExecutable(exec->globalData().evalExecutableStructure.get(), exec, source, inStrictContext)
+EvalExecutable::EvalExecutable(ExecState* exec, PassRefPtr<CodeCache> codeCache, const SourceCode& source, bool inStrictContext)
+ : ScriptExecutable(exec->vm().evalExecutableStructure.get(), exec, source, inStrictContext)
+ , m_codeCache(codeCache)
{
}
@@ -123,7 +130,7 @@ void EvalExecutable::destroy(JSCell* cell)
const ClassInfo ProgramExecutable::s_info = { "ProgramExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(ProgramExecutable) };
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec->globalData().programExecutableStructure.get(), exec, source, false)
+ : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec, source, false)
{
}
@@ -134,14 +141,15 @@ void ProgramExecutable::destroy(JSCell* cell)
const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) };
-FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine)
- : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, unlinkedExecutable->isInStrictContext())
- , m_unlinkedExecutable(globalData, this, unlinkedExecutable)
+FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn)
+ : ScriptExecutable(vm.functionExecutableStructure.get(), vm, source, unlinkedExecutable->isInStrictContext())
+ , m_unlinkedExecutable(vm, this, unlinkedExecutable)
{
- ASSERT(!source.isNull());
+ RELEASE_ASSERT(!source.isNull());
ASSERT(source.length());
m_firstLine = firstLine;
m_lastLine = lastLine;
+ m_startColumn = startColumn;
}
void FunctionExecutable::destroy(JSCell* cell)
@@ -151,7 +159,7 @@ void FunctionExecutable::destroy(JSCell* cell)
JSObject* EvalExecutable::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ ASSERT(exec->vm().dynamicGlobalObject);
ASSERT(!!m_evalCodeBlock);
JSObject* error = 0;
if (m_evalCodeBlock->getJITType() != JITCode::topTierJIT())
@@ -177,7 +185,7 @@ inline const char* samplingDescription(JITCode::JITType jitType)
case JITCode::DFGJIT:
return "DFG Compilation (TOTAL)";
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
}
@@ -190,7 +198,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCo
UNUSED_PARAM(jitType);
UNUSED_PARAM(bytecodeIndex);
#endif
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
if (!!m_evalCodeBlock) {
@@ -199,19 +207,19 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCo
m_evalCodeBlock = newCodeBlock.release();
} else {
UNUSED_PARAM(scope);
- UNUSED_PARAM(globalData);
+ UNUSED_PARAM(vm);
UNUSED_PARAM(lexicalGlobalObject);
if (!lexicalGlobalObject->evalEnabled())
return throwError(exec, createEvalError(exec, lexicalGlobalObject->evalDisabledErrorMessage()));
JSObject* exception = 0;
- UnlinkedEvalCodeBlock* unlinkedEvalCode = lexicalGlobalObject->createEvalCodeBlock(exec, this, &exception);
+ UnlinkedEvalCodeBlock* unlinkedEvalCode = lexicalGlobalObject->createEvalCodeBlock(m_codeCache.get(), exec, scope, this, &exception);
if (!unlinkedEvalCode)
return exception;
OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
- m_unlinkedEvalCodeBlock.set(*globalData, this, unlinkedEvalCode);
+ m_unlinkedEvalCodeBlock.set(*vm, this, unlinkedEvalCode);
m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, unlinkedEvalCode, lexicalGlobalObject, source().provider(), scope->localDepth(), previousCodeBlock.release()));
m_evalCodeBlock->copyPostParseDataFromAlternative();
}
@@ -231,9 +239,9 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCo
}
#if ENABLE(JIT)
-void EvalExecutable::jettisonOptimizedCode(JSGlobalData& globalData)
+void EvalExecutable::jettisonOptimizedCode(VM& vm)
{
- jettisonCodeBlock(globalData, m_evalCodeBlock);
+ jettisonCodeBlock(vm, m_evalCodeBlock);
m_jitCodeForCall = m_evalCodeBlock->getJITCode();
ASSERT(!m_jitCodeForCallWithArityCheck);
}
@@ -256,7 +264,7 @@ void EvalExecutable::unlinkCalls()
#if ENABLE(JIT)
if (!m_jitCodeForCall)
return;
- ASSERT(m_evalCodeBlock);
+ RELEASE_ASSERT(m_evalCodeBlock);
m_evalCodeBlock->unlinkCalls();
#endif
}
@@ -271,9 +279,9 @@ void EvalExecutable::clearCode()
JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
{
ParserError error;
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, error);
+ RefPtr<ProgramNode> programNode = parse<ProgramNode>(vm, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, error);
if (programNode)
return 0;
ASSERT(error.m_type != ParserError::ErrorNone);
@@ -282,7 +290,7 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
JSObject* ProgramExecutable::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
ASSERT(!!m_programCodeBlock);
JSObject* error = 0;
if (m_programCodeBlock->getJITType() != JITCode::topTierJIT())
@@ -313,7 +321,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JI
m_programCodeBlock = newCodeBlock.release();
} else {
JSGlobalObject* globalObject = scope->globalObject();
- m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), globalObject, source().provider(), m_programCodeBlock.release()));
+ m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, m_unlinkedProgramCodeBlock.get(), globalObject, source().provider(), source().startColumn(), m_programCodeBlock.release()));
m_programCodeBlock->copyPostParseDataFromAlternative();
}
@@ -332,9 +340,9 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JI
}
#if ENABLE(JIT)
-void ProgramExecutable::jettisonOptimizedCode(JSGlobalData& globalData)
+void ProgramExecutable::jettisonOptimizedCode(VM& vm)
{
- jettisonCodeBlock(globalData, m_programCodeBlock);
+ jettisonCodeBlock(vm, m_programCodeBlock);
m_jitCodeForCall = m_programCodeBlock->getJITCode();
ASSERT(!m_jitCodeForCallWithArityCheck);
}
@@ -345,7 +353,7 @@ void ProgramExecutable::unlinkCalls()
#if ENABLE(JIT)
if (!m_jitCodeForCall)
return;
- ASSERT(m_programCodeBlock);
+ RELEASE_ASSERT(m_programCodeBlock);
m_programCodeBlock->unlinkCalls();
#endif
}
@@ -367,21 +375,21 @@ int ProgramExecutable::addGlobalVar(JSGlobalObject* globalObject, const Identifi
return index;
}
-JSObject* ProgramExecutable::initalizeGlobalProperties(JSGlobalData& globalData, CallFrame* callFrame, JSScope* scope)
+JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope)
{
- ASSERT(scope);
+ RELEASE_ASSERT(scope);
JSGlobalObject* globalObject = scope->globalObject();
- ASSERT(globalObject);
- ASSERT(&globalObject->globalData() == &globalData);
+ RELEASE_ASSERT(globalObject);
+ ASSERT(&globalObject->vm() == &vm);
JSObject* exception = 0;
UnlinkedProgramCodeBlock* unlinkedCode = globalObject->createProgramCodeBlock(callFrame, this, &exception);
if (exception)
return exception;
- m_unlinkedProgramCodeBlock.set(globalData, this, unlinkedCode);
+ m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCode);
- BatchedTransitionOptimizer optimizer(globalData, globalObject);
+ BatchedTransitionOptimizer optimizer(vm, globalObject);
const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCode->variableDeclarations();
const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCode->functionDeclarations();
@@ -393,12 +401,12 @@ JSObject* ProgramExecutable::initalizeGlobalProperties(JSGlobalData& globalData,
CallFrame* globalExec = globalObject->globalExec();
for (size_t i = 0; i < functionDeclarations.size(); ++i) {
- bool propertyDidExist = globalObject->removeDirect(globalData, functionDeclarations[i].first); // Newly declared functions overwrite existing properties.
+ bool propertyDidExist = globalObject->removeDirect(vm, functionDeclarations[i].first); // Newly declared functions overwrite existing properties.
UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get();
- JSValue value = JSFunction::create(globalExec, unlinkedFunctionExecutable->link(globalData, m_source, lineNo(), 0), scope);
+ JSValue value = JSFunction::create(globalExec, unlinkedFunctionExecutable->link(vm, m_source, lineNo(), 0), scope);
int index = addGlobalVar(globalObject, functionDeclarations[i].first, IsVariable,
!propertyDidExist ? IsFunctionToSpecialize : NotFunctionOrNotSpecializable);
- globalObject->registerAt(index).set(globalData, globalObject, value);
+ globalObject->registerAt(index).set(vm, globalObject, value);
}
for (size_t i = 0; i < variableDeclarations.size(); ++i) {
@@ -436,21 +444,21 @@ FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKi
if (kind == CodeForCall)
result = m_codeBlockForCall.get();
else {
- ASSERT(kind == CodeForConstruct);
+ RELEASE_ASSERT(kind == CodeForConstruct);
result = m_codeBlockForConstruct.get();
}
if (!result)
return 0;
while (result->alternative())
result = static_cast<FunctionCodeBlock*>(result->alternative());
- ASSERT(result);
+ RELEASE_ASSERT(result);
ASSERT(JITCode::isBaselineCode(result->getJITType()));
return result;
}
JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
ASSERT(!!m_codeBlockForCall);
JSObject* error = 0;
if (m_codeBlockForCall->getJITType() != JITCode::topTierJIT())
@@ -461,7 +469,7 @@ JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, JSScope*
JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
ASSERT(!!m_codeBlockForConstruct);
JSObject* error = 0;
if (m_codeBlockForConstruct->getJITType() != JITCode::topTierJIT())
@@ -482,30 +490,29 @@ bool FunctionExecutable::jitCompileForConstruct(ExecState* exec)
}
#endif
-FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
-{
- return baselineCodeBlockFor(kind);
-}
-
PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception)
{
if (!!codeBlockFor(specializationKind))
return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
- JSGlobalData* globalData = scope->globalData();
+ VM* vm = scope->vm();
JSGlobalObject* globalObject = scope->globalObject();
ParserError error;
DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
- UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*globalData, m_source, specializationKind, debuggerMode, profilerMode, error);
- recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine());
+ UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*vm, scope, m_source, specializationKind, debuggerMode, profilerMode, error);
+ recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());
if (!unlinkedCodeBlock) {
exception = error.toErrorObject(globalObject, m_source);
return nullptr;
}
- OwnPtr<FunctionCodeBlock> result = adoptPtr(new FunctionCodeBlock(this, unlinkedCodeBlock, globalObject, source().provider(), source().startOffset()));
+ SourceProvider* provider = source().provider();
+ unsigned sourceOffset = source().startOffset();
+ unsigned startColumn = source().startColumn();
+
+ OwnPtr<FunctionCodeBlock> result = adoptPtr(new FunctionCodeBlock(this, unlinkedCodeBlock, globalObject, provider, sourceOffset, startColumn));
result->copyPostParseDataFrom(codeBlockFor(specializationKind).get());
return result.release();
}
@@ -531,7 +538,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* s
m_codeBlockForCall = newCodeBlock.release();
m_numParametersForCall = m_codeBlockForCall->numParameters();
- ASSERT(m_numParametersForCall);
+ RELEASE_ASSERT(m_numParametersForCall);
#if ENABLE(JIT)
if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, jitType, bytecodeIndex, CodeForCall))
@@ -567,7 +574,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSSco
m_codeBlockForConstruct = newCodeBlock.release();
m_numParametersForConstruct = m_codeBlockForConstruct->numParameters();
- ASSERT(m_numParametersForConstruct);
+ RELEASE_ASSERT(m_numParametersForConstruct);
#if ENABLE(JIT)
if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, jitType, bytecodeIndex, CodeForConstruct))
@@ -584,16 +591,16 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSSco
}
#if ENABLE(JIT)
-void FunctionExecutable::jettisonOptimizedCodeForCall(JSGlobalData& globalData)
+void FunctionExecutable::jettisonOptimizedCodeForCall(VM& vm)
{
- jettisonCodeBlock(globalData, m_codeBlockForCall);
+ jettisonCodeBlock(vm, m_codeBlockForCall);
m_jitCodeForCall = m_codeBlockForCall->getJITCode();
m_jitCodeForCallWithArityCheck = m_codeBlockForCall->getJITCodeWithArityCheck();
}
-void FunctionExecutable::jettisonOptimizedCodeForConstruct(JSGlobalData& globalData)
+void FunctionExecutable::jettisonOptimizedCodeForConstruct(VM& vm)
{
- jettisonCodeBlock(globalData, m_codeBlockForConstruct);
+ jettisonCodeBlock(vm, m_codeBlockForConstruct);
m_jitCodeForConstruct = m_codeBlockForConstruct->getJITCode();
m_jitCodeForConstructWithArityCheck = m_codeBlockForConstruct->getJITCodeWithArityCheck();
}
@@ -638,11 +645,11 @@ void FunctionExecutable::unlinkCalls()
{
#if ENABLE(JIT)
if (!!m_jitCodeForCall) {
- ASSERT(m_codeBlockForCall);
+ RELEASE_ASSERT(m_codeBlockForCall);
m_codeBlockForCall->unlinkCalls();
}
if (!!m_jitCodeForConstruct) {
- ASSERT(m_codeBlockForConstruct);
+ RELEASE_ASSERT(m_codeBlockForConstruct);
m_codeBlockForConstruct->unlinkCalls();
}
#endif
@@ -655,9 +662,10 @@ FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, E
return 0;
unsigned firstLine = source.firstLine() + unlinkedFunction->firstLineOffset();
unsigned startOffset = source.startOffset() + unlinkedFunction->startOffset();
+ unsigned startColumn = source.startColumn();
unsigned sourceLength = unlinkedFunction->sourceLength();
- SourceCode functionSource(source.provider(), startOffset, startOffset + sourceLength, firstLine);
- return FunctionExecutable::create(exec->globalData(), functionSource, unlinkedFunction, firstLine, unlinkedFunction->lineCount());
+ SourceCode functionSource(source.provider(), startOffset, startOffset + sourceLength, firstLine, startColumn);
+ return FunctionExecutable::create(exec->vm(), functionSource, unlinkedFunction, firstLine, unlinkedFunction->lineCount(), startColumn);
}
String FunctionExecutable::paramString() const
@@ -678,7 +686,7 @@ CodeBlockHash NativeExecutable::hashFor(CodeSpecializationKind kind) const
if (kind == CodeForCall)
return CodeBlockHash(static_cast<unsigned>(bitwise_cast<size_t>(m_function)));
- ASSERT(kind == CodeForConstruct);
+ RELEASE_ASSERT(kind == CodeForConstruct);
return CodeBlockHash(static_cast<unsigned>(bitwise_cast<size_t>(m_constructor)));
}
diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h
index 83eb602c4..28e823ca4 100644
--- a/Source/JavaScriptCore/runtime/Executable.h
+++ b/Source/JavaScriptCore/runtime/Executable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,10 +32,11 @@
#include "HandlerInfo.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "JITCode.h"
#include "JSGlobalObject.h"
#include "LLIntCLoop.h"
-#include "Nodes.h"
#include "SamplingTool.h"
+#include "SourceCode.h"
#include "UnlinkedCodeBlock.h"
#include <wtf/PassOwnPtr.h>
@@ -67,16 +68,16 @@ namespace JSC {
static const int NUM_PARAMETERS_IS_HOST = 0;
static const int NUM_PARAMETERS_NOT_COMPILED = -1;
- ExecutableBase(JSGlobalData& globalData, Structure* structure, int numParameters)
- : JSCell(globalData, structure)
+ ExecutableBase(VM& vm, Structure* structure, int numParameters)
+ : JSCell(vm, structure)
, m_numParametersForCall(numParameters)
, m_numParametersForConstruct(numParameters)
{
}
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
}
public:
@@ -101,7 +102,7 @@ namespace JSC {
return m_numParametersForCall == NUM_PARAMETERS_IS_HOST;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); }
void clearCode();
@@ -176,16 +177,6 @@ namespace JSC {
return hasJITCodeForConstruct();
}
- // Intrinsics are only for calls, currently.
- Intrinsic intrinsic() const;
-
- Intrinsic intrinsicFor(CodeSpecializationKind kind) const
- {
- if (isCall(kind))
- return intrinsic();
- return NoIntrinsic;
- }
-
static ptrdiff_t offsetOfJITCodeFor(CodeSpecializationKind kind)
{
if (kind == CodeForCall)
@@ -211,6 +202,16 @@ namespace JSC {
}
#endif // ENABLE(JIT)
+ // Intrinsics are only for calls, currently.
+ Intrinsic intrinsic() const;
+
+ Intrinsic intrinsicFor(CodeSpecializationKind kind) const
+ {
+ if (isCall(kind))
+ return intrinsic();
+ return NoIntrinsic;
+ }
+
#if ENABLE(JIT) || ENABLE(LLINT_C_LOOP)
MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind kind)
{
@@ -270,26 +271,26 @@ namespace JSC {
typedef ExecutableBase Base;
#if ENABLE(JIT)
- static NativeExecutable* create(JSGlobalData& globalData, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
+ static NativeExecutable* create(VM& vm, MacroAssemblerCodeRef callThunk, NativeFunction function, MacroAssemblerCodeRef constructThunk, NativeFunction constructor, Intrinsic intrinsic)
{
NativeExecutable* executable;
if (!callThunk) {
- executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
- executable->finishCreation(globalData, JITCode(), JITCode(), intrinsic);
+ executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
+ executable->finishCreation(vm, JITCode(), JITCode(), intrinsic);
} else {
- executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
- executable->finishCreation(globalData, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
+ executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
+ executable->finishCreation(vm, JITCode::HostFunction(callThunk), JITCode::HostFunction(constructThunk), intrinsic);
}
return executable;
}
#endif
#if ENABLE(LLINT_C_LOOP)
- static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
+ static NativeExecutable* create(VM& vm, NativeFunction function, NativeFunction constructor)
{
- ASSERT(!globalData.canUseJIT());
- NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(globalData.heap)) NativeExecutable(globalData, function, constructor);
- executable->finishCreation(globalData);
+ ASSERT(!vm.canUseJIT());
+ NativeExecutable* executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor);
+ executable->finishCreation(vm);
return executable;
}
#endif
@@ -302,8 +303,24 @@ namespace JSC {
NativeFunction function() { return m_function; }
NativeFunction constructor() { return m_constructor; }
+
+ NativeFunction nativeFunctionFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return function();
+ ASSERT(kind == CodeForConstruct);
+ return constructor();
+ }
+
+ static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind)
+ {
+ if (kind == CodeForCall)
+ return OBJECT_OFFSETOF(NativeExecutable, m_function);
+ ASSERT(kind == CodeForConstruct);
+ return OBJECT_OFFSETOF(NativeExecutable, m_constructor);
+ }
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
static const ClassInfo s_info;
@@ -311,9 +328,9 @@ namespace JSC {
protected:
#if ENABLE(JIT)
- void finishCreation(JSGlobalData& globalData, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
+ void finishCreation(VM& vm, JITCode callThunk, JITCode constructThunk, Intrinsic intrinsic)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
m_jitCodeForCall = callThunk;
m_jitCodeForConstruct = constructThunk;
m_jitCodeForCallWithArityCheck = callThunk.addressForCall();
@@ -323,8 +340,8 @@ namespace JSC {
#endif
private:
- NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
- : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
+ NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor)
+ : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
, m_function(function)
, m_constructor(constructor)
{
@@ -340,17 +357,19 @@ namespace JSC {
public:
typedef ExecutableBase Base;
- ScriptExecutable(Structure* structure, JSGlobalData& globalData, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(globalData, structure, NUM_PARAMETERS_NOT_COMPILED)
+ ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext)
+ : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
+ , m_neverInline(false)
{
}
ScriptExecutable(Structure* structure, ExecState* exec, const SourceCode& source, bool isInStrictContext)
- : ExecutableBase(exec->globalData(), structure, NUM_PARAMETERS_NOT_COMPILED)
+ : ExecutableBase(exec->vm(), structure, NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
, m_features(isInStrictContext ? StrictModeFeature : 0)
+ , m_neverInline(false)
{
}
@@ -365,11 +384,16 @@ namespace JSC {
const String& sourceURL() const { return m_source.provider()->url(); }
int lineNo() const { return m_firstLine; }
int lastLine() const { return m_lastLine; }
+ unsigned startColumn() const { return m_startColumn; }
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; }
+
+ void setNeverInline(bool value) { m_neverInline = value; }
+ bool neverInline() const { return m_neverInline; }
+ bool isInliningCandidate() const { return !neverInline(); }
void unlinkCalls();
@@ -377,31 +401,34 @@ namespace JSC {
static const ClassInfo s_info;
- void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
+ void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine, unsigned startColumn)
{
m_features = features;
m_hasCapturedVariables = hasCapturedVariables;
m_firstLine = firstLine;
m_lastLine = lastLine;
+ m_startColumn = startColumn;
}
protected:
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
- globalData.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
+ Base::finishCreation(vm);
+ vm.heap.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
#if ENABLE(CODEBLOCK_SAMPLING)
- if (SamplingTool* sampler = globalData.interpreter->sampler())
- sampler->notifyOfScope(globalData, this);
+ if (SamplingTool* sampler = vm.interpreter->sampler())
+ sampler->notifyOfScope(vm, this);
#endif
}
SourceCode m_source;
CodeFeatures m_features;
bool m_hasCapturedVariables;
+ bool m_neverInline;
int m_firstLine;
int m_lastLine;
+ unsigned m_startColumn;
};
class EvalExecutable : public ScriptExecutable {
@@ -413,7 +440,7 @@ namespace JSC {
JSObject* compile(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_evalCodeBlock)
error = compileInternal(exec, scope, JITCode::bottomTierJIT());
@@ -424,7 +451,7 @@ namespace JSC {
JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCode(JSGlobalData&);
+ void jettisonOptimizedCode(VM&);
bool jitCompile(ExecState*);
#endif
@@ -434,10 +461,10 @@ namespace JSC {
return *m_evalCodeBlock;
}
- static EvalExecutable* create(ExecState* exec, const SourceCode& source, bool isInStrictContext)
+ static EvalExecutable* create(ExecState* exec, PassRefPtr<CodeCache> cache, const SourceCode& source, bool isInStrictContext)
{
- EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, source, isInStrictContext);
- executable->finishCreation(exec->globalData());
+ EvalExecutable* executable = new (NotNull, allocateCell<EvalExecutable>(*exec->heap())) EvalExecutable(exec, cache, source, isInStrictContext);
+ executable->finishCreation(exec->vm());
return executable;
}
@@ -447,9 +474,9 @@ namespace JSC {
return generatedJITCodeForCall();
}
#endif
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(EvalExecutableType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
@@ -462,13 +489,14 @@ namespace JSC {
private:
static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
- EvalExecutable(ExecState*, const SourceCode&, bool);
+ EvalExecutable(ExecState*, PassRefPtr<CodeCache>, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
static void visitChildren(JSCell*, SlotVisitor&);
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
+ RefPtr<CodeCache> m_codeCache;
};
class ProgramExecutable : public ScriptExecutable {
@@ -479,18 +507,18 @@ namespace JSC {
static ProgramExecutable* create(ExecState* exec, const SourceCode& source)
{
ProgramExecutable* executable = new (NotNull, allocateCell<ProgramExecutable>(*exec->heap())) ProgramExecutable(exec, source);
- executable->finishCreation(exec->globalData());
+ executable->finishCreation(exec->vm());
return executable;
}
- JSObject* initalizeGlobalProperties(JSGlobalData&, CallFrame*, JSScope*);
+ JSObject* initializeGlobalProperties(VM&, CallFrame*, JSScope*);
static void destroy(JSCell*);
JSObject* compile(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_programCodeBlock)
error = compileInternal(exec, scope, JITCode::bottomTierJIT());
@@ -501,7 +529,7 @@ namespace JSC {
JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCode(JSGlobalData&);
+ void jettisonOptimizedCode(VM&);
bool jitCompile(ExecState*);
#endif
@@ -520,9 +548,9 @@ namespace JSC {
}
#endif
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ProgramExecutableType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
@@ -555,15 +583,20 @@ namespace JSC {
public:
typedef ScriptExecutable Base;
- static FunctionExecutable* create(JSGlobalData& globalData, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine)
+ static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, unsigned firstLine, unsigned lastLine, unsigned startColumn)
{
- FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, source, unlinkedExecutable, firstLine, lastLine);
- executable->finishCreation(globalData);
+ FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, firstLine, lastLine, startColumn);
+ executable->finishCreation(vm);
return executable;
}
static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
static void destroy(JSCell*);
+
+ UnlinkedFunctionExecutable* unlinkedExecutable()
+ {
+ return m_unlinkedExecutable.get();
+ }
// Returns either call or construct bytecode. This can be appropriate
// for answering questions that that don't vary between call and construct --
@@ -576,13 +609,11 @@ namespace JSC {
return *m_codeBlockForConstruct;
}
- FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind);
-
PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CodeSpecializationKind, JSObject*& exception);
JSObject* compileForCall(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForCall)
error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT());
@@ -593,7 +624,7 @@ namespace JSC {
JSObject* compileOptimizedForCall(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCodeForCall(JSGlobalData&);
+ void jettisonOptimizedCodeForCall(VM&);
bool jitCompileForCall(ExecState*);
#endif
@@ -610,7 +641,7 @@ namespace JSC {
JSObject* compileForConstruct(ExecState* exec, JSScope* scope)
{
- ASSERT(exec->globalData().dynamicGlobalObject);
+ RELEASE_ASSERT(exec->vm().dynamicGlobalObject);
JSObject* error = 0;
if (!m_codeBlockForConstruct)
error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT());
@@ -621,7 +652,7 @@ namespace JSC {
JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, unsigned bytecodeIndex);
#if ENABLE(JIT)
- void jettisonOptimizedCodeForConstruct(JSGlobalData&);
+ void jettisonOptimizedCodeForConstruct(VM&);
bool jitCompileForConstruct(ExecState*);
#endif
@@ -661,13 +692,13 @@ namespace JSC {
}
#if ENABLE(JIT)
- void jettisonOptimizedCodeFor(JSGlobalData& globalData, CodeSpecializationKind kind)
+ void jettisonOptimizedCodeFor(VM& vm, CodeSpecializationKind kind)
{
if (kind == CodeForCall)
- jettisonOptimizedCodeForCall(globalData);
+ jettisonOptimizedCodeForCall(vm);
else {
ASSERT(kind == CodeForConstruct);
- jettisonOptimizedCodeForConstruct(globalData);
+ jettisonOptimizedCodeForConstruct(vm);
}
}
@@ -713,9 +744,9 @@ namespace JSC {
void clearCodeIfNotCompiling();
void clearUnlinkedCodeForRecompilationIfNotCompiling();
static void visitChildren(JSCell*, SlotVisitor&);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
@@ -725,7 +756,7 @@ namespace JSC {
void clearCode();
private:
- FunctionExecutable(JSGlobalData&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine);
+ FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine, unsigned lastLine, unsigned startColumn);
JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX);
@@ -755,38 +786,6 @@ namespace JSC {
OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
};
- inline JSFunction::JSFunction(JSGlobalData& globalData, FunctionExecutable* executable, JSScope* scope)
- : Base(globalData, scope->globalObject()->functionStructure())
- , m_executable(globalData, this, executable)
- , m_scope(globalData, this, scope)
- , m_inheritorIDWatchpoint(InitializedBlind) // See comment in JSFunction.cpp concerning the reason for using InitializedBlind as opposed to InitializedWatching.
- {
- }
-
- inline FunctionExecutable* JSFunction::jsExecutable() const
- {
- ASSERT(!isHostFunctionNonInline());
- return static_cast<FunctionExecutable*>(m_executable.get());
- }
-
- inline bool JSFunction::isHostFunction() const
- {
- ASSERT(m_executable);
- return m_executable->isHostFunction();
- }
-
- inline NativeFunction JSFunction::nativeFunction()
- {
- ASSERT(isHostFunction());
- return static_cast<NativeExecutable*>(m_executable.get())->function();
- }
-
- inline NativeFunction JSFunction::nativeConstructor()
- {
- ASSERT(isHostFunction());
- return static_cast<NativeExecutable*>(m_executable.get())->constructor();
- }
-
inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
{
JSFunction* function = jsCast<JSFunction*>(getJSFunction(value));
@@ -819,10 +818,12 @@ namespace JSC {
case FunctionExecutableType:
return jsCast<FunctionExecutable*>(this)->unlinkCalls();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
}
+#include "JSFunctionInlines.h"
+
#endif
diff --git a/Source/JavaScriptCore/runtime/ExecutionHarness.h b/Source/JavaScriptCore/runtime/ExecutionHarness.h
index b71b60217..ba52a1e51 100644
--- a/Source/JavaScriptCore/runtime/ExecutionHarness.h
+++ b/Source/JavaScriptCore/runtime/ExecutionHarness.h
@@ -41,8 +41,10 @@ inline bool prepareForExecution(ExecState* exec, OwnPtr<CodeBlockType>& codeBloc
#if ENABLE(LLINT)
if (JITCode::isBaselineCode(jitType)) {
// Start off in the low level interpreter.
- LLInt::getEntrypoint(exec->globalData(), codeBlock.get(), jitCode);
+ LLInt::getEntrypoint(exec->vm(), codeBlock.get(), jitCode);
codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
+ if (exec->vm().m_perBytecodeProfiler)
+ exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock.get());
return true;
}
#endif // ENABLE(LLINT)
@@ -54,8 +56,10 @@ inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBloc
#if ENABLE(LLINT)
if (JITCode::isBaselineCode(jitType)) {
// Start off in the low level interpreter.
- LLInt::getFunctionEntrypoint(exec->globalData(), kind, jitCode, jitCodeWithArityCheck);
+ LLInt::getFunctionEntrypoint(exec->vm(), kind, jitCode, jitCodeWithArityCheck);
codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
+ if (exec->vm().m_perBytecodeProfiler)
+ exec->vm().m_perBytecodeProfiler->ensureBytecodesFor(codeBlock.get());
return true;
}
#else
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index bf74c0a97..3c4379b39 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -29,6 +29,7 @@
#include "JSString.h"
#include "Lexer.h"
#include "Nodes.h"
+#include "Operations.h"
#include "Parser.h"
#include <wtf/text/StringBuilder.h>
@@ -45,11 +46,11 @@ FunctionConstructor::FunctionConstructor(JSGlobalObject* globalObject, Structure
void FunctionConstructor::finishCreation(ExecState* exec, FunctionPrototype* functionPrototype)
{
- Base::finishCreation(exec->globalData(), functionPrototype->classInfo()->className);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
+ Base::finishCreation(exec->vm(), functionPrototype->classInfo()->className);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
// Number of arguments for constructor
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
}
static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState* exec)
@@ -123,7 +124,7 @@ JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState* exec, JSGlobalObj
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
{
- return constructFunction(exec, globalObject, args, Identifier(exec, "anonymous"), String(), TextPosition::minimumPosition());
+ return constructFunction(exec, globalObject, args, exec->propertyNames().anonymous, String(), TextPosition::minimumPosition());
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.h b/Source/JavaScriptCore/runtime/FunctionConstructor.h
index 99eafee80..3d211f633 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.h
@@ -44,9 +44,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
private:
diff --git a/Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp b/Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp
new file mode 100644
index 000000000..1577ed57a
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FunctionExecutableDump.h"
+
+namespace JSC {
+
+void FunctionExecutableDump::dump(PrintStream& out) const
+{
+ out.print(m_executable->inferredName().string(), "#", m_executable->hashFor(CodeForCall), "/", m_executable->hashFor(CodeForConstruct), ":[", RawPointer(m_executable), "]");
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/FunctionExecutableDump.h b/Source/JavaScriptCore/runtime/FunctionExecutableDump.h
new file mode 100644
index 000000000..732ec458f
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/FunctionExecutableDump.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FunctionExecutableDump_h
+#define FunctionExecutableDump_h
+
+#include "Executable.h"
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+class FunctionExecutableDump {
+public:
+ explicit FunctionExecutableDump(FunctionExecutable* executable)
+ : m_executable(executable)
+ {
+ }
+
+ void dump(PrintStream&) const;
+private:
+ FunctionExecutable* m_executable;
+};
+
+} // namespace JSC
+
+#endif // FunctionExecutableDump_h
+
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
index 8e4390b1b..183298267 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -29,6 +29,7 @@
#include "JSStringBuilder.h"
#include "Interpreter.h"
#include "Lexer.h"
+#include "Operations.h"
namespace JSC {
@@ -48,23 +49,23 @@ FunctionPrototype::FunctionPrototype(JSGlobalObject* globalObject, Structure* st
void FunctionPrototype::finishCreation(ExecState* exec, const String& name)
{
- Base::finishCreation(exec->globalData(), name);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+ Base::finishCreation(exec->vm(), name);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
}
void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, JSFunction** callFunction, JSFunction** applyFunction)
{
JSFunction* toStringFunction = JSFunction::create(exec, globalObject, 0, exec->propertyNames().toString.string(), functionProtoFuncToString);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().toString, toStringFunction, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().toString, toStringFunction, DontEnum);
*applyFunction = JSFunction::create(exec, globalObject, 2, exec->propertyNames().apply.string(), functionProtoFuncApply);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().apply, *applyFunction, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().apply, *applyFunction, DontEnum);
*callFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().call.string(), functionProtoFuncCall);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().call, *callFunction, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().call, *callFunction, DontEnum);
JSFunction* bindFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().bind.string(), functionProtoFuncBind);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().bind, bindFunction, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().bind, bindFunction, DontEnum);
}
static EncodedJSValue JSC_HOST_CALL callFunctionPrototype(ExecState*)
@@ -186,12 +187,12 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
// Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order.
size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0;
- JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), numBoundArgs);
+ JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->vm(), globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), numBoundArgs);
if (!boundArgs)
return JSValue::encode(throwOutOfMemoryError(exec));
for (size_t i = 0; i < numBoundArgs; ++i)
- boundArgs->initializeIndex(exec->globalData(), i, exec->argument(i + 1));
+ boundArgs->initializeIndex(exec->vm(), i, exec->argument(i + 1));
// If the [[Class]] internal property of Target is "Function", then ...
// Else set the length own property of F to 0.
diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.h b/Source/JavaScriptCore/runtime/FunctionPrototype.h
index 07f381306..0083fb9d2 100644
--- a/Source/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/Source/JavaScriptCore/runtime/FunctionPrototype.h
@@ -38,9 +38,9 @@ namespace JSC {
void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallback.cpp b/Source/JavaScriptCore/runtime/GCActivityCallback.cpp
index 0c07b5e02..4898122b5 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallback.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallback.cpp
@@ -31,16 +31,20 @@
#include "APIShims.h"
#include "Heap.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSLock.h"
#include "JSObject.h"
#include <wtf/RetainPtr.h>
#include <wtf/WTFThreadData.h>
+#if PLATFORM(EFL)
+#include <wtf/MainThread.h>
+#endif
+
namespace JSC {
-#if USE(CF) || PLATFORM(QT)
+#if USE(CF) || PLATFORM(QT) || PLATFORM(EFL)
const double gcTimeSlicePerMB = 0.01; // Percentage of CPU time we will spend to reclaim 1 MB
const double maxGCTimeSlice = 0.05; // The maximum amount of CPU time we want to use for opportunistic timer-triggered collections.
@@ -50,19 +54,25 @@ const double hour = 60 * 60;
#if USE(CF)
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
- : GCActivityCallback(heap->globalData(), CFRunLoopGetCurrent())
+ : GCActivityCallback(heap->vm(), CFRunLoopGetCurrent())
, m_delay(s_decade)
{
}
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap, CFRunLoopRef runLoop)
- : GCActivityCallback(heap->globalData(), runLoop)
+ : GCActivityCallback(heap->vm(), runLoop)
, m_delay(s_decade)
{
}
#elif PLATFORM(QT)
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
- : GCActivityCallback(heap->globalData())
+ : GCActivityCallback(heap->vm())
+ , m_delay(hour)
+{
+}
+#elif PLATFORM(EFL)
+DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
+ : GCActivityCallback(heap->vm(), WTF::isMainThread())
, m_delay(hour)
{
}
@@ -70,11 +80,11 @@ DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
void DefaultGCActivityCallback::doWork()
{
- Heap* heap = &m_globalData->heap;
+ Heap* heap = &m_vm->heap;
if (!isEnabled())
return;
- APIEntryShim shim(m_globalData);
+ APIEntryShim shim(m_vm);
#if !PLATFORM(IOS)
double startTime = WTF::monotonicallyIncreasingTime();
if (heap->isPagedOut(startTime + pagingTimeOut)) {
@@ -116,15 +126,40 @@ void DefaultGCActivityCallback::cancelTimer()
m_delay = hour;
m_timer.stop();
}
+#elif PLATFORM(EFL)
+void DefaultGCActivityCallback::scheduleTimer(double newDelay)
+{
+ if (newDelay * timerSlop > m_delay)
+ return;
+
+ stop();
+ m_delay = newDelay;
+
+ ASSERT(!m_timer);
+ m_timer = add(newDelay, this);
+}
+
+void DefaultGCActivityCallback::cancelTimer()
+{
+ m_delay = hour;
+ stop();
+}
#endif
void DefaultGCActivityCallback::didAllocate(size_t bytes)
{
+#if PLATFORM(EFL)
+ if (!isEnabled())
+ return;
+
+ ASSERT(WTF::isMainThread());
+#endif
+
// The first byte allocated in an allocation cycle will report 0 bytes to didAllocate.
// We pretend it's one byte so that we don't ignore this allocation entirely.
if (!bytes)
bytes = 1;
- Heap* heap = static_cast<Heap*>(&m_globalData->heap);
+ Heap* heap = static_cast<Heap*>(&m_vm->heap);
double gcTimeSlice = std::min((static_cast<double>(bytes) / MB) * gcTimeSlicePerMB, maxGCTimeSlice);
double newDelay = heap->lastGCLength() / gcTimeSlice;
scheduleTimer(newDelay);
@@ -143,7 +178,7 @@ void DefaultGCActivityCallback::cancel()
#else
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
- : GCActivityCallback(heap->globalData())
+ : GCActivityCallback(heap->vm())
{
}
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallback.h b/Source/JavaScriptCore/runtime/GCActivityCallback.h
index 3522e6c8e..a7aec6a8d 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallback.h
+++ b/Source/JavaScriptCore/runtime/GCActivityCallback.h
@@ -52,14 +52,20 @@ public:
protected:
#if USE(CF)
- GCActivityCallback(JSGlobalData* globalData, CFRunLoopRef runLoop)
- : HeapTimer(globalData, runLoop)
+ GCActivityCallback(VM* vm, CFRunLoopRef runLoop)
+ : HeapTimer(vm, runLoop)
, m_enabled(true)
{
}
+#elif PLATFORM(EFL)
+ GCActivityCallback(VM* vm, bool flag)
+ : HeapTimer(vm)
+ , m_enabled(flag)
+ {
+ }
#else
- GCActivityCallback(JSGlobalData* globalData)
- : HeapTimer(globalData)
+ GCActivityCallback(VM* vm)
+ : HeapTimer(vm)
, m_enabled(true)
{
}
@@ -70,7 +76,7 @@ protected:
class DefaultGCActivityCallback : public GCActivityCallback {
public:
- static DefaultGCActivityCallback* create(Heap*);
+ static PassOwnPtr<DefaultGCActivityCallback> create(Heap*);
DefaultGCActivityCallback(Heap*);
@@ -84,7 +90,7 @@ public:
protected:
DefaultGCActivityCallback(Heap*, CFRunLoopRef);
#endif
-#if USE(CF) || PLATFORM(QT)
+#if USE(CF) || PLATFORM(QT) || PLATFORM(EFL)
protected:
void cancelTimer();
void scheduleTimer(double);
@@ -94,9 +100,9 @@ private:
#endif
};
-inline DefaultGCActivityCallback* DefaultGCActivityCallback::create(Heap* heap)
+inline PassOwnPtr<DefaultGCActivityCallback> DefaultGCActivityCallback::create(Heap* heap)
{
- return new DefaultGCActivityCallback(heap);
+ return adoptPtr(new DefaultGCActivityCallback(heap));
}
}
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
index 35b992567..d7c9d53c2 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
@@ -20,29 +20,29 @@
#include "GCActivityCallback.h"
#include "Heap.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include <BlackBerryPlatformMemory.h>
namespace JSC {
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
- : GCActivityCallback(heap->globalData())
+ : GCActivityCallback(heap->vm())
{
}
void DefaultGCActivityCallback::doWork()
{
- JSLock lock(SilenceAssertionsOnly);
- m_globalData->heap.collect(Heap::DoNotSweep);
+ JSLockHolder lock(m_vm);
+ m_vm->heap.collect(Heap::DoNotSweep);
}
-void DefaultGCActivityCallback::didAllocate(size_t bytesAllocated)
+void DefaultGCActivityCallback::didAllocate(size_t)
{
if (m_timer.started())
return;
// Try using ~5% CPU time.
- m_timer.start(m_globalData->heap.lastGCLength() * 20);
+ m_timer.start(m_vm->heap.lastGCLength() * 20);
}
void DefaultGCActivityCallback::willCollect()
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.cpp b/Source/JavaScriptCore/runtime/GetterSetter.cpp
index 8ed582548..b4651141e 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.cpp
+++ b/Source/JavaScriptCore/runtime/GetterSetter.cpp
@@ -24,6 +24,7 @@
#include "GetterSetter.h"
#include "JSObject.h"
+#include "Operations.h"
#include <wtf/Assertions.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/GetterSetter.h b/Source/JavaScriptCore/runtime/GetterSetter.h
index b8caf0198..f459e4432 100644
--- a/Source/JavaScriptCore/runtime/GetterSetter.h
+++ b/Source/JavaScriptCore/runtime/GetterSetter.h
@@ -39,7 +39,7 @@ namespace JSC {
private:
GetterSetter(ExecState* exec)
- : JSCell(exec->globalData(), exec->globalData().getterSetterStructure.get())
+ : JSCell(exec->vm(), exec->vm().getterSetterStructure.get())
{
}
@@ -49,19 +49,19 @@ namespace JSC {
static GetterSetter* create(ExecState* exec)
{
GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(*exec->heap())) GetterSetter(exec);
- getterSetter->finishCreation(exec->globalData());
+ getterSetter->finishCreation(exec->vm());
return getterSetter;
}
static void visitChildren(JSCell*, SlotVisitor&);
JSObject* getter() const { return m_getter.get(); }
- void setGetter(JSGlobalData& globalData, JSObject* getter) { m_getter.setMayBeNull(globalData, this, getter); }
+ void setGetter(VM& vm, JSObject* getter) { m_getter.setMayBeNull(vm, this, getter); }
JSObject* setter() const { return m_setter.get(); }
- void setSetter(JSGlobalData& globalData, JSObject* setter) { m_setter.setMayBeNull(globalData, this, setter); }
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ void setSetter(VM& vm, JSObject* setter) { m_setter.setMayBeNull(vm, this, setter); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(GetterSetterType, OverridesVisitChildren), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType, OverridesVisitChildren), &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp
index 583c12bb1..ad61b493a 100644
--- a/Source/JavaScriptCore/runtime/Identifier.cpp
+++ b/Source/JavaScriptCore/runtime/Identifier.cpp
@@ -25,6 +25,7 @@
#include "JSObject.h"
#include "JSScope.h"
#include "NumericStrings.h"
+#include "Operations.h"
#include <new>
#include <string.h>
#include <wtf/Assertions.h>
@@ -50,7 +51,7 @@ void deleteIdentifierTable(IdentifierTable* table)
struct IdentifierASCIIStringTranslator {
static unsigned hash(const LChar* c)
{
- return StringHasher::computeHashAndMaskTop8Bits<LChar>(c);
+ return StringHasher::computeHashAndMaskTop8Bits(c);
}
static bool equal(StringImpl* r, const LChar* s)
@@ -69,7 +70,7 @@ struct IdentifierASCIIStringTranslator {
struct IdentifierLCharFromUCharTranslator {
static unsigned hash(const CharBuffer<UChar>& buf)
{
- return StringHasher::computeHashAndMaskTop8Bits<UChar>(buf.s, buf.length);
+ return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length);
}
static bool equal(StringImpl* str, const CharBuffer<UChar>& buf)
@@ -87,19 +88,14 @@ struct IdentifierLCharFromUCharTranslator {
}
};
-PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c)
+PassRefPtr<StringImpl> Identifier::add(VM* vm, const char* c)
{
ASSERT(c);
ASSERT(c[0]);
if (!c[1])
- return add(globalData, globalData->smallStrings.singleCharacterStringRep(c[0]));
+ return add(vm, vm->smallStrings.singleCharacterStringRep(c[0]));
- IdentifierTable& identifierTable = *globalData->identifierTable;
- LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable();
-
- const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c);
- if (iter != literalIdentifierTable.end())
- return iter->value;
+ IdentifierTable& identifierTable = *vm->identifierTable;
HashSet<StringImpl*>::AddResult addResult = identifierTable.add<const LChar*, IdentifierASCIIStringTranslator>(reinterpret_cast<const LChar*>(c));
@@ -107,36 +103,34 @@ PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c)
// The boolean in the pair tells us if that is so.
RefPtr<StringImpl> addedString = addResult.isNewEntry ? adoptRef(*addResult.iterator) : *addResult.iterator;
- literalIdentifierTable.add(c, addedString.get());
-
return addedString.release();
}
PassRefPtr<StringImpl> Identifier::add(ExecState* exec, const char* c)
{
- return add(&exec->globalData(), c);
+ return add(&exec->vm(), c);
}
-PassRefPtr<StringImpl> Identifier::add8(JSGlobalData* globalData, const UChar* s, int length)
+PassRefPtr<StringImpl> Identifier::add8(VM* vm, const UChar* s, int length)
{
if (length == 1) {
UChar c = s[0];
ASSERT(c <= 0xff);
if (canUseSingleCharacterString(c))
- return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
+ return add(vm, vm->smallStrings.singleCharacterStringRep(c));
}
if (!length)
return StringImpl::empty();
CharBuffer<UChar> buf = { s, static_cast<unsigned>(length) };
- HashSet<StringImpl*>::AddResult addResult = globalData->identifierTable->add<CharBuffer<UChar>, IdentifierLCharFromUCharTranslator >(buf);
+ HashSet<StringImpl*>::AddResult addResult = vm->identifierTable->add<CharBuffer<UChar>, IdentifierLCharFromUCharTranslator >(buf);
// If the string is newly-translated, then we need to adopt it.
// The boolean in the pair tells us if that is so.
return addResult.isNewEntry ? adoptRef(*addResult.iterator) : *addResult.iterator;
}
-PassRefPtr<StringImpl> Identifier::addSlowCase(JSGlobalData* globalData, StringImpl* r)
+PassRefPtr<StringImpl> Identifier::addSlowCase(VM* vm, StringImpl* r)
{
ASSERT(!r->isIdentifier());
// The empty & null strings are static singletons, and static strings are handled
@@ -146,68 +140,68 @@ PassRefPtr<StringImpl> Identifier::addSlowCase(JSGlobalData* globalData, StringI
if (r->length() == 1) {
UChar c = (*r)[0];
if (c <= maxSingleCharacterString)
- r = globalData->smallStrings.singleCharacterStringRep(c);
+ r = vm->smallStrings.singleCharacterStringRep(c);
if (r->isIdentifier())
return r;
}
- return *globalData->identifierTable->add(r).iterator;
+ return *vm->identifierTable->add(r).iterator;
}
PassRefPtr<StringImpl> Identifier::addSlowCase(ExecState* exec, StringImpl* r)
{
- return addSlowCase(&exec->globalData(), r);
+ return addSlowCase(&exec->vm(), r);
}
Identifier Identifier::from(ExecState* exec, unsigned value)
{
- return Identifier(exec, exec->globalData().numericStrings.add(value));
+ return Identifier(exec, exec->vm().numericStrings.add(value));
}
Identifier Identifier::from(ExecState* exec, int value)
{
- return Identifier(exec, exec->globalData().numericStrings.add(value));
+ return Identifier(exec, exec->vm().numericStrings.add(value));
}
Identifier Identifier::from(ExecState* exec, double value)
{
- return Identifier(exec, exec->globalData().numericStrings.add(value));
+ return Identifier(exec, exec->vm().numericStrings.add(value));
}
-Identifier Identifier::from(JSGlobalData* globalData, unsigned value)
+Identifier Identifier::from(VM* vm, unsigned value)
{
- return Identifier(globalData, globalData->numericStrings.add(value));
+ return Identifier(vm, vm->numericStrings.add(value));
}
-Identifier Identifier::from(JSGlobalData* globalData, int value)
+Identifier Identifier::from(VM* vm, int value)
{
- return Identifier(globalData, globalData->numericStrings.add(value));
+ return Identifier(vm, vm->numericStrings.add(value));
}
-Identifier Identifier::from(JSGlobalData* globalData, double value)
+Identifier Identifier::from(VM* vm, double value)
{
- return Identifier(globalData, globalData->numericStrings.add(value));
+ return Identifier(vm, vm->numericStrings.add(value));
}
#ifndef NDEBUG
-void Identifier::checkCurrentIdentifierTable(JSGlobalData* globalData)
+void Identifier::checkCurrentIdentifierTable(VM* vm)
{
// Check the identifier table accessible through the threadspecific matches the
- // globalData's identifier table.
- ASSERT_UNUSED(globalData, globalData->identifierTable == wtfThreadData().currentIdentifierTable());
+ // vm's identifier table.
+ ASSERT_UNUSED(vm, vm->identifierTable == wtfThreadData().currentIdentifierTable());
}
void Identifier::checkCurrentIdentifierTable(ExecState* exec)
{
- checkCurrentIdentifierTable(&exec->globalData());
+ checkCurrentIdentifierTable(&exec->vm());
}
#else
// These only exists so that our exports are the same for debug and release builds.
-// This would be an ASSERT_NOT_REACHED(), but we're in NDEBUG only code here!
-NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentIdentifierTable(JSGlobalData*) { CRASH(); }
+// This would be an RELEASE_ASSERT_NOT_REACHED(), but we're in NDEBUG only code here!
+NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentIdentifierTable(VM*) { CRASH(); }
NO_RETURN_DUE_TO_CRASH void Identifier::checkCurrentIdentifierTable(ExecState*) { CRASH(); }
#endif
diff --git a/Source/JavaScriptCore/runtime/Identifier.h b/Source/JavaScriptCore/runtime/Identifier.h
index dcb739ec3..75b68b6e1 100644
--- a/Source/JavaScriptCore/runtime/Identifier.h
+++ b/Source/JavaScriptCore/runtime/Identifier.h
@@ -21,7 +21,7 @@
#ifndef Identifier_h
#define Identifier_h
-#include "JSGlobalData.h"
+#include "VM.h"
#include <wtf/ThreadSpecific.h>
#include <wtf/WTFThreadData.h>
#include <wtf/text/CString.h>
@@ -42,15 +42,15 @@ namespace JSC {
template<unsigned charactersCount>
Identifier(ExecState* exec, const char (&characters)[charactersCount]) : m_string(add(exec, characters)) { }
template<unsigned charactersCount>
- Identifier(JSGlobalData* globalData, const char (&characters)[charactersCount]) : m_string(add(globalData, characters)) { }
+ Identifier(VM* vm, const char (&characters)[charactersCount]) : m_string(add(vm, characters)) { }
Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { }
Identifier(ExecState* exec, const String& s) : m_string(add(exec, s.impl())) { }
- Identifier(JSGlobalData* globalData, const LChar* s, int length) : m_string(add(globalData, s, length)) { }
- Identifier(JSGlobalData* globalData, const UChar* s, int length) : m_string(add(globalData, s, length)) { }
- Identifier(JSGlobalData* globalData, StringImpl* rep) : m_string(add(globalData, rep)) { }
- Identifier(JSGlobalData* globalData, const String& s) : m_string(add(globalData, s.impl())) { }
+ Identifier(VM* vm, const LChar* s, int length) : m_string(add(vm, s, length)) { }
+ Identifier(VM* vm, const UChar* s, int length) : m_string(add(vm, s, length)) { }
+ Identifier(VM* vm, StringImpl* rep) : m_string(add(vm, rep)) { }
+ Identifier(VM* vm, const String& s) : m_string(add(vm, s.impl())) { }
const String& string() const { return m_string; }
StringImpl* impl() const { return m_string.impl(); }
@@ -60,14 +60,14 @@ namespace JSC {
CString ascii() const { return m_string.ascii(); }
- static Identifier createLCharFromUChar(JSGlobalData* globalData, const UChar* s, int length) { return Identifier(globalData, add8(globalData, s, length)); }
+ static Identifier createLCharFromUChar(VM* vm, const UChar* s, int length) { return Identifier(vm, add8(vm, s, length)); }
JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, unsigned y);
JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, int y);
static Identifier from(ExecState* exec, double y);
- static Identifier from(JSGlobalData*, unsigned y);
- static Identifier from(JSGlobalData*, int y);
- static Identifier from(JSGlobalData*, double y);
+ static Identifier from(VM*, unsigned y);
+ static Identifier from(VM*, int y);
+ static Identifier from(VM*, double y);
bool isNull() const { return m_string.isNull(); }
bool isEmpty() const { return m_string.isEmpty(); }
@@ -87,7 +87,7 @@ namespace JSC {
static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
// Only to be used with string literals.
- static PassRefPtr<StringImpl> add(JSGlobalData*, const char*);
+ static PassRefPtr<StringImpl> add(VM*, const char*);
JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(ExecState*, const char*);
private:
@@ -99,8 +99,8 @@ namespace JSC {
static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); }
static bool equal(const Identifier& a, const LChar* b) { return equal(a.m_string.impl(), b); }
- template <typename T> static PassRefPtr<StringImpl> add(JSGlobalData*, const T*, int length);
- static PassRefPtr<StringImpl> add8(JSGlobalData*, const UChar*, int length);
+ template <typename T> static PassRefPtr<StringImpl> add(VM*, const T*, int length);
+ static PassRefPtr<StringImpl> add8(VM*, const UChar*, int length);
template <typename T> ALWAYS_INLINE static bool canUseSingleCharacterString(T);
static PassRefPtr<StringImpl> add(ExecState* exec, StringImpl* r)
@@ -112,21 +112,21 @@ namespace JSC {
return r;
return addSlowCase(exec, r);
}
- static PassRefPtr<StringImpl> add(JSGlobalData* globalData, StringImpl* r)
+ static PassRefPtr<StringImpl> add(VM* vm, StringImpl* r)
{
#ifndef NDEBUG
- checkCurrentIdentifierTable(globalData);
+ checkCurrentIdentifierTable(vm);
#endif
if (r->isIdentifier())
return r;
- return addSlowCase(globalData, r);
+ return addSlowCase(vm, r);
}
JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(ExecState*, StringImpl* r);
- JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(JSGlobalData*, StringImpl* r);
+ JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> addSlowCase(VM*, StringImpl* r);
JS_EXPORT_PRIVATE static void checkCurrentIdentifierTable(ExecState*);
- JS_EXPORT_PRIVATE static void checkCurrentIdentifierTable(JSGlobalData*);
+ JS_EXPORT_PRIVATE static void checkCurrentIdentifierTable(VM*);
};
template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar)
@@ -150,7 +150,7 @@ namespace JSC {
struct IdentifierCharBufferTranslator {
static unsigned hash(const CharBuffer<T>& buf)
{
- return StringHasher::computeHashAndMaskTop8Bits<T>(buf.s, buf.length);
+ return StringHasher::computeHashAndMaskTop8Bits(buf.s, buf.length);
}
static bool equal(StringImpl* str, const CharBuffer<T>& buf)
@@ -170,18 +170,18 @@ namespace JSC {
};
template <typename T>
- PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const T* s, int length)
+ PassRefPtr<StringImpl> Identifier::add(VM* vm, const T* s, int length)
{
if (length == 1) {
T c = s[0];
if (canUseSingleCharacterString(c))
- return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
+ return add(vm, vm->smallStrings.singleCharacterStringRep(c));
}
if (!length)
return StringImpl::empty();
CharBuffer<T> buf = { s, static_cast<unsigned>(length) };
- HashSet<StringImpl*>::AddResult addResult = globalData->identifierTable->add<CharBuffer<T>, IdentifierCharBufferTranslator<T> >(buf);
+ HashSet<StringImpl*>::AddResult addResult = vm->identifierTable->add<CharBuffer<T>, IdentifierCharBufferTranslator<T> >(buf);
// If the string is newly-translated, then we need to adopt it.
// The boolean in the pair tells us if that is so.
@@ -251,11 +251,17 @@ namespace JSC {
template<typename U, typename V>
HashSet<StringImpl*>::AddResult IdentifierTable::add(U value)
{
- HashSet<StringImpl*>::AddResult result = m_table.add<U, V>(value);
+ HashSet<StringImpl*>::AddResult result = m_table.add<V>(value);
(*result.iterator)->setIsIdentifier(true);
return result;
}
} // namespace JSC
+namespace WTF {
+
+template <> struct VectorTraits<JSC::Identifier> : SimpleClassVectorTraits { };
+
+} // namespace WTF
+
#endif // Identifier_h
diff --git a/Source/JavaScriptCore/runtime/IndexingHeader.h b/Source/JavaScriptCore/runtime/IndexingHeader.h
index caa18183a..145b61876 100644
--- a/Source/JavaScriptCore/runtime/IndexingHeader.h
+++ b/Source/JavaScriptCore/runtime/IndexingHeader.h
@@ -44,25 +44,25 @@ public:
static ptrdiff_t offsetOfIndexingHeader() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); }
- static ptrdiff_t offsetOfPublicLength() { return OBJECT_OFFSETOF(IndexingHeader, m_publicLength); }
- static ptrdiff_t offsetOfVectorLength() { return OBJECT_OFFSETOF(IndexingHeader, m_vectorLength); }
+ static ptrdiff_t offsetOfPublicLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.publicLength); }
+ static ptrdiff_t offsetOfVectorLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.vectorLength); }
IndexingHeader()
- : m_publicLength(0)
- , m_vectorLength(0)
{
+ u.lengths.publicLength = 0;
+ u.lengths.vectorLength = 0;
}
- uint32_t vectorLength() const { return m_vectorLength; }
+ uint32_t vectorLength() const { return u.lengths.vectorLength; }
void setVectorLength(uint32_t length)
{
- ASSERT(length <= maximumLength);
- m_vectorLength = length;
+ RELEASE_ASSERT(length <= maximumLength);
+ u.lengths.vectorLength = length;
}
- uint32_t publicLength() { return m_publicLength; }
- void setPublicLength(uint32_t auxWord) { m_publicLength = auxWord; }
+ uint32_t publicLength() { return u.lengths.publicLength; }
+ void setPublicLength(uint32_t auxWord) { u.lengths.publicLength = auxWord; }
static IndexingHeader* from(Butterfly* butterfly)
{
@@ -86,12 +86,12 @@ public:
PropertyStorage propertyStorage()
{
- return reinterpret_cast<PropertyStorage>(this);
+ return reinterpret_cast_ptr<PropertyStorage>(this);
}
ConstPropertyStorage propertyStorage() const
{
- return reinterpret_cast<ConstPropertyStorage>(this);
+ return reinterpret_cast_ptr<ConstPropertyStorage>(this);
}
ArrayStorage* arrayStorage()
@@ -111,9 +111,13 @@ public:
private:
friend class LLIntOffsetsExtractor;
-
- uint32_t m_publicLength; // The meaning of this field depends on the array type, but for all JSArrays we rely on this being the publicly visible length (array.length).
- uint32_t m_vectorLength; // The length of the indexed property storage. The actual size of the storage depends on this, and the type.
+
+ union {
+ struct {
+ uint32_t publicLength; // The meaning of this field depends on the array type, but for all JSArrays we rely on this being the publicly visible length (array.length).
+ uint32_t vectorLength; // The length of the indexed property storage. The actual size of the storage depends on this, and the type.
+ } lengths;
+ } u;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/IndexingType.cpp b/Source/JavaScriptCore/runtime/IndexingType.cpp
index dc2733ad1..040a7828a 100644
--- a/Source/JavaScriptCore/runtime/IndexingType.cpp
+++ b/Source/JavaScriptCore/runtime/IndexingType.cpp
@@ -71,9 +71,8 @@ IndexingType leastUpperBoundOfIndexingTypeAndValue(IndexingType indexingType, JS
return leastUpperBoundOfIndexingTypeAndType(indexingType, speculationFromValue(value));
}
-const char* indexingTypeToString(IndexingType indexingType)
+void dumpIndexingType(PrintStream& out, IndexingType indexingType)
{
- static char result[128];
const char* basicName;
switch (indexingType & AllArrayTypes) {
case NonArray:
@@ -120,11 +119,7 @@ const char* indexingTypeToString(IndexingType indexingType)
break;
}
- snprintf(
- result, sizeof(result), "%s%s", basicName,
- (indexingType & MayHaveIndexedAccessors) ? "|MayHaveIndexedAccessors" : "");
-
- return result;
+ out.printf("%s%s", basicName, (indexingType & MayHaveIndexedAccessors) ? "|MayHaveIndexedAccessors" : "");
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/IndexingType.h b/Source/JavaScriptCore/runtime/IndexingType.h
index ab253be1e..dc5684b5f 100644
--- a/Source/JavaScriptCore/runtime/IndexingType.h
+++ b/Source/JavaScriptCore/runtime/IndexingType.h
@@ -34,27 +34,27 @@ namespace JSC {
typedef uint8_t IndexingType;
// Flags for testing the presence of capabilities.
-static const IndexingType IsArray = 1;
+static const IndexingType IsArray = 0x01;
// The shape of the indexed property storage.
-static const IndexingType IndexingShapeMask = 30;
-static const IndexingType NoIndexingShape = 0;
-static const IndexingType UndecidedShape = 2; // Only useful for arrays.
-static const IndexingType Int32Shape = 20;
-static const IndexingType DoubleShape = 22;
-static const IndexingType ContiguousShape = 26;
-static const IndexingType ArrayStorageShape = 28;
-static const IndexingType SlowPutArrayStorageShape = 30;
+static const IndexingType IndexingShapeMask = 0x1E;
+static const IndexingType NoIndexingShape = 0x00;
+static const IndexingType UndecidedShape = 0x02; // Only useful for arrays.
+static const IndexingType Int32Shape = 0x14;
+static const IndexingType DoubleShape = 0x16;
+static const IndexingType ContiguousShape = 0x1A;
+static const IndexingType ArrayStorageShape = 0x1C;
+static const IndexingType SlowPutArrayStorageShape = 0x1E;
static const IndexingType IndexingShapeShift = 1;
static const IndexingType NumberOfIndexingShapes = 16;
// Additional flags for tracking the history of the type. These are usually
// masked off unless you ask for them directly.
-static const IndexingType MayHaveIndexedAccessors = 32;
+static const IndexingType MayHaveIndexedAccessors = 0x20;
// List of acceptable array types.
-static const IndexingType NonArray = 0;
+static const IndexingType NonArray = 0x0;
static const IndexingType NonArrayWithInt32 = Int32Shape;
static const IndexingType NonArrayWithDouble = DoubleShape;
static const IndexingType NonArrayWithContiguous = ContiguousShape;
@@ -149,7 +149,8 @@ IndexingType leastUpperBoundOfIndexingTypes(IndexingType, IndexingType);
IndexingType leastUpperBoundOfIndexingTypeAndType(IndexingType, SpeculatedType);
IndexingType leastUpperBoundOfIndexingTypeAndValue(IndexingType, JSValue);
-const char* indexingTypeToString(IndexingType);
+void dumpIndexingType(PrintStream&, IndexingType);
+MAKE_PRINT_ADAPTOR(IndexingTypeDump, IndexingType, dumpIndexingType);
// Mask of all possible types.
static const IndexingType AllArrayTypes = 31;
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp
index afb5e6317..071babc46 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp
@@ -26,6 +26,7 @@
#include "FunctionPrototype.h"
#include "JSGlobalObject.h"
#include "JSString.h"
+#include "Operations.h"
namespace JSC {
@@ -34,26 +35,26 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(InternalFunction);
const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* structure)
- : JSDestructibleObject(globalObject->globalData(), structure)
+ : JSDestructibleObject(globalObject->vm(), structure)
{
}
-void InternalFunction::finishCreation(JSGlobalData& globalData, const String& name)
+void InternalFunction::finishCreation(VM& vm, const String& name)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
ASSERT(methodTable()->getCallData != InternalFunction::s_info.methodTable.getCallData);
- putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name), DontDelete | ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
}
const String& InternalFunction::name(ExecState* exec)
{
- return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue();
+ return asString(getDirect(exec->vm(), exec->vm().propertyNames->name))->tryGetValue();
}
const String InternalFunction::displayName(ExecState* exec)
{
- JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
+ JSValue displayName = getDirect(exec->vm(), exec->vm().propertyNames->displayName);
if (displayName && isJSString(displayName))
return asString(displayName)->tryGetValue();
@@ -63,7 +64,7 @@ const String InternalFunction::displayName(ExecState* exec)
CallType InternalFunction::getCallData(JSCell*, CallData&)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return CallTypeNone;
}
diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h
index daeebc34d..e35f5f9f2 100644
--- a/Source/JavaScriptCore/runtime/InternalFunction.h
+++ b/Source/JavaScriptCore/runtime/InternalFunction.h
@@ -41,9 +41,9 @@ namespace JSC {
const String displayName(ExecState*);
const String calculatedDisplayName(ExecState*);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
@@ -51,7 +51,7 @@ namespace JSC {
JS_EXPORT_PRIVATE InternalFunction(JSGlobalObject*, Structure*);
- JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, const String& name);
+ JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);
static CallType getCallData(JSCell*, CallData&);
};
diff --git a/Source/JavaScriptCore/runtime/Intrinsic.h b/Source/JavaScriptCore/runtime/Intrinsic.h
index 73244e7c7..313826edb 100644
--- a/Source/JavaScriptCore/runtime/Intrinsic.h
+++ b/Source/JavaScriptCore/runtime/Intrinsic.h
@@ -47,6 +47,8 @@ enum Intrinsic {
LogIntrinsic,
RegExpExecIntrinsic,
RegExpTestIntrinsic,
+ StringPrototypeValueOfIntrinsic,
+ IMulIntrinsic
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 21d7b215c..f0910951b 100644
--- a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -23,8 +23,8 @@
#ifndef JSAPIValueWrapper_h
#define JSAPIValueWrapper_h
+#include "JSCJSValue.h"
#include "JSCell.h"
-#include "JSValue.h"
#include "CallFrame.h"
#include "Structure.h"
@@ -37,9 +37,9 @@ namespace JSC {
JSValue value() const { return m_value.get(); }
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(APIValueWrapperType, OverridesVisitChildren | OverridesGetPropertyNames), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(APIValueWrapperType, OverridesVisitChildren | OverridesGetPropertyNames), &s_info);
}
static JS_EXPORTDATA const ClassInfo s_info;
@@ -54,14 +54,14 @@ namespace JSC {
protected:
void finishCreation(ExecState* exec, JSValue value)
{
- Base::finishCreation(exec->globalData());
- m_value.set(exec->globalData(), this, value);
+ Base::finishCreation(exec->vm());
+ m_value.set(exec->vm(), this, value);
ASSERT(!value.isCell());
}
private:
JSAPIValueWrapper(ExecState* exec)
- : JSCell(exec->globalData(), exec->globalData().apiWrapperStructure.get())
+ : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get())
{
}
diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp
index 3b665962f..3a3bb50af 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.cpp
+++ b/Source/JavaScriptCore/runtime/JSActivation.cpp
@@ -32,6 +32,7 @@
#include "Arguments.h"
#include "Interpreter.h"
#include "JSFunction.h"
+#include "Operations.h"
using namespace std;
@@ -85,7 +86,7 @@ inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertyDesc
inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyName, JSValue value, bool shouldThrow)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
@@ -101,7 +102,7 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN
if (isTornOff() && !isValid(entry))
return false;
- registerAt(entry.getIndex()).set(globalData, this, value);
+ registerAt(entry.getIndex()).set(vm, this, value);
return true;
}
@@ -124,7 +125,7 @@ void JSActivation::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec
JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
}
-inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
+inline bool JSActivation::symbolTablePutWithAttributes(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -137,7 +138,7 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
return false;
entry.setAttributes(attributes);
- registerAt(entry.getIndex()).set(globalData, this, value);
+ registerAt(entry.getIndex()).set(vm, this, value);
return true;
}
@@ -156,8 +157,8 @@ bool JSActivation::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyNam
if (thisObject->symbolTableGet(propertyName, slot))
return true;
- if (WriteBarrierBase<Unknown>* location = thisObject->getDirectLocation(exec->globalData(), propertyName)) {
- slot.setValue(location->get());
+ if (JSValue value = thisObject->getDirect(exec->vm(), propertyName)) {
+ slot.setValue(value);
return true;
}
@@ -200,7 +201,7 @@ void JSActivation::put(JSCell* cell, ExecState* exec, PropertyName propertyName,
// properties are non-standard extensions that other implementations do not
// expose in the activation object.
ASSERT(!thisObject->hasGetterSetterProperties());
- thisObject->putOwnDataProperty(exec->globalData(), propertyName, value, slot);
+ thisObject->putOwnDataProperty(exec->vm(), propertyName, value, slot);
}
// FIXME: Make this function honor ReadOnly (const) and DontEnum
@@ -209,7 +210,7 @@ void JSActivation::putDirectVirtual(JSObject* object, ExecState* exec, PropertyN
JSActivation* thisObject = jsCast<JSActivation*>(object);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
- if (thisObject->symbolTablePutWithAttributes(exec->globalData(), propertyName, value, attributes))
+ if (thisObject->symbolTablePutWithAttributes(exec->vm(), propertyName, value, attributes))
return;
// We don't call through to JSObject because __proto__ and getter/setter
@@ -244,7 +245,7 @@ JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, PropertyName
return arguments;
int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister);
- JSValue arguments = JSValue(Arguments::create(callFrame->globalData(), callFrame));
+ JSValue arguments = JSValue(Arguments::create(callFrame->vm(), callFrame));
callFrame->uncheckedR(argumentsRegister) = arguments;
callFrame->uncheckedR(realArgumentsRegister) = arguments;
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index b8f5621af..dfbc0c134 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -41,22 +41,22 @@ namespace JSC {
class JSActivation : public JSVariableObject {
private:
- JSActivation(JSGlobalData& globalData, CallFrame*, SharedSymbolTable*);
+ JSActivation(VM& vm, CallFrame*, SharedSymbolTable*);
public:
typedef JSVariableObject Base;
- static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, CodeBlock* codeBlock)
+ static JSActivation* create(VM& vm, CallFrame* callFrame, CodeBlock* codeBlock)
{
SharedSymbolTable* symbolTable = codeBlock->symbolTable();
JSActivation* activation = new (
NotNull,
allocateCell<JSActivation>(
- globalData.heap,
+ vm.heap,
allocationSize(symbolTable)
)
- ) JSActivation(globalData, callFrame, symbolTable);
- activation->finishCreation(globalData);
+ ) JSActivation(vm, callFrame, symbolTable);
+ activation->finishCreation(vm);
return activation;
}
@@ -75,11 +75,11 @@ namespace JSC {
static JSObject* toThisObject(JSCell*, ExecState*);
- void tearOff(JSGlobalData&);
+ void tearOff(VM&);
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); }
WriteBarrierBase<Unknown>& registerAt(int) const;
bool isValidIndex(int) const;
@@ -96,7 +96,7 @@ namespace JSC {
bool symbolTableGet(PropertyName, PropertyDescriptor&);
bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable);
bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
- bool symbolTablePutWithAttributes(JSGlobalData&, PropertyName, JSValue, unsigned attributes);
+ bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
static JSValue argumentsGetter(ExecState*, JSValue, PropertyName);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
@@ -110,9 +110,9 @@ namespace JSC {
extern int activationCount;
extern int allTheThingsCount;
- inline JSActivation::JSActivation(JSGlobalData& globalData, CallFrame* callFrame, SharedSymbolTable* symbolTable)
+ inline JSActivation::JSActivation(VM& vm, CallFrame* callFrame, SharedSymbolTable* symbolTable)
: Base(
- globalData,
+ vm,
callFrame->lexicalGlobalObject()->activationStructure(),
callFrame->registers(),
callFrame->scope(),
@@ -149,17 +149,17 @@ namespace JSC {
return storageOffset() - (symbolTable->captureStart() * sizeof(WriteBarrier<Unknown>));
}
- inline void JSActivation::tearOff(JSGlobalData& globalData)
+ inline void JSActivation::tearOff(VM& vm)
{
ASSERT(!isTornOff());
- WriteBarrierBase<Unknown>* dst = reinterpret_cast<WriteBarrierBase<Unknown>*>(
+ WriteBarrierBase<Unknown>* dst = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
WriteBarrierBase<Unknown>* src = m_registers;
int captureEnd = symbolTable()->captureEnd();
for (int i = symbolTable()->captureStart(); i < captureEnd; ++i)
- dst[i].set(globalData, this, src[i].get());
+ dst[i].set(vm, this, src[i].get());
m_registers = dst;
ASSERT(isTornOff());
@@ -167,7 +167,7 @@ namespace JSC {
inline bool JSActivation::isTornOff()
{
- return m_registers == reinterpret_cast<WriteBarrierBase<Unknown>*>(
+ return m_registers == reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
reinterpret_cast<char*>(this) + registersOffset(symbolTable()));
}
@@ -178,7 +178,7 @@ namespace JSC {
inline WriteBarrier<Unknown>* JSActivation::storage()
{
- return reinterpret_cast<WriteBarrier<Unknown>*>(
+ return reinterpret_cast_ptr<WriteBarrier<Unknown>*>(
reinterpret_cast<char*>(this) + storageOffset());
}
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index c742804f7..f97ccedcd 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -48,10 +48,10 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSArray);
const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSArray)};
-Butterfly* createArrayButterflyInDictionaryIndexingMode(JSGlobalData& globalData, unsigned initialLength)
+Butterfly* createArrayButterflyInDictionaryIndexingMode(VM& vm, unsigned initialLength)
{
Butterfly* butterfly = Butterfly::create(
- globalData, 0, 0, true, IndexingHeader(), ArrayStorage::sizeFor(0));
+ vm, 0, 0, true, IndexingHeader(), ArrayStorage::sizeFor(0));
ArrayStorage* storage = butterfly->arrayStorage();
storage->setLength(initialLength);
storage->setVectorLength(0);
@@ -67,7 +67,7 @@ void JSArray::setLengthWritable(ExecState* exec, bool writable)
if (!isLengthWritable() || writable)
return;
- enterDictionaryIndexingMode(exec->globalData());
+ enterDictionaryIndexingMode(exec->vm());
SparseArrayValueMap* map = arrayStorage()->m_sparseMap.get();
ASSERT(map);
@@ -244,9 +244,9 @@ void JSArray::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, Pro
}
// This method makes room in the vector, but leaves the new space for count slots uncleared.
-bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, unsigned count)
+bool JSArray::unshiftCountSlowCase(VM& vm, bool addToFront, unsigned count)
{
- ArrayStorage* storage = ensureArrayStorage(globalData);
+ ArrayStorage* storage = ensureArrayStorage(vm);
Butterfly* butterfly = storage->butterfly();
unsigned propertyCapacity = structure()->outOfLineCapacity();
unsigned propertySize = structure()->outOfLineSize();
@@ -286,7 +286,7 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, un
newStorageCapacity = currentCapacity;
} else {
size_t newSize = Butterfly::totalSize(0, propertyCapacity, true, ArrayStorage::sizeFor(desiredCapacity));
- if (!globalData.heap.tryAllocateStorage(newSize, &newAllocBase))
+ if (!vm.heap.tryAllocateStorage(newSize, &newAllocBase))
return false;
newStorageCapacity = desiredCapacity;
}
@@ -349,8 +349,8 @@ bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, boo
if (newLength < length) {
// Copy any keys we might be interested in into a vector.
- Vector<unsigned> keys;
- keys.reserveCapacity(min(map->size(), static_cast<size_t>(length - newLength)));
+ Vector<unsigned, 0, UnsafeVectorOverflow> keys;
+ keys.reserveInitialCapacity(min(map->size(), static_cast<size_t>(length - newLength)));
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
unsigned index = static_cast<unsigned>(it->key);
@@ -408,9 +408,9 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
if (newLength >= MIN_SPARSE_ARRAY_INDEX) {
return setLengthWithArrayStorage(
exec, newLength, throwException,
- convertContiguousToArrayStorage(exec->globalData()));
+ convertContiguousToArrayStorage(exec->vm()));
}
- createInitialUndecided(exec->globalData(), newLength);
+ createInitialUndecided(exec->vm(), newLength);
return true;
case ArrayWithUndecided:
@@ -424,10 +424,10 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
&& !isDenseEnoughForVector(newLength, countElements()))) {
return setLengthWithArrayStorage(
exec, newLength, throwException,
- ensureArrayStorage(exec->globalData()));
+ ensureArrayStorage(exec->vm()));
}
if (newLength > m_butterfly->publicLength()) {
- ensureLength(exec->globalData(), newLength);
+ ensureLength(exec->vm(), newLength);
return true;
}
if (structure()->indexingType() == ArrayWithDouble) {
@@ -469,7 +469,7 @@ JSValue JSArray::pop(ExecState* exec)
if (!length--)
return jsUndefined();
- ASSERT(length < m_butterfly->vectorLength());
+ RELEASE_ASSERT(length < m_butterfly->vectorLength());
JSValue value = m_butterfly->contiguous()[length].get();
if (value) {
m_butterfly->contiguous()[length].clear();
@@ -485,7 +485,7 @@ JSValue JSArray::pop(ExecState* exec)
if (!length--)
return jsUndefined();
- ASSERT(length < m_butterfly->vectorLength());
+ RELEASE_ASSERT(length < m_butterfly->vectorLength());
double value = m_butterfly->contiguousDouble()[length];
if (value == value) {
m_butterfly->contiguousDouble()[length] = QNaN;
@@ -513,7 +513,7 @@ JSValue JSArray::pop(ExecState* exec)
JSValue element = valueSlot.get();
valueSlot.clear();
- ASSERT(isLengthWritable());
+ RELEASE_ASSERT(isLengthWritable());
storage->setLength(index);
return element;
}
@@ -549,19 +549,19 @@ void JSArray::push(ExecState* exec, JSValue value)
{
switch (structure()->indexingType()) {
case ArrayClass: {
- createInitialUndecided(exec->globalData(), 0);
+ createInitialUndecided(exec->vm(), 0);
// Fall through.
}
case ArrayWithUndecided: {
- convertUndecidedForValue(exec->globalData(), value);
+ convertUndecidedForValue(exec->vm(), value);
push(exec, value);
return;
}
case ArrayWithInt32: {
if (!value.isInt32()) {
- convertInt32ForValue(exec->globalData(), value);
+ convertInt32ForValue(exec->vm(), value);
push(exec, value);
return;
}
@@ -589,7 +589,7 @@ void JSArray::push(ExecState* exec, JSValue value)
unsigned length = m_butterfly->publicLength();
ASSERT(length <= m_butterfly->vectorLength());
if (length < m_butterfly->vectorLength()) {
- m_butterfly->contiguous()[length].set(exec->globalData(), this, value);
+ m_butterfly->contiguous()[length].set(exec->vm(), this, value);
m_butterfly->setPublicLength(length + 1);
return;
}
@@ -607,13 +607,13 @@ void JSArray::push(ExecState* exec, JSValue value)
case ArrayWithDouble: {
if (!value.isNumber()) {
- convertDoubleToContiguous(exec->globalData());
+ convertDoubleToContiguous(exec->vm());
push(exec, value);
return;
}
double valueAsDouble = value.asNumber();
if (valueAsDouble != valueAsDouble) {
- convertDoubleToContiguous(exec->globalData());
+ convertDoubleToContiguous(exec->vm());
push(exec, value);
return;
}
@@ -653,7 +653,7 @@ void JSArray::push(ExecState* exec, JSValue value)
// Fast case - push within vector, always update m_length & m_numValuesInVector.
unsigned length = storage->length();
if (length < storage->vectorLength()) {
- storage->m_vector[length].set(exec->globalData(), this, value);
+ storage->m_vector[length].set(exec->vm(), this, value);
storage->setLength(length + 1);
++storage->m_numValuesInVector;
return;
@@ -674,14 +674,14 @@ void JSArray::push(ExecState* exec, JSValue value)
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
bool JSArray::shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage* storage)
{
unsigned oldLength = storage->length();
- ASSERT(count <= oldLength);
+ RELEASE_ASSERT(count <= oldLength);
// If the array contains holes or is otherwise in an abnormal state,
// use the generic algorithm in ArrayPrototype.
@@ -736,7 +736,7 @@ bool JSArray::shiftCountWithArrayStorage(unsigned startIndex, unsigned count, Ar
bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex, unsigned count)
{
- ASSERT(count > 0);
+ RELEASE_ASSERT(count > 0);
switch (structure()->indexingType()) {
case ArrayClass:
@@ -749,12 +749,12 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
case ArrayWithInt32:
case ArrayWithContiguous: {
unsigned oldLength = m_butterfly->publicLength();
- ASSERT(count <= oldLength);
+ RELEASE_ASSERT(count <= oldLength);
// We may have to walk the entire array to do the shift. We're willing to do
// so only if it's not horribly slow.
if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX)
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->vm()));
unsigned end = oldLength - count;
for (unsigned i = startIndex; i < end; ++i) {
@@ -768,7 +768,7 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
// about holes (at least for now), but it can detect them quickly. So
// we convert to array storage and then allow the array storage path to
// figure it out.
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->vm()));
}
// No need for a barrier since we're just moving data around in the same vector.
// This is in line with our standing assumption that we won't have a deletion
@@ -784,12 +784,12 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
case ArrayWithDouble: {
unsigned oldLength = m_butterfly->publicLength();
- ASSERT(count <= oldLength);
+ RELEASE_ASSERT(count <= oldLength);
// We may have to walk the entire array to do the shift. We're willing to do
// so only if it's not horribly slow.
if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX)
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->vm()));
unsigned end = oldLength - count;
for (unsigned i = startIndex; i < end; ++i) {
@@ -803,7 +803,7 @@ bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex
// about holes (at least for now), but it can detect them quickly. So
// we convert to array storage and then allow the array storage path to
// figure it out.
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->vm()));
}
// No need for a barrier since we're just moving data around in the same vector.
// This is in line with our standing assumption that we won't have a deletion
@@ -832,7 +832,7 @@ bool JSArray::unshiftCountWithArrayStorage(ExecState* exec, unsigned startIndex,
{
unsigned length = storage->length();
- ASSERT(startIndex <= length);
+ RELEASE_ASSERT(startIndex <= length);
// If the array contains holes or is otherwise in an abnormal state,
// use the generic algorithm in ArrayPrototype.
@@ -850,7 +850,7 @@ bool JSArray::unshiftCountWithArrayStorage(ExecState* exec, unsigned startIndex,
storage->setVectorLength(vectorLength + count);
} else if (!moveFront && vectorLength - length >= count)
storage = storage->butterfly()->arrayStorage();
- else if (unshiftCountSlowCase(exec->globalData(), moveFront, count))
+ else if (unshiftCountSlowCase(exec->vm(), moveFront, count))
storage = arrayStorage();
else {
throwOutOfMemoryError(exec);
@@ -886,14 +886,14 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd
// We may have to walk the entire array to do the unshift. We're willing to do so
// only if it's not horribly slow.
if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
- ensureLength(exec->globalData(), oldLength + count);
+ ensureLength(exec->vm(), oldLength + count);
for (unsigned i = oldLength; i-- > startIndex;) {
JSValue v = m_butterfly->contiguous()[i].get();
if (UNLIKELY(!v))
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
m_butterfly->contiguous()[i + count].setWithoutWriteBarrier(v);
}
@@ -911,14 +911,14 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd
// We may have to walk the entire array to do the unshift. We're willing to do so
// only if it's not horribly slow.
if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
- ensureLength(exec->globalData(), oldLength + count);
+ ensureLength(exec->vm(), oldLength + count);
for (unsigned i = oldLength; i-- > startIndex;) {
double v = m_butterfly->contiguousDouble()[i];
if (UNLIKELY(v != v))
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
m_butterfly->contiguousDouble()[i + count] = v;
}
@@ -979,7 +979,7 @@ void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallTy
lengthNotIncludingUndefined,
newRelevantLength);
- WriteBarrier<Unknown>* data = indexingData<indexingType>();
+ ContiguousJSValues data = indexingData<indexingType>();
if (indexingType == ArrayWithArrayStorage && arrayStorage()->m_sparseMap.get()) {
throwOutOfMemoryError(exec);
@@ -1026,8 +1026,8 @@ void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallTy
compare = compareNumbersForQSort;
break;
}
-
- qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compare);
+ ASSERT(data.length() >= newRelevantLength);
+ qsort(data.data(), newRelevantLength, sizeof(WriteBarrier<Unknown>), compare);
return;
}
@@ -1061,20 +1061,47 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
}
}
-template<IndexingType indexingType>
-void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevantLength)
+template <IndexingType> struct ContiguousTypeAccessor {
+ typedef WriteBarrier<Unknown> Type;
+ static JSValue getAsValue(ContiguousData<Type> data, size_t i) { return data[i].get(); }
+ static void setWithValue(VM& vm, JSArray* thisValue, ContiguousData<Type> data, size_t i, JSValue value)
+ {
+ data[i].set(vm, thisValue, value);
+ }
+ static void replaceDataReference(ContiguousData<Type>* outData, ContiguousJSValues inData)
+ {
+ *outData = inData;
+ }
+};
+
+template <> struct ContiguousTypeAccessor<ArrayWithDouble> {
+ typedef double Type;
+ static JSValue getAsValue(ContiguousData<Type> data, size_t i) { ASSERT(data[i] == data[i]); return JSValue(JSValue::EncodeAsDouble, data[i]); }
+ static void setWithValue(VM&, JSArray*, ContiguousData<Type> data, size_t i, JSValue value)
+ {
+ data[i] = value.asNumber();
+ }
+ static NO_RETURN_DUE_TO_CRASH void replaceDataReference(ContiguousData<Type>*, ContiguousJSValues)
+ {
+ RELEASE_ASSERT_WITH_MESSAGE(0, "Inconsistent indexing types during compact array sort.");
+ }
+};
+
+
+template<IndexingType indexingType, typename StorageType>
+void JSArray::sortCompactedVector(ExecState* exec, ContiguousData<StorageType> data, unsigned relevantLength)
{
if (!relevantLength)
return;
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.
// This is a considerable improvement over doing it twice per comparison, though it requires a large temporary
// buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
// random or otherwise changing results, effectively making compare function inconsistent.
- Vector<ValueStringPair> values(relevantLength);
+ Vector<ValueStringPair, 0, UnsafeVectorOverflow> values(relevantLength);
if (!values.begin()) {
throwOutOfMemoryError(exec);
return;
@@ -1083,31 +1110,14 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan
Heap::heap(this)->pushTempSortVector(&values);
bool isSortingPrimitiveValues = true;
- switch (indexingType) {
- case ArrayWithInt32:
- for (size_t i = 0; i < relevantLength; i++) {
- JSValue value = static_cast<WriteBarrier<Unknown>*>(begin)[i].get();
- ASSERT(value.isInt32());
- values[i].first = value;
- }
- break;
-
- case ArrayWithDouble:
- for (size_t i = 0; i < relevantLength; i++) {
- double value = static_cast<double*>(begin)[i];
- ASSERT(value == value);
- values[i].first = JSValue(JSValue::EncodeAsDouble, value);
- }
- break;
-
- default:
- for (size_t i = 0; i < relevantLength; i++) {
- JSValue value = static_cast<WriteBarrier<Unknown>*>(begin)[i].get();
- ASSERT(!value.isUndefined());
- values[i].first = value;
+
+ for (size_t i = 0; i < relevantLength; i++) {
+ JSValue value = ContiguousTypeAccessor<indexingType>::getAsValue(data, i);
+ ASSERT(indexingType != ArrayWithInt32 || value.isInt32());
+ ASSERT(!value.isUndefined());
+ values[i].first = value;
+ if (indexingType != ArrayWithDouble && indexingType != ArrayWithInt32)
isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive();
- }
- break;
}
// FIXME: The following loop continues to call toString on subsequent values even after
@@ -1141,13 +1151,13 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan
case ArrayWithInt32:
case ArrayWithDouble:
case ArrayWithContiguous:
- ensureLength(globalData, relevantLength);
+ ensureLength(vm, relevantLength);
break;
case ArrayWithArrayStorage:
if (arrayStorage()->vectorLength() < relevantLength) {
- increaseVectorLength(exec->globalData(), relevantLength);
- begin = arrayStorage()->m_vector;
+ increaseVectorLength(exec->vm(), relevantLength);
+ ContiguousTypeAccessor<indexingType>::replaceDataReference(&data, arrayStorage()->vector());
}
if (arrayStorage()->length() < relevantLength)
arrayStorage()->setLength(relevantLength);
@@ -1157,12 +1167,8 @@ void JSArray::sortCompactedVector(ExecState* exec, void* begin, unsigned relevan
CRASH();
}
- for (size_t i = 0; i < relevantLength; i++) {
- if (indexingType == ArrayWithDouble)
- static_cast<double*>(begin)[i] = values[i].first.asNumber();
- else
- static_cast<WriteBarrier<Unknown>*>(begin)[i].set(globalData, this, values[i].first);
- }
+ for (size_t i = 0; i < relevantLength; i++)
+ ContiguousTypeAccessor<indexingType>::setWithValue(vm, this, data, i, values[i].first);
Heap::heap(this)->popTempSortVector(&values);
}
@@ -1217,13 +1223,12 @@ void JSArray::sort(ExecState* exec)
ArrayStorage* storage = m_butterfly->arrayStorage();
ASSERT(!storage->m_sparseMap);
- sortCompactedVector<ArrayWithArrayStorage>(
- exec, storage->m_vector, lengthNotIncludingUndefined);
+ sortCompactedVector<ArrayWithArrayStorage>(exec, storage->vector(), lengthNotIncludingUndefined);
return;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -1242,7 +1247,7 @@ struct AVLTreeAbstractorForArrayCompare {
typedef JSValue key;
typedef int32_t size;
- Vector<AVLTreeNodeForArrayCompare> m_nodes;
+ Vector<AVLTreeNodeForArrayCompare, 0, UnsafeVectorOverflow> m_nodes;
ExecState* m_exec;
JSValue m_compareFunction;
CallType m_compareCallType;
@@ -1382,13 +1387,13 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
// Copy the values back into m_storage.
AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
iter.start_iter_least(tree);
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
for (unsigned i = 0; i < elementsToExtractThreshold; ++i) {
ASSERT(i < butterfly()->vectorLength());
if (structure()->indexingType() == ArrayWithDouble)
butterfly()->contiguousDouble()[i] = tree.abstractor().m_nodes[*iter].value.asNumber();
else
- currentIndexingData()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
+ currentIndexingData()[i].set(vm, this, tree.abstractor().m_nodes[*iter].value);
++iter;
}
// Put undefined values back in.
@@ -1444,7 +1449,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
return;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -1467,7 +1472,7 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
case ArrayWithInt32:
case ArrayWithContiguous: {
vectorEnd = m_butterfly->publicLength();
- vector = m_butterfly->contiguous();
+ vector = m_butterfly->contiguous().data();
break;
}
@@ -1528,7 +1533,7 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t le
case ArrayWithInt32:
case ArrayWithContiguous: {
- vector = m_butterfly->contiguous();
+ vector = m_butterfly->contiguous().data();
vectorEnd = m_butterfly->publicLength();
break;
}
@@ -1635,12 +1640,12 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
newRelevantLength = numDefined + numUndefined;
if (hasArrayStorage(indexingType))
- ASSERT(!arrayStorage()->m_sparseMap);
+ RELEASE_ASSERT(!arrayStorage()->m_sparseMap);
switch (indexingType) {
case ArrayWithInt32:
case ArrayWithDouble:
- ASSERT(numDefined == newRelevantLength);
+ RELEASE_ASSERT(numDefined == newRelevantLength);
break;
default:
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index cef3b53ad..af81d2e3f 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -39,19 +39,19 @@ public:
typedef JSNonFinalObject Base;
protected:
- explicit JSArray(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly)
- : JSNonFinalObject(globalData, structure, butterfly)
+ explicit JSArray(VM& vm, Structure* structure, Butterfly* butterfly)
+ : JSNonFinalObject(vm, structure, butterfly)
{
}
public:
- static JSArray* create(JSGlobalData&, Structure*, unsigned initialLength = 0);
+ static JSArray* create(VM&, Structure*, unsigned initialLength = 0);
// tryCreateUninitialized is used for fast construction of arrays whose size and
// contents are known at time of creation. Clients of this interface must:
// - null-check the result (indicating out of memory, or otherwise unable to allocate vector).
// - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength.
- static JSArray* tryCreateUninitialized(JSGlobalData&, Structure*, unsigned initialLength);
+ static JSArray* tryCreateUninitialized(VM&, Structure*, unsigned initialLength);
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
@@ -84,7 +84,7 @@ public:
bool shiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
{
- return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->vm()));
}
bool shiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
{
@@ -106,7 +106,7 @@ public:
bool unshiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
{
- return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
}
bool unshiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
{
@@ -129,9 +129,9 @@ public:
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToArguments(ExecState*, CallFrame*, uint32_t length);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, indexingType);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, indexingType);
}
protected:
@@ -156,13 +156,13 @@ private:
bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*);
- bool unshiftCountSlowCase(JSGlobalData&, bool, unsigned);
+ bool unshiftCountSlowCase(VM&, bool, unsigned);
template<IndexingType indexingType>
void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
- template<IndexingType indexingType>
- void sortCompactedVector(ExecState*, void* begin, unsigned relevantLength);
+ template<IndexingType indexingType, typename StorageType>
+ void sortCompactedVector(ExecState*, ContiguousData<StorageType>, unsigned relevantLength);
template<IndexingType indexingType>
void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
@@ -174,21 +174,21 @@ private:
void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength);
};
-inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length, unsigned& vectorLength)
+inline Butterfly* createContiguousArrayButterfly(VM& vm, unsigned length, unsigned& vectorLength)
{
IndexingHeader header;
vectorLength = std::max(length, BASE_VECTOR_LEN);
header.setVectorLength(vectorLength);
header.setPublicLength(length);
Butterfly* result = Butterfly::create(
- globalData, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue));
+ vm, 0, 0, true, header, vectorLength * sizeof(EncodedJSValue));
return result;
}
-inline Butterfly* createArrayButterfly(JSGlobalData& globalData, unsigned initialLength)
+inline Butterfly* createArrayButterfly(VM& vm, unsigned initialLength)
{
Butterfly* butterfly = Butterfly::create(
- globalData, 0, 0, true, baseIndexingHeaderForArray(initialLength), ArrayStorage::sizeFor(BASE_VECTOR_LEN));
+ vm, 0, 0, true, baseIndexingHeaderForArray(initialLength), ArrayStorage::sizeFor(BASE_VECTOR_LEN));
ArrayStorage* storage = butterfly->arrayStorage();
storage->m_indexBias = 0;
storage->m_sparseMap.clear();
@@ -196,9 +196,9 @@ inline Butterfly* createArrayButterfly(JSGlobalData& globalData, unsigned initia
return butterfly;
}
-Butterfly* createArrayButterflyInDictionaryIndexingMode(JSGlobalData&, unsigned initialLength);
+Butterfly* createArrayButterflyInDictionaryIndexingMode(VM&, unsigned initialLength);
-inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength)
+inline JSArray* JSArray::create(VM& vm, Structure* structure, unsigned initialLength)
{
Butterfly* butterfly;
if (LIKELY(!hasArrayStorage(structure->indexingType()))) {
@@ -208,7 +208,7 @@ inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure,
|| hasDouble(structure->indexingType())
|| hasContiguous(structure->indexingType()));
unsigned vectorLength;
- butterfly = createContiguousArrayButterfly(globalData, initialLength, vectorLength);
+ butterfly = createContiguousArrayButterfly(vm, initialLength, vectorLength);
ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX);
if (hasDouble(structure->indexingType())) {
for (unsigned i = 0; i < vectorLength; ++i)
@@ -218,14 +218,14 @@ inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure,
ASSERT(
structure->indexingType() == ArrayWithSlowPutArrayStorage
|| structure->indexingType() == ArrayWithArrayStorage);
- butterfly = createArrayButterfly(globalData, initialLength);
+ butterfly = createArrayButterfly(vm, initialLength);
}
- JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
- array->finishCreation(globalData);
+ JSArray* array = new (NotNull, allocateCell<JSArray>(vm.heap)) JSArray(vm, structure, butterfly);
+ array->finishCreation(vm);
return array;
}
-inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Structure* structure, unsigned initialLength)
+inline JSArray* JSArray::tryCreateUninitialized(VM& vm, Structure* structure, unsigned initialLength)
{
unsigned vectorLength = std::max(BASE_VECTOR_LEN, initialLength);
if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
@@ -240,7 +240,7 @@ inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Struct
|| hasContiguous(structure->indexingType()));
void* temp;
- if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
+ if (!vm.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
return 0;
butterfly = Butterfly::fromBase(temp, 0, 0);
butterfly->setVectorLength(vectorLength);
@@ -251,7 +251,7 @@ inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Struct
}
} else {
void* temp;
- if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
+ if (!vm.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
return 0;
butterfly = Butterfly::fromBase(temp, 0, 0);
*butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength);
@@ -261,8 +261,8 @@ inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Struct
storage->m_numValuesInVector = initialLength;
}
- JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
- array->finishCreation(globalData);
+ JSArray* array = new (NotNull, allocateCell<JSArray>(vm.heap)) JSArray(vm, structure, butterfly);
+ array->finishCreation(vm);
return array;
}
@@ -284,34 +284,32 @@ inline bool isJSArray(JSValue v) { return v.isCell() && isJSArray(v.asCell()); }
inline JSArray* constructArray(ExecState* exec, Structure* arrayStructure, const ArgList& values)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
unsigned length = values.size();
- JSArray* array = JSArray::tryCreateUninitialized(globalData, arrayStructure, length);
+ JSArray* array = JSArray::tryCreateUninitialized(vm, arrayStructure, length);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
// function will correctly handle an exception being thrown from here.
- if (!array)
- CRASH();
+ RELEASE_ASSERT(array);
for (unsigned i = 0; i < length; ++i)
- array->initializeIndex(globalData, i, values.at(i));
+ array->initializeIndex(vm, i, values.at(i));
return array;
}
inline JSArray* constructArray(ExecState* exec, Structure* arrayStructure, const JSValue* values, unsigned length)
{
- JSGlobalData& globalData = exec->globalData();
- JSArray* array = JSArray::tryCreateUninitialized(globalData, arrayStructure, length);
+ VM& vm = exec->vm();
+ JSArray* array = JSArray::tryCreateUninitialized(vm, arrayStructure, length);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
// function will correctly handle an exception being thrown from here.
- if (!array)
- CRASH();
+ RELEASE_ASSERT(array);
for (unsigned i = 0; i < length; ++i)
- array->initializeIndex(globalData, i, values[i]);
+ array->initializeIndex(vm, i, values[i]);
return array;
}
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
index bb1af9d20..fb255d954 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
@@ -28,6 +28,7 @@
#include "GetterSetter.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
namespace JSC {
@@ -78,8 +79,7 @@ JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* global
ConstructData constructData;
ConstructType constructType = JSC::getConstructData(targetFunction, constructData);
bool canConstruct = constructType != ConstructTypeNone;
-
- NativeExecutable* executable = exec->globalData().getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor);
+ NativeExecutable* executable = exec->vm().getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor);
JSBoundFunction* function = new (NotNull, allocateCell<JSBoundFunction>(*exec->heap())) JSBoundFunction(exec, globalObject, globalObject->boundFunctionStructure(), targetFunction, boundThis, boundArgs);
function->finishCreation(exec, executable, length, name);
@@ -98,9 +98,9 @@ bool JSBoundFunction::customHasInstance(JSObject* object, ExecState* exec, JSVal
JSBoundFunction::JSBoundFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs)
: Base(exec, globalObject, structure)
- , m_targetFunction(exec->globalData(), this, targetFunction)
- , m_boundThis(exec->globalData(), this, boundThis)
- , m_boundArgs(exec->globalData(), this, boundArgs)
+ , m_targetFunction(exec->vm(), this, targetFunction)
+ , m_boundThis(exec->vm(), this, boundThis)
+ , m_boundArgs(exec->vm(), this, boundArgs)
{
}
diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.h b/Source/JavaScriptCore/runtime/JSBoundFunction.h
index 886021940..3378d4048 100644
--- a/Source/JavaScriptCore/runtime/JSBoundFunction.h
+++ b/Source/JavaScriptCore/runtime/JSBoundFunction.h
@@ -47,10 +47,10 @@ public:
JSValue boundThis() { return m_boundThis.get(); }
JSValue boundArgs() { return m_boundArgs.get(); }
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
ASSERT(globalObject);
- return Structure::create(globalData, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSCJSValue.cpp
index d9253730f..627e9e077 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSCJSValue.cpp
@@ -21,15 +21,16 @@
*/
#include "config.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "BooleanConstructor.h"
#include "BooleanPrototype.h"
#include "Error.h"
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
-#include "JSGlobalObject.h"
+#include "JSCJSValueInlines.h"
#include "JSFunction.h"
+#include "JSGlobalObject.h"
#include "JSNotAnObject.h"
#include "NumberObject.h"
#include <wtf/MathExtras.h>
@@ -45,7 +46,7 @@ double JSValue::toInteger(ExecState* exec) const
if (isInt32())
return asInt32();
double d = toNumber(exec);
- return isnan(d) ? 0.0 : trunc(d);
+ return std::isnan(d) ? 0.0 : trunc(d);
}
double JSValue::toIntegerPreserveNaN(ExecState* exec) const
@@ -111,7 +112,7 @@ JSObject* JSValue::synthesizePrototype(ExecState* exec) const
// ECMA 8.7.2
void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
unsigned index = propertyName.asIndex();
if (index != PropertyName::NotAnIndex) {
@@ -136,7 +137,7 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
for (; ; obj = asObject(prototype)) {
unsigned attributes;
JSCell* specificValue;
- PropertyOffset offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
+ PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes, specificValue);
if (offset != invalidOffset) {
if (attributes & ReadOnly) {
if (slot.isStrictMode())
@@ -144,7 +145,7 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
return;
}
- JSValue gs = obj->getDirectOffset(offset);
+ JSValue gs = obj->getDirect(offset);
if (gs.isGetterSetter()) {
JSObject* setterFunc = asGetterSetter(gs)->setter();
if (!setterFunc) {
@@ -193,51 +194,53 @@ void JSValue::putToPrimitiveByIndex(ExecState* exec, unsigned propertyName, JSVa
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
-char* JSValue::description() const
+void JSValue::dump(PrintStream& out) const
{
- static const size_t size = 256;
- static char description[size];
-
if (!*this)
- snprintf(description, size, "<JSValue()>");
+ out.print("<JSValue()>");
else if (isInt32())
- snprintf(description, size, "Int32: %d", asInt32());
+ out.printf("Int32: %d", asInt32());
else if (isDouble()) {
#if USE(JSVALUE64)
- snprintf(description, size, "Double: %lld, %lf", (long long)reinterpretDoubleToInt64(asDouble()), asDouble());
+ out.printf("Double: %lld, %lf", (long long)reinterpretDoubleToInt64(asDouble()), asDouble());
#else
union {
double asDouble;
uint32_t asTwoInt32s[2];
} u;
u.asDouble = asDouble();
- snprintf(description, size, "Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
+ out.printf("Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble());
#endif
} else if (isCell()) {
- if (asCell()->inherits(&Structure::s_info)) {
+ if (asCell()->inherits(&JSString::s_info)) {
+ JSString* string = jsCast<JSString*>(asCell());
+ out.print("String: ");
+ if (string->isRope())
+ out.print("(rope) ");
+ out.print(string->tryGetValue());
+ } else if (asCell()->inherits(&Structure::s_info)) {
Structure* structure = jsCast<Structure*>(asCell());
- snprintf(
- description, size, "Structure: %p: %s, %s",
- structure, structure->classInfo()->className,
- indexingTypeToString(structure->indexingTypeIncludingHistory()));
+ out.print(
+ "Structure: ", RawPointer(structure), ": ", structure->classInfo()->className,
+ ", ", IndexingTypeDump(structure->indexingTypeIncludingHistory()));
} else {
- snprintf(
- description, size, "Cell: %p -> %p (%p: %s, %s)",
- asCell(), isObject() ? asObject(*this)->butterfly() : 0, asCell()->structure(), asCell()->structure()->classInfo()->className,
- indexingTypeToString(asCell()->structure()->indexingTypeIncludingHistory()));
+ out.print("Cell: ", RawPointer(asCell()));
+ if (isObject() && asObject(*this)->butterfly())
+ out.print("->", RawPointer(asObject(*this)->butterfly()));
+ out.print(
+ " (", RawPointer(asCell()->structure()), ": ", asCell()->structure()->classInfo()->className,
+ ", ", IndexingTypeDump(asCell()->structure()->indexingTypeIncludingHistory()), ")");
}
} else if (isTrue())
- snprintf(description, size, "True");
+ out.print("True");
else if (isFalse())
- snprintf(description, size, "False");
+ out.print("False");
else if (isNull())
- snprintf(description, size, "Null");
+ out.print("Null");
else if (isUndefined())
- snprintf(description, size, "Undefined");
+ out.print("Undefined");
else
- snprintf(description, size, "INVALID");
-
- return description;
+ out.print("INVALID");
}
// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
@@ -292,20 +295,20 @@ bool JSValue::isValidCallee()
JSString* JSValue::toStringSlowCase(ExecState* exec) const
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
ASSERT(!isString());
if (isInt32())
- return jsString(&globalData, globalData.numericStrings.add(asInt32()));
+ return jsString(&vm, vm.numericStrings.add(asInt32()));
if (isDouble())
- return jsString(&globalData, globalData.numericStrings.add(asDouble()));
+ return jsString(&vm, vm.numericStrings.add(asDouble()));
if (isTrue())
- return globalData.smallStrings.trueString(&globalData);
+ return vm.smallStrings.trueString();
if (isFalse())
- return globalData.smallStrings.falseString(&globalData);
+ return vm.smallStrings.falseString();
if (isNull())
- return globalData.smallStrings.nullString(&globalData);
+ return vm.smallStrings.nullString();
if (isUndefined())
- return globalData.smallStrings.undefinedString(&globalData);
+ return vm.smallStrings.undefinedString();
ASSERT(isCell());
JSValue value = asCell()->toPrimitive(exec, PreferString);
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSCJSValue.h
index f6447d0bd..abb4b8109 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSCJSValue.h
@@ -20,18 +20,19 @@
*
*/
-#ifndef JSValue_h
-#define JSValue_h
+#ifndef JSCJSValue_h
+#define JSCJSValue_h
#include <math.h>
#include <stddef.h> // for size_t
#include <stdint.h>
-#include <wtf/AlwaysInline.h>
#include <wtf/Assertions.h>
+#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/HashTraits.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/TriState.h>
namespace JSC {
@@ -41,7 +42,7 @@ namespace JSC {
class ExecState;
class JSCell;
-class JSGlobalData;
+class VM;
class JSGlobalObject;
class JSObject;
class JSString;
@@ -213,6 +214,7 @@ public:
bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
bool toBoolean(ExecState*) const;
+ TriState pureToBoolean() const;
// toNumber conversion is expected to be side effect free if an exception has
// been set in the ExecState already.
@@ -245,12 +247,12 @@ public:
JSObject* toThisObject(ExecState*) const;
- static bool equal(ExecState* exec, JSValue v1, JSValue v2);
- static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
- static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
- static bool strictEqual(ExecState* exec, JSValue v1, JSValue v2);
- static bool strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2);
- static bool strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
+ static bool equal(ExecState*, JSValue v1, JSValue v2);
+ static bool equalSlowCase(ExecState*, JSValue v1, JSValue v2);
+ static bool equalSlowCaseInline(ExecState*, JSValue v1, JSValue v2);
+ static bool strictEqual(ExecState*, JSValue v1, JSValue v2);
+ static bool strictEqualSlowCase(ExecState*, JSValue v1, JSValue v2);
+ static bool strictEqualSlowCaseInline(ExecState*, JSValue v1, JSValue v2);
bool isCell() const;
JSCell* asCell() const;
@@ -258,7 +260,7 @@ public:
JSValue structureOrUndefined() const;
- JS_EXPORT_PRIVATE char* description() const;
+ JS_EXPORT_PRIVATE void dump(PrintStream&) const;
JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
@@ -494,4 +496,4 @@ inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) !=
} // namespace JSC
-#endif // JSValue_h
+#endif // JSCJSValue_h
diff --git a/Source/JavaScriptCore/runtime/JSCJSValueInlines.h b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h
new file mode 100644
index 000000000..e22fe244f
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h
@@ -0,0 +1,810 @@
+/*
+ * 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. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 JSValueInlines_h
+#define JSValueInlines_h
+
+#include "InternalFunction.h"
+#include "JSCJSValue.h"
+#include "JSCellInlines.h"
+#include "JSFunction.h"
+
+namespace JSC {
+
+ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
+{
+ if (isInt32())
+ return asInt32();
+ return JSC::toInt32(toNumber(exec));
+}
+
+inline uint32_t JSValue::toUInt32(ExecState* exec) const
+{
+ // See comment on JSC::toUInt32, above.
+ return toInt32(exec);
+}
+
+inline bool JSValue::isUInt32() const
+{
+ return isInt32() && asInt32() >= 0;
+}
+
+inline uint32_t JSValue::asUInt32() const
+{
+ ASSERT(isUInt32());
+ return asInt32();
+}
+
+inline double JSValue::asNumber() const
+{
+ ASSERT(isNumber());
+ return isInt32() ? asInt32() : asDouble();
+}
+
+inline JSValue jsNaN()
+{
+ return JSValue(QNaN);
+}
+
+inline JSValue::JSValue(char i)
+{
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(unsigned char i)
+{
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(short i)
+{
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(unsigned short i)
+{
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(unsigned i)
+{
+ if (static_cast<int32_t>(i) < 0) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(long i)
+{
+ if (static_cast<int32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(unsigned long i)
+{
+ if (static_cast<uint32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<uint32_t>(i));
+}
+
+inline JSValue::JSValue(long long i)
+{
+ if (static_cast<int32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(i));
+}
+
+inline JSValue::JSValue(unsigned long long i)
+{
+ if (static_cast<uint32_t>(i) != i) {
+ *this = JSValue(EncodeAsDouble, static_cast<double>(i));
+ return;
+ }
+ *this = JSValue(static_cast<uint32_t>(i));
+}
+
+inline JSValue::JSValue(double d)
+{
+ const int32_t asInt32 = static_cast<int32_t>(d);
+ if (asInt32 != d || (!asInt32 && std::signbit(d))) { // true for -0.0
+ *this = JSValue(EncodeAsDouble, d);
+ return;
+ }
+ *this = JSValue(static_cast<int32_t>(d));
+}
+
+inline EncodedJSValue JSValue::encode(JSValue value)
+{
+ return value.u.asInt64;
+}
+
+inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
+{
+ JSValue v;
+ v.u.asInt64 = encodedJSValue;
+ return v;
+}
+
+#if USE(JSVALUE32_64)
+inline JSValue::JSValue()
+{
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = 0;
+}
+
+inline JSValue::JSValue(JSNullTag)
+{
+ u.asBits.tag = NullTag;
+ u.asBits.payload = 0;
+}
+
+inline JSValue::JSValue(JSUndefinedTag)
+{
+ u.asBits.tag = UndefinedTag;
+ u.asBits.payload = 0;
+}
+
+inline JSValue::JSValue(JSTrueTag)
+{
+ u.asBits.tag = BooleanTag;
+ u.asBits.payload = 1;
+}
+
+inline JSValue::JSValue(JSFalseTag)
+{
+ u.asBits.tag = BooleanTag;
+ u.asBits.payload = 0;
+}
+
+inline JSValue::JSValue(HashTableDeletedValueTag)
+{
+ u.asBits.tag = DeletedValueTag;
+ u.asBits.payload = 0;
+}
+
+inline JSValue::JSValue(JSCell* ptr)
+{
+ if (ptr)
+ u.asBits.tag = CellTag;
+ else
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = reinterpret_cast<int32_t>(ptr);
+}
+
+inline JSValue::JSValue(const JSCell* ptr)
+{
+ if (ptr)
+ u.asBits.tag = CellTag;
+ else
+ u.asBits.tag = EmptyValueTag;
+ u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
+}
+
+inline JSValue::operator bool() const
+{
+ ASSERT(tag() != DeletedValueTag);
+ return tag() != EmptyValueTag;
+}
+
+inline bool JSValue::operator==(const JSValue& other) const
+{
+ return u.asInt64 == other.u.asInt64;
+}
+
+inline bool JSValue::operator!=(const JSValue& other) const
+{
+ return u.asInt64 != other.u.asInt64;
+}
+
+inline bool JSValue::isEmpty() const
+{
+ return tag() == EmptyValueTag;
+}
+
+inline bool JSValue::isUndefined() const
+{
+ return tag() == UndefinedTag;
+}
+
+inline bool JSValue::isNull() const
+{
+ return tag() == NullTag;
+}
+
+inline bool JSValue::isUndefinedOrNull() const
+{
+ return isUndefined() || isNull();
+}
+
+inline bool JSValue::isCell() const
+{
+ return tag() == CellTag;
+}
+
+inline bool JSValue::isInt32() const
+{
+ return tag() == Int32Tag;
+}
+
+inline bool JSValue::isDouble() const
+{
+ return tag() < LowestTag;
+}
+
+inline bool JSValue::isTrue() const
+{
+ return tag() == BooleanTag && payload();
+}
+
+inline bool JSValue::isFalse() const
+{
+ return tag() == BooleanTag && !payload();
+}
+
+inline uint32_t JSValue::tag() const
+{
+ return u.asBits.tag;
+}
+
+inline int32_t JSValue::payload() const
+{
+ return u.asBits.payload;
+}
+
+inline int32_t JSValue::asInt32() const
+{
+ ASSERT(isInt32());
+ return u.asBits.payload;
+}
+
+inline double JSValue::asDouble() const
+{
+ ASSERT(isDouble());
+ return u.asDouble;
+}
+
+ALWAYS_INLINE JSCell* JSValue::asCell() const
+{
+ ASSERT(isCell());
+ return reinterpret_cast<JSCell*>(u.asBits.payload);
+}
+
+ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
+{
+ u.asDouble = d;
+}
+
+inline JSValue::JSValue(int i)
+{
+ u.asBits.tag = Int32Tag;
+ u.asBits.payload = i;
+}
+
+#if ENABLE(LLINT_C_LOOP)
+inline JSValue::JSValue(int32_t tag, int32_t payload)
+{
+ u.asBits.tag = tag;
+ u.asBits.payload = payload;
+}
+#endif
+
+inline bool JSValue::isNumber() const
+{
+ return isInt32() || isDouble();
+}
+
+inline bool JSValue::isBoolean() const
+{
+ return isTrue() || isFalse();
+}
+
+inline bool JSValue::asBoolean() const
+{
+ ASSERT(isBoolean());
+ return payload();
+}
+
+#else // !USE(JSVALUE32_64) i.e. USE(JSVALUE64)
+
+// 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
+inline JSValue::JSValue()
+{
+ u.asInt64 = ValueEmpty;
+}
+
+// 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
+inline JSValue::JSValue(HashTableDeletedValueTag)
+{
+ u.asInt64 = ValueDeleted;
+}
+
+inline JSValue::JSValue(JSCell* ptr)
+{
+ u.asInt64 = reinterpret_cast<uintptr_t>(ptr);
+}
+
+inline JSValue::JSValue(const JSCell* ptr)
+{
+ u.asInt64 = reinterpret_cast<uintptr_t>(const_cast<JSCell*>(ptr));
+}
+
+inline JSValue::operator bool() const
+{
+ return u.asInt64;
+}
+
+inline bool JSValue::operator==(const JSValue& other) const
+{
+ return u.asInt64 == other.u.asInt64;
+}
+
+inline bool JSValue::operator!=(const JSValue& other) const
+{
+ return u.asInt64 != other.u.asInt64;
+}
+
+inline bool JSValue::isEmpty() const
+{
+ return u.asInt64 == ValueEmpty;
+}
+
+inline bool JSValue::isUndefined() const
+{
+ return asValue() == JSValue(JSUndefined);
+}
+
+inline bool JSValue::isNull() const
+{
+ return asValue() == JSValue(JSNull);
+}
+
+inline bool JSValue::isTrue() const
+{
+ return asValue() == JSValue(JSTrue);
+}
+
+inline bool JSValue::isFalse() const
+{
+ return asValue() == JSValue(JSFalse);
+}
+
+inline bool JSValue::asBoolean() const
+{
+ ASSERT(isBoolean());
+ return asValue() == JSValue(JSTrue);
+}
+
+inline int32_t JSValue::asInt32() const
+{
+ ASSERT(isInt32());
+ return static_cast<int32_t>(u.asInt64);
+}
+
+inline bool JSValue::isDouble() const
+{
+ return isNumber() && !isInt32();
+}
+
+inline JSValue::JSValue(JSNullTag)
+{
+ u.asInt64 = ValueNull;
+}
+
+inline JSValue::JSValue(JSUndefinedTag)
+{
+ u.asInt64 = ValueUndefined;
+}
+
+inline JSValue::JSValue(JSTrueTag)
+{
+ u.asInt64 = ValueTrue;
+}
+
+inline JSValue::JSValue(JSFalseTag)
+{
+ u.asInt64 = ValueFalse;
+}
+
+inline bool JSValue::isUndefinedOrNull() const
+{
+ // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
+ return (u.asInt64 & ~TagBitUndefined) == ValueNull;
+}
+
+inline bool JSValue::isBoolean() const
+{
+ return (u.asInt64 & ~1) == ValueFalse;
+}
+
+inline bool JSValue::isCell() const
+{
+ return !(u.asInt64 & TagMask);
+}
+
+inline bool JSValue::isInt32() const
+{
+ return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
+}
+
+inline int64_t reinterpretDoubleToInt64(double value)
+{
+ return bitwise_cast<int64_t>(value);
+}
+inline double reinterpretInt64ToDouble(int64_t value)
+{
+ return bitwise_cast<double>(value);
+}
+
+ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
+{
+ u.asInt64 = reinterpretDoubleToInt64(d) + DoubleEncodeOffset;
+}
+
+inline JSValue::JSValue(int i)
+{
+ u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
+}
+
+inline double JSValue::asDouble() const
+{
+ ASSERT(isDouble());
+ return reinterpretInt64ToDouble(u.asInt64 - DoubleEncodeOffset);
+}
+
+inline bool JSValue::isNumber() const
+{
+ return u.asInt64 & TagTypeNumber;
+}
+
+ALWAYS_INLINE JSCell* JSValue::asCell() const
+{
+ ASSERT(isCell());
+ return u.ptr;
+}
+
+#endif // USE(JSVALUE64)
+
+inline bool JSValue::isString() const
+{
+ return isCell() && asCell()->isString();
+}
+
+inline bool JSValue::isPrimitive() const
+{
+ return !isCell() || asCell()->isString();
+}
+
+inline bool JSValue::isGetterSetter() const
+{
+ return isCell() && asCell()->isGetterSetter();
+}
+
+inline bool JSValue::isObject() const
+{
+ return isCell() && asCell()->isObject();
+}
+
+inline bool JSValue::getString(ExecState* exec, String& s) const
+{
+ return isCell() && asCell()->getString(exec, s);
+}
+
+inline String JSValue::getString(ExecState* exec) const
+{
+ return isCell() ? asCell()->getString(exec) : String();
+}
+
+template <typename Base> String HandleConverter<Base, Unknown>::getString(ExecState* exec) const
+{
+ return jsValue().getString(exec);
+}
+
+inline JSObject* JSValue::getObject() const
+{
+ return isCell() ? asCell()->getObject() : 0;
+}
+
+ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
+{
+ if (isInt32()) {
+ int32_t i = asInt32();
+ v = static_cast<uint32_t>(i);
+ return i >= 0;
+ }
+ if (isDouble()) {
+ double d = asDouble();
+ v = static_cast<uint32_t>(d);
+ return v == d;
+ }
+ return false;
+}
+
+inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+{
+ return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
+}
+
+inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
+{
+ if (isInt32()) {
+ number = asInt32();
+ value = *this;
+ return true;
+ }
+ if (isDouble()) {
+ number = asDouble();
+ value = *this;
+ return true;
+ }
+ if (isCell())
+ return asCell()->getPrimitiveNumber(exec, number, value);
+ if (isTrue()) {
+ number = 1.0;
+ value = *this;
+ return true;
+ }
+ if (isFalse() || isNull()) {
+ number = 0.0;
+ value = *this;
+ return true;
+ }
+ ASSERT(isUndefined());
+ number = QNaN;
+ value = *this;
+ return true;
+}
+
+ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
+{
+ if (isInt32())
+ return asInt32();
+ if (isDouble())
+ return asDouble();
+ return toNumberSlowCase(exec);
+}
+
+inline JSObject* JSValue::toObject(ExecState* exec) const
+{
+ return isCell() ? asCell()->toObject(exec, exec->lexicalGlobalObject()) : toObjectSlowCase(exec, exec->lexicalGlobalObject());
+}
+
+inline JSObject* JSValue::toObject(ExecState* exec, JSGlobalObject* globalObject) const
+{
+ return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject);
+}
+
+inline bool JSValue::isFunction() const
+{
+ return isCell() && (asCell()->inherits(&JSFunction::s_info) || asCell()->inherits(&InternalFunction::s_info));
+}
+
+// this method is here to be after the inline declaration of JSCell::inherits
+inline bool JSValue::inherits(const ClassInfo* classInfo) const
+{
+ return isCell() && asCell()->inherits(classInfo);
+}
+
+inline JSObject* JSValue::toThisObject(ExecState* exec) const
+{
+ return isCell() ? asCell()->methodTable()->toThisObject(asCell(), exec) : toThisObjectSlowCase(exec);
+}
+
+inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName) const
+{
+ PropertySlot slot(asValue());
+ return get(exec, propertyName, slot);
+}
+
+inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName, PropertySlot& slot) const
+{
+ if (UNLIKELY(!isCell())) {
+ JSObject* prototype = synthesizePrototype(exec);
+ if (!prototype->getPropertySlot(exec, propertyName, slot))
+ return jsUndefined();
+ return slot.getValue(exec, propertyName);
+ }
+ JSCell* cell = asCell();
+ while (true) {
+ if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
+ return slot.getValue(exec, propertyName);
+ JSValue prototype = asObject(cell)->prototype();
+ if (!prototype.isObject())
+ return jsUndefined();
+ cell = asObject(prototype);
+ }
+}
+
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
+{
+ PropertySlot slot(asValue());
+ return get(exec, propertyName, slot);
+}
+
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
+{
+ if (UNLIKELY(!isCell())) {
+ JSObject* prototype = synthesizePrototype(exec);
+ if (!prototype->getPropertySlot(exec, propertyName, slot))
+ return jsUndefined();
+ return slot.getValue(exec, propertyName);
+ }
+ JSCell* cell = const_cast<JSCell*>(asCell());
+ while (true) {
+ if (cell->methodTable()->getOwnPropertySlotByIndex(cell, exec, propertyName, slot))
+ return slot.getValue(exec, propertyName);
+ JSValue prototype = asObject(cell)->prototype();
+ if (!prototype.isObject())
+ return jsUndefined();
+ cell = prototype.asCell();
+ }
+}
+
+inline void JSValue::put(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+{
+ if (UNLIKELY(!isCell())) {
+ putToPrimitive(exec, propertyName, value, slot);
+ return;
+ }
+ asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
+}
+
+inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
+{
+ if (UNLIKELY(!isCell())) {
+ putToPrimitiveByIndex(exec, propertyName, value, shouldThrow);
+ return;
+ }
+ asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
+}
+
+inline JSValue JSValue::structureOrUndefined() const
+{
+ if (isCell())
+ return JSValue(asCell()->structure());
+ return jsUndefined();
+}
+
+// ECMA 11.9.3
+inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
+{
+ if (v1.isInt32() && v2.isInt32())
+ return v1 == v2;
+
+ return equalSlowCase(exec, v1, v2);
+}
+
+ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
+{
+ do {
+ if (v1.isNumber() && v2.isNumber())
+ return v1.asNumber() == v2.asNumber();
+
+ bool s1 = v1.isString();
+ bool s2 = v2.isString();
+ if (s1 && s2)
+ return asString(v1)->value(exec) == asString(v2)->value(exec);
+
+ if (v1.isUndefinedOrNull()) {
+ if (v2.isUndefinedOrNull())
+ return true;
+ if (!v2.isCell())
+ return false;
+ return v2.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
+ }
+
+ if (v2.isUndefinedOrNull()) {
+ if (!v1.isCell())
+ return false;
+ return v1.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
+ }
+
+ if (v1.isObject()) {
+ if (v2.isObject())
+ return v1 == v2;
+ JSValue p1 = v1.toPrimitive(exec);
+ if (exec->hadException())
+ return false;
+ v1 = p1;
+ if (v1.isInt32() && v2.isInt32())
+ return v1 == v2;
+ continue;
+ }
+
+ if (v2.isObject()) {
+ JSValue p2 = v2.toPrimitive(exec);
+ if (exec->hadException())
+ return false;
+ v2 = p2;
+ if (v1.isInt32() && v2.isInt32())
+ return v1 == v2;
+ continue;
+ }
+
+ if (s1 || s2) {
+ double d1 = v1.toNumber(exec);
+ double d2 = v2.toNumber(exec);
+ return d1 == d2;
+ }
+
+ if (v1.isBoolean()) {
+ if (v2.isNumber())
+ return static_cast<double>(v1.asBoolean()) == v2.asNumber();
+ } else if (v2.isBoolean()) {
+ if (v1.isNumber())
+ return v1.asNumber() == static_cast<double>(v2.asBoolean());
+ }
+
+ return v1 == v2;
+ } while (true);
+}
+
+// ECMA 11.9.3
+ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
+{
+ ASSERT(v1.isCell() && v2.isCell());
+
+ if (v1.asCell()->isString() && v2.asCell()->isString())
+ return asString(v1)->value(exec) == asString(v2)->value(exec);
+
+ return v1 == v2;
+}
+
+inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2)
+{
+ if (v1.isInt32() && v2.isInt32())
+ return v1 == v2;
+
+ if (v1.isNumber() && v2.isNumber())
+ return v1.asNumber() == v2.asNumber();
+
+ if (!v1.isCell() || !v2.isCell())
+ return v1 == v2;
+
+ return strictEqualSlowCaseInline(exec, v1, v2);
+}
+
+inline TriState JSValue::pureToBoolean() const
+{
+ if (isInt32())
+ return asInt32() ? TrueTriState : FalseTriState;
+ if (isDouble())
+ return isNotZeroAndOrdered(asDouble()) ? TrueTriState : FalseTriState; // false for NaN
+ if (isCell())
+ return asCell()->pureToBoolean();
+ return isTrue() ? TrueTriState : FalseTriState;
+}
+
+} // namespace JSC
+
+#endif // JSValueInlines_h
+
diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp
index f6f4d716d..07b333193 100644
--- a/Source/JavaScriptCore/runtime/JSCell.cpp
+++ b/Source/JavaScriptCore/runtime/JSCell.cpp
@@ -27,6 +27,7 @@
#include "JSString.h"
#include "JSObject.h"
#include "NumberObject.h"
+#include "Operations.h"
#include <wtf/MathExtras.h>
namespace JSC {
@@ -65,13 +66,19 @@ const JSObject* JSCell::getObject() const
return isObject() ? static_cast<const JSObject*>(this) : 0;
}
-CallType JSCell::getCallData(JSCell*, CallData&)
+CallType JSCell::getCallData(JSCell*, CallData& callData)
{
+ callData.js.functionExecutable = 0;
+ callData.js.scope = 0;
+ callData.native.function = 0;
return CallTypeNone;
}
-ConstructType JSCell::getConstructData(JSCell*, ConstructData&)
+ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
{
+ constructData.js.functionExecutable = 0;
+ constructData.js.scope = 0;
+ constructData.native.function = 0;
return ConstructTypeNone;
}
@@ -173,23 +180,23 @@ void slowValidateCell(JSCell* cell)
JSValue JSCell::defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return jsUndefined();
}
void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
void JSCell::getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
String JSCell::className(const JSObject*)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return String();
}
@@ -200,29 +207,29 @@ const char* JSCell::className()
void JSCell::getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
void JSCell::putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
bool JSCell::defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
bool JSCell::getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index b28fedd8d..76acb1e55 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -24,11 +24,9 @@
#define JSCell_h
#include "CallData.h"
-#include "CallFrame.h"
#include "ConstructData.h"
#include "Heap.h"
#include "JSLock.h"
-#include "JSValueInlines.h"
#include "SlotVisitor.h"
#include "TypedArrayDescriptor.h"
#include "WriteBarrier.h"
@@ -38,6 +36,7 @@
namespace JSC {
class CopyVisitor;
+class ExecState;
class JSDestructibleObject;
class JSGlobalObject;
class LLIntOffsetsExtractor;
@@ -66,7 +65,7 @@ public:
JSCell(CreatingEarlyCellTag);
protected:
- JSCell(JSGlobalData&, Structure*);
+ JSCell(VM&, Structure*);
JS_EXPORT_PRIVATE static void destroy(JSCell*);
public:
@@ -79,7 +78,7 @@ public:
bool isAPIValueWrapper() const;
Structure* structure() const;
- void setStructure(JSGlobalData&, Structure*);
+ void setStructure(VM&, Structure*);
void clearStructure() { m_structure.clear(); }
const char* className();
@@ -97,6 +96,7 @@ public:
JS_EXPORT_PRIVATE JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
bool toBoolean(ExecState*) const;
+ TriState pureToBoolean() const;
JS_EXPORT_PRIVATE double toNumber(ExecState*) const;
JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const;
@@ -106,6 +106,7 @@ public:
// Object operations, with the toObject operation included.
const ClassInfo* classInfo() const;
const MethodTable* methodTable() const;
+ const MethodTable* methodTableForDestruction() const;
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
@@ -141,8 +142,8 @@ public:
static const TypedArrayType TypedArrayStorageType = TypedArrayNone;
protected:
- void finishCreation(JSGlobalData&);
- void finishCreation(JSGlobalData&, Structure*, CreatingEarlyCellTag);
+ void finishCreation(VM&);
+ void finishCreation(VM&, Structure*, CreatingEarlyCellTag);
// Base implementation; for non-object classes implements getPropertySlot.
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
@@ -150,12 +151,12 @@ protected:
// Dummy implementations of override-able static functions for classes to put in their MethodTable
static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
- static NO_RETURN_DUE_TO_ASSERT void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- static NO_RETURN_DUE_TO_ASSERT void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
- static NO_RETURN_DUE_TO_ASSERT void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static NO_RETURN_DUE_TO_CRASH void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static NO_RETURN_DUE_TO_CRASH void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
+ static NO_RETURN_DUE_TO_CRASH void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
static String className(const JSObject*);
JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue);
- static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
+ static NO_RETURN_DUE_TO_CRASH void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
@@ -165,174 +166,6 @@ private:
WriteBarrier<Structure> m_structure;
};
-inline JSCell::JSCell(CreatingEarlyCellTag)
-{
-}
-
-inline void JSCell::finishCreation(JSGlobalData& globalData)
-{
-#if ENABLE(GC_VALIDATION)
- ASSERT(globalData.isInitializingObject());
- globalData.setInitializingObjectClass(0);
-#else
- UNUSED_PARAM(globalData);
-#endif
- ASSERT(m_structure);
-}
-
-inline Structure* JSCell::structure() const
-{
- return m_structure.get();
-}
-
-inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- MARK_LOG_PARENT(visitor, cell);
-
- visitor.append(&cell->m_structure);
-}
-
-// --- JSValue inlines ----------------------------
-
-inline bool JSValue::isString() const
-{
- return isCell() && asCell()->isString();
-}
-
-inline bool JSValue::isPrimitive() const
-{
- return !isCell() || asCell()->isString();
-}
-
-inline bool JSValue::isGetterSetter() const
-{
- return isCell() && asCell()->isGetterSetter();
-}
-
-inline bool JSValue::isObject() const
-{
- return isCell() && asCell()->isObject();
-}
-
-inline bool JSValue::getString(ExecState* exec, String& s) const
-{
- return isCell() && asCell()->getString(exec, s);
-}
-
-inline String JSValue::getString(ExecState* exec) const
-{
- return isCell() ? asCell()->getString(exec) : String();
-}
-
-template <typename Base> String HandleConverter<Base, Unknown>::getString(ExecState* exec) const
-{
- return jsValue().getString(exec);
-}
-
-inline JSObject* JSValue::getObject() const
-{
- return isCell() ? asCell()->getObject() : 0;
-}
-
-ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
-{
- if (isInt32()) {
- int32_t i = asInt32();
- v = static_cast<uint32_t>(i);
- return i >= 0;
- }
- if (isDouble()) {
- double d = asDouble();
- v = static_cast<uint32_t>(d);
- return v == d;
- }
- return false;
-}
-
-inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
-{
- return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
-}
-
-inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
-{
- if (isInt32()) {
- number = asInt32();
- value = *this;
- return true;
- }
- if (isDouble()) {
- number = asDouble();
- value = *this;
- return true;
- }
- if (isCell())
- return asCell()->getPrimitiveNumber(exec, number, value);
- if (isTrue()) {
- number = 1.0;
- value = *this;
- return true;
- }
- if (isFalse() || isNull()) {
- number = 0.0;
- value = *this;
- return true;
- }
- ASSERT(isUndefined());
- number = QNaN;
- value = *this;
- return true;
-}
-
-ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
-{
- if (isInt32())
- return asInt32();
- if (isDouble())
- return asDouble();
- return toNumberSlowCase(exec);
-}
-
-inline JSObject* JSValue::toObject(ExecState* exec) const
-{
- return isCell() ? asCell()->toObject(exec, exec->lexicalGlobalObject()) : toObjectSlowCase(exec, exec->lexicalGlobalObject());
-}
-
-inline JSObject* JSValue::toObject(ExecState* exec, JSGlobalObject* globalObject) const
-{
- return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject);
-}
-
-template<typename T>
-void* allocateCell(Heap& heap, size_t size)
-{
- ASSERT(size >= sizeof(T));
-#if ENABLE(GC_VALIDATION)
- ASSERT(!heap.globalData()->isInitializingObject());
- heap.globalData()->setInitializingObjectClass(&T::s_info);
-#endif
- JSCell* result = 0;
- if (T::needsDestruction && T::hasImmortalStructure)
- result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size));
- else if (T::needsDestruction && !T::hasImmortalStructure)
- result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size));
- else
- result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
- result->clearStructure();
- return result;
-}
-
-template<typename T>
-void* allocateCell(Heap& heap)
-{
- return allocateCell<T>(heap, sizeof(T));
-}
-
-inline bool isZapped(const JSCell* cell)
-{
- return cell->isZapped();
-}
-
template<typename To, typename From>
inline To jsCast(From* from)
{
diff --git a/Source/JavaScriptCore/runtime/JSCellInlines.h b/Source/JavaScriptCore/runtime/JSCellInlines.h
new file mode 100644
index 000000000..5312cae35
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSCellInlines.h
@@ -0,0 +1,204 @@
+/*
+ * 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 JSCellInlines_h
+#define JSCellInlines_h
+
+#include "CallFrame.h"
+#include "Handle.h"
+#include "JSCell.h"
+#include "JSObject.h"
+#include "JSString.h"
+#include "Structure.h"
+
+namespace JSC {
+
+inline JSCell::JSCell(CreatingEarlyCellTag)
+{
+}
+
+inline JSCell::JSCell(VM& vm, Structure* structure)
+ : m_structure(vm, this, structure)
+{
+}
+
+inline void JSCell::finishCreation(VM& vm)
+{
+#if ENABLE(GC_VALIDATION)
+ ASSERT(vm.isInitializingObject());
+ vm.setInitializingObjectClass(0);
+#else
+ UNUSED_PARAM(vm);
+#endif
+ ASSERT(m_structure);
+}
+
+inline void JSCell::finishCreation(VM& vm, Structure* structure, CreatingEarlyCellTag)
+{
+#if ENABLE(GC_VALIDATION)
+ ASSERT(vm.isInitializingObject());
+ vm.setInitializingObjectClass(0);
+ if (structure)
+#endif
+ m_structure.setEarlyValue(vm, this, structure);
+ // Very first set of allocations won't have a real structure.
+ ASSERT(m_structure || !vm.structureStructure);
+}
+
+inline Structure* JSCell::structure() const
+{
+ return m_structure.get();
+}
+
+inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ MARK_LOG_PARENT(visitor, cell);
+
+ visitor.append(&cell->m_structure);
+}
+
+template<typename T>
+void* allocateCell(Heap& heap, size_t size)
+{
+ ASSERT(size >= sizeof(T));
+#if ENABLE(GC_VALIDATION)
+ ASSERT(!heap.vm()->isInitializingObject());
+ heap.vm()->setInitializingObjectClass(&T::s_info);
+#endif
+ JSCell* result = 0;
+ if (T::needsDestruction && T::hasImmortalStructure)
+ result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size));
+ else if (T::needsDestruction)
+ result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size));
+ else
+ result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
+ result->clearStructure();
+ return result;
+}
+
+template<typename T>
+void* allocateCell(Heap& heap)
+{
+ return allocateCell<T>(heap, sizeof(T));
+}
+
+inline bool isZapped(const JSCell* cell)
+{
+ return cell->isZapped();
+}
+
+inline bool JSCell::isObject() const
+{
+ return m_structure->isObject();
+}
+
+inline bool JSCell::isString() const
+{
+ return m_structure->typeInfo().type() == StringType;
+}
+
+inline bool JSCell::isGetterSetter() const
+{
+ return m_structure->typeInfo().type() == GetterSetterType;
+}
+
+inline bool JSCell::isProxy() const
+{
+ return structure()->typeInfo().type() == ProxyType;
+}
+
+inline bool JSCell::isAPIValueWrapper() const
+{
+ return m_structure->typeInfo().type() == APIValueWrapperType;
+}
+
+inline void JSCell::setStructure(VM& vm, Structure* structure)
+{
+ ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
+ ASSERT(structure->classInfo() == m_structure->classInfo());
+ ASSERT(!m_structure
+ || m_structure->transitionWatchpointSetHasBeenInvalidated()
+ || m_structure.get() == structure);
+ m_structure.set(vm, this, structure);
+}
+
+inline const MethodTable* JSCell::methodTableForDestruction() const
+{
+ return &classInfo()->methodTable;
+}
+
+inline const MethodTable* JSCell::methodTable() const
+{
+ if (Structure* rootStructure = m_structure->structure())
+ RELEASE_ASSERT(rootStructure == rootStructure->structure());
+
+ return &classInfo()->methodTable;
+}
+
+inline bool JSCell::inherits(const ClassInfo* info) const
+{
+ return classInfo()->isSubClassOf(info);
+}
+
+ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+ if (!structure()->typeInfo().overridesGetOwnPropertySlot())
+ return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
+ return methodTable()->getOwnPropertySlot(this, exec, propertyName, slot);
+}
+
+// Fast call to get a property where we may not yet have converted the string to an
+// identifier. The first time we perform a property access with a given string, try
+// performing the property map lookup without forming an identifier. We detect this
+// case by checking whether the hash has yet been set for this string.
+ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const String& name)
+{
+ if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) {
+ PropertyOffset offset = name.impl()->hasHash()
+ ? structure()->get(exec->vm(), Identifier(exec, name))
+ : structure()->get(exec->vm(), name);
+ if (offset != invalidOffset)
+ return asObject(this)->locationForOffset(offset)->get();
+ }
+ return JSValue();
+}
+
+inline bool JSCell::toBoolean(ExecState* exec) const
+{
+ if (isString())
+ return static_cast<const JSString*>(this)->toBoolean();
+ return !structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
+}
+
+inline TriState JSCell::pureToBoolean() const
+{
+ if (isString())
+ return static_cast<const JSString*>(this)->toBoolean() ? TrueTriState : FalseTriState;
+ return MixedTriState;
+}
+
+} // namespace JSC
+
+#endif // JSCellInlines_h
diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp
index cd3948fcf..b69573670 100644
--- a/Source/JavaScriptCore/runtime/JSDateMath.cpp
+++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc.
* Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
@@ -74,6 +74,7 @@
#include "JSObject.h"
#include "JSScope.h"
+#include "Operations.h"
#include <algorithm>
#include <limits.h>
@@ -126,14 +127,14 @@ static inline int msToWeekDay(double ms)
return wd;
}
-// Get the DST offset for the time passed in.
+// Get the combined UTC + DST offset for the time passed in.
//
// NOTE: The implementation relies on the fact that no time zones have
// more than one daylight savings offset change per month.
// If this function is called with NaN it returns NaN.
-static double getDSTOffset(ExecState* exec, double ms, double utcOffset)
+static LocalTimeOffset localTimeOffset(ExecState* exec, double ms)
{
- DSTOffsetCache& cache = exec->globalData().dstOffsetCache;
+ LocalTimeOffsetCache& cache = exec->vm().localTimeOffsetCache;
double start = cache.start;
double end = cache.end;
@@ -145,7 +146,7 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset)
double newEnd = end + cache.increment;
if (ms <= newEnd) {
- double endOffset = calculateDSTOffset(newEnd, utcOffset);
+ LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd);
if (cache.offset == endOffset) {
// If the offset at the end of the new interval still matches
// the offset in the cache, we grow the cached time interval
@@ -153,34 +154,33 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset)
cache.end = newEnd;
cache.increment = msPerMonth;
return endOffset;
+ }
+ LocalTimeOffset offset = calculateLocalTimeOffset(ms);
+ if (offset == endOffset) {
+ // The offset at the given time is equal to the offset at the
+ // new end of the interval, so that means that we've just skipped
+ // the point in time where the DST offset change occurred. Updated
+ // the interval to reflect this and reset the increment.
+ cache.start = ms;
+ cache.end = newEnd;
+ cache.increment = msPerMonth;
} else {
- double offset = calculateDSTOffset(ms, utcOffset);
- if (offset == endOffset) {
- // The offset at the given time is equal to the offset at the
- // new end of the interval, so that means that we've just skipped
- // the point in time where the DST offset change occurred. Updated
- // the interval to reflect this and reset the increment.
- cache.start = ms;
- cache.end = newEnd;
- cache.increment = msPerMonth;
- } else {
- // The interval contains a DST offset change and the given time is
- // before it. Adjust the increment to avoid a linear search for
- // the offset change point and change the end of the interval.
- cache.increment /= 3;
- cache.end = ms;
- }
- // Update the offset in the cache and return it.
- cache.offset = offset;
- return offset;
+ // The interval contains a DST offset change and the given time is
+ // before it. Adjust the increment to avoid a linear search for
+ // the offset change point and change the end of the interval.
+ cache.increment /= 3;
+ cache.end = ms;
}
+ // Update the offset in the cache and return it.
+ cache.offset = offset;
+ return offset;
}
}
// Compute the DST offset for the time and shrink the cache interval
// to only contain the time. This allows fast repeated DST offset
// computations for the same time.
- double offset = calculateDSTOffset(ms, utcOffset);
+ LocalTimeOffset offset = calculateLocalTimeOffset(ms);
cache.offset = offset;
cache.start = ms;
cache.end = ms;
@@ -188,30 +188,14 @@ static double getDSTOffset(ExecState* exec, double ms, double utcOffset)
return offset;
}
-/*
- * Get the difference in milliseconds between this time zone and UTC (GMT)
- * NOT including DST.
- */
-double getUTCOffset(ExecState* exec)
-{
- double utcOffset = exec->globalData().cachedUTCOffset;
- if (!isnan(utcOffset))
- return utcOffset;
- exec->globalData().cachedUTCOffset = calculateUTCOffset();
- return exec->globalData().cachedUTCOffset;
-}
-
double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
{
double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay());
double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds);
double result = (day * WTF::msPerDay) + ms;
- if (!inputIsUTC) { // convert to UTC
- double utcOffset = getUTCOffset(exec);
- result -= utcOffset;
- result -= getDSTOffset(exec, result, utcOffset);
- }
+ if (!inputIsUTC)
+ result -= localTimeOffset(exec, result).offset;
return result;
}
@@ -219,12 +203,10 @@ double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double
// input is UTC
void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm)
{
- double dstOff = 0.0;
- double utcOff = 0.0;
+ LocalTimeOffset localTime;
if (!outputIsUTC) {
- utcOff = getUTCOffset(exec);
- dstOff = getDSTOffset(exec, ms, utcOff);
- ms += dstOff + utcOff;
+ localTime = localTimeOffset(exec, ms);
+ ms += localTime.offset;
}
const int year = msToYear(ms);
@@ -236,8 +218,8 @@ void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, Gregori
tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year)));
tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year)));
tm.setYear(year);
- tm.setIsDST(dstOff != 0.0);
- tm.setUtcOffset(static_cast<long>((dstOff + utcOff) / WTF::msPerSecond));
+ tm.setIsDST(localTime.isDST);
+ tm.setUtcOffset(localTime.offset / WTF::msPerSecond);
}
double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString)
@@ -246,27 +228,25 @@ double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateSt
bool haveTZ;
int offset;
double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
- if (isnan(ms))
+ if (std::isnan(ms))
return QNaN;
// fall back to local timezone
- if (!haveTZ) {
- double utcOffset = getUTCOffset(exec);
- double dstOffset = getDSTOffset(exec, ms, utcOffset);
- offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute);
- }
+ if (!haveTZ)
+ offset = localTimeOffset(exec, ms).offset / WTF::msPerMinute;
+
return ms - (offset * WTF::msPerMinute);
}
double parseDate(ExecState* exec, const String& date)
{
- if (date == exec->globalData().cachedDateString)
- return exec->globalData().cachedDateStringValue;
+ if (date == exec->vm().cachedDateString)
+ return exec->vm().cachedDateStringValue;
double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data());
- if (isnan(value))
+ if (std::isnan(value))
value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
- exec->globalData().cachedDateString = date;
- exec->globalData().cachedDateStringValue = value;
+ exec->vm().cachedDateString = date;
+ exec->vm().cachedDateStringValue = value;
return value;
}
diff --git a/Source/JavaScriptCore/runtime/JSDestructibleObject.h b/Source/JavaScriptCore/runtime/JSDestructibleObject.h
index efbe2b4f6..27dc06da5 100644
--- a/Source/JavaScriptCore/runtime/JSDestructibleObject.h
+++ b/Source/JavaScriptCore/runtime/JSDestructibleObject.h
@@ -3,4 +3,43 @@
#include "JSObject.h"
+namespace JSC {
+
+struct ClassInfo;
+
+class JSDestructibleObject : public JSNonFinalObject {
+public:
+ typedef JSNonFinalObject Base;
+
+ static const bool needsDestruction = true;
+
+ const ClassInfo* classInfo() const { return m_classInfo; }
+
+ static ptrdiff_t classInfoOffset() { return OBJECT_OFFSETOF(JSDestructibleObject, m_classInfo); }
+
+protected:
+ JSDestructibleObject(VM& vm, Structure* structure, Butterfly* butterfly = 0)
+ : JSNonFinalObject(vm, structure, butterfly)
+ , m_classInfo(structure->classInfo())
+ {
+ ASSERT(m_classInfo);
+ }
+
+private:
+ const ClassInfo* m_classInfo;
+};
+
+inline const ClassInfo* JSCell::classInfo() const
+{
+ if (MarkedBlock::blockFor(this)->destructorType() == MarkedBlock::Normal)
+ return static_cast<const JSDestructibleObject*>(this)->classInfo();
+#if ENABLE(GC_VALIDATION)
+ return m_structure.unvalidatedGet()->classInfo();
+#else
+ return m_structure->classInfo();
+#endif
+}
+
+} // namespace JSC
+
#endif
diff --git a/Source/JavaScriptCore/runtime/JSExportMacros.h b/Source/JavaScriptCore/runtime/JSExportMacros.h
index 19e2c286f..77e4b0a33 100644
--- a/Source/JavaScriptCore/runtime/JSExportMacros.h
+++ b/Source/JavaScriptCore/runtime/JSExportMacros.h
@@ -48,7 +48,7 @@
#else // !USE(EXPORT_MACROS)
-#if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
+#if OS(WINDOWS) && !COMPILER(GCC)
#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore)
#define JS_EXPORTDATA __declspec(dllexport)
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 0a98e7c13..3b89f6d7a 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -35,7 +35,9 @@
#include "JSGlobalObject.h"
#include "JSNotAnObject.h"
#include "Interpreter.h"
+#include "ObjectConstructor.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "Parser.h"
#include "PropertyNameArray.h"
@@ -61,12 +63,12 @@ JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, in
#if !ENABLE(JIT)
UNUSED_PARAM(intrinsic);
#else
- if (intrinsic != NoIntrinsic && exec->globalData().canUseJIT()) {
+ if (intrinsic != NoIntrinsic && exec->vm().canUseJIT()) {
ASSERT(nativeConstructor == callHostFunctionAsConstructor);
- executable = exec->globalData().getHostFunction(nativeFunction, intrinsic);
+ executable = exec->vm().getHostFunction(nativeFunction, intrinsic);
} else
#endif
- executable = exec->globalData().getHostFunction(nativeFunction, nativeConstructor);
+ executable = exec->vm().getHostFunction(nativeFunction, nativeConstructor);
JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure());
// Can't do this during initialization because getHostFunction might do a GC allocation.
@@ -80,49 +82,49 @@ void JSFunction::destroy(JSCell* cell)
}
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
- : Base(exec->globalData(), structure)
+ : Base(exec->vm(), structure)
, m_executable()
- , m_scope(exec->globalData(), this, globalObject)
+ , m_scope(exec->vm(), this, globalObject)
// We initialize blind so that changes to the prototype after function creation but before
// the optimizer kicks in don't disable optimizations. Once the optimizer kicks in, the
// watchpoint will start watching and any changes will both force deoptimization and disable
// future attempts to optimize. This is necessary because we are guaranteed that the
- // inheritorID is changed exactly once prior to optimizations kicking in. We could be
+ // allocation profile is changed exactly once prior to optimizations kicking in. We could be
// smarter and count the number of times the prototype is clobbered and only optimize if it
// was clobbered exactly once, but that seems like overkill. In almost all cases it will be
// clobbered once, and if it's clobbered more than once, that will probably only occur
// before we started optimizing, anyway.
- , m_inheritorIDWatchpoint(InitializedBlind)
+ , m_allocationProfileWatchpoint(InitializedBlind)
{
}
void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const String& name)
{
- Base::finishCreation(exec->globalData());
+ Base::finishCreation(exec->vm());
ASSERT(inherits(&s_info));
- m_executable.set(exec->globalData(), this, executable);
- putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name), DontDelete | ReadOnly | DontEnum);
- putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
+ m_executable.set(exec->vm(), this, executable);
+ putDirect(exec->vm(), exec->vm().propertyNames->name, jsString(exec, name), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->vm(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
-Structure* JSFunction::cacheInheritorID(ExecState* exec)
+ObjectAllocationProfile* JSFunction::createAllocationProfile(ExecState* exec, size_t inlineCapacity)
{
- JSValue prototype = get(exec, exec->globalData().propertyNames->prototype);
- if (prototype.isObject())
- m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData()));
- else
- m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure());
- return m_cachedInheritorID.get();
+ VM& vm = exec->vm();
+ JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
+ if (!prototype)
+ prototype = globalObject()->objectPrototype();
+ m_allocationProfile.initialize(globalObject()->vm(), this, prototype, inlineCapacity);
+ return &m_allocationProfile;
}
String JSFunction::name(ExecState* exec)
{
- return get(exec, exec->globalData().propertyNames->name).toWTFString(exec);
+ return get(exec, exec->vm().propertyNames->name).toWTFString(exec);
}
String JSFunction::displayName(ExecState* exec)
{
- JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
+ JSValue displayName = getDirect(exec->vm(), exec->vm().propertyNames->displayName);
if (displayName && isJSString(displayName))
return asString(displayName)->tryGetValue();
@@ -161,6 +163,7 @@ void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_scope);
visitor.append(&thisObject->m_executable);
+ thisObject->m_allocationProfile.visitAggregate(visitor);
}
CallType JSFunction::getCallData(JSCell* cell, CallData& callData)
@@ -218,16 +221,17 @@ bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName
return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
if (propertyName == exec->propertyNames().prototype) {
- WriteBarrierBase<Unknown>* location = thisObject->getDirectLocation(exec->globalData(), propertyName);
-
- if (!location) {
- JSObject* prototype = constructEmptyObject(exec, thisObject->globalObject()->emptyObjectStructure());
- prototype->putDirect(exec->globalData(), exec->propertyNames().constructor, thisObject, DontEnum);
- thisObject->putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
- location = thisObject->getDirectLocation(exec->globalData(), exec->propertyNames().prototype);
+ VM& vm = exec->vm();
+ PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName);
+ if (!isValidOffset(offset)) {
+ JSObject* prototype = constructEmptyObject(exec);
+ prototype->putDirect(vm, exec->propertyNames().constructor, thisObject, DontEnum);
+ thisObject->putDirect(vm, exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
+ offset = thisObject->getDirectOffset(vm, exec->propertyNames().prototype);
+ ASSERT(isValidOffset(offset));
}
- slot.setValue(thisObject, location->get(), thisObject->offsetForLocation(location));
+ slot.setValue(thisObject, thisObject->getDirect(offset), offset);
}
if (propertyName == exec->propertyNames().arguments) {
@@ -352,9 +356,9 @@ void JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J
// following the rules set out in ECMA-262 8.12.9.
PropertySlot slot;
thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
- thisObject->m_cachedInheritorID.clear();
- thisObject->m_inheritorIDWatchpoint.notifyWrite();
- // Don't allow this to be cached, since a [[Put]] must clear m_cachedInheritorID.
+ thisObject->m_allocationProfile.clear();
+ thisObject->m_allocationProfileWatchpoint.notifyWrite();
+ // Don't allow this to be cached, since a [[Put]] must clear m_allocationProfile.
PutPropertySlot dontCache;
Base::put(thisObject, exec, propertyName, value, dontCache);
return;
@@ -378,7 +382,7 @@ bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName prop
{
JSFunction* thisObject = jsCast<JSFunction*>(cell);
// For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
- if (!thisObject->isHostFunction() && !exec->globalData().isInDefineOwnProperty()
+ if (!thisObject->isHostFunction() && !exec->vm().isInDefineOwnProperty()
&& (propertyName == exec->propertyNames().arguments
|| propertyName == exec->propertyNames().length
|| propertyName == exec->propertyNames().name
@@ -399,8 +403,8 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
// following the rules set out in ECMA-262 8.12.9.
PropertySlot slot;
thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
- thisObject->m_cachedInheritorID.clear();
- thisObject->m_inheritorIDWatchpoint.notifyWrite();
+ thisObject->m_allocationProfile.clear();
+ thisObject->m_allocationProfileWatchpoint.notifyWrite();
return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
}
@@ -466,7 +470,6 @@ ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& construc
constructData.js.scope = thisObject->scope();
return ConstructTypeJS;
}
-
String getCalculatedDisplayName(CallFrame* callFrame, JSObject* object)
{
diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h
index 322ee58e3..da50f9581 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.h
+++ b/Source/JavaScriptCore/runtime/JSFunction.h
@@ -27,6 +27,7 @@
#include "InternalFunction.h"
#include "JSDestructibleObject.h"
#include "JSScope.h"
+#include "ObjectAllocationProfile.h"
#include "Watchpoint.h"
namespace JSC {
@@ -52,7 +53,7 @@ namespace JSC {
friend class JIT;
friend class DFG::SpeculativeJIT;
friend class DFG::JITCompiler;
- friend class JSGlobalData;
+ friend class VM;
public:
typedef JSDestructibleObject Base;
@@ -61,10 +62,10 @@ namespace JSC {
static JSFunction* create(ExecState* exec, FunctionExecutable* executable, JSScope* scope)
{
- JSGlobalData& globalData = exec->globalData();
- JSFunction* function = new (NotNull, allocateCell<JSFunction>(globalData.heap)) JSFunction(globalData, executable, scope);
+ VM& vm = exec->vm();
+ JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
ASSERT(function->structure()->globalObject());
- function->finishCreation(globalData);
+ function->finishCreation(vm);
return function;
}
@@ -88,10 +89,10 @@ namespace JSC {
{
return m_scope.get();
}
- void setScope(JSGlobalData& globalData, JSScope* scope)
+ void setScope(VM& vm, JSScope* scope)
{
ASSERT(!isHostFunctionNonInline());
- m_scope.set(globalData, this, scope);
+ m_scope.set(vm, this, scope);
}
ExecutableBase* executable() const { return m_executable.get(); }
@@ -104,10 +105,10 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
ASSERT(globalObject);
- return Structure::create(globalData, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
}
NativeFunction nativeFunction();
@@ -116,53 +117,53 @@ namespace JSC {
static ConstructType getConstructData(JSCell*, ConstructData&);
static CallType getCallData(JSCell*, CallData&);
- static inline size_t offsetOfScopeChain()
+ static inline ptrdiff_t offsetOfScopeChain()
{
return OBJECT_OFFSETOF(JSFunction, m_scope);
}
- static inline size_t offsetOfExecutable()
+ static inline ptrdiff_t offsetOfExecutable()
{
return OBJECT_OFFSETOF(JSFunction, m_executable);
}
- Structure* cachedInheritorID(ExecState* exec)
+ static inline ptrdiff_t offsetOfAllocationProfile()
{
- if (UNLIKELY(!m_cachedInheritorID))
- return cacheInheritorID(exec);
- return m_cachedInheritorID.get();
+ return OBJECT_OFFSETOF(JSFunction, m_allocationProfile);
}
- Structure* tryGetKnownInheritorID()
+ ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity)
{
- if (!m_cachedInheritorID)
+ if (UNLIKELY(m_allocationProfile.isNull()))
+ return createAllocationProfile(exec, inlineCapacity);
+ return &m_allocationProfile;
+ }
+
+ ObjectAllocationProfile* tryGetAllocationProfile()
+ {
+ if (m_allocationProfile.isNull())
return 0;
- if (m_inheritorIDWatchpoint.hasBeenInvalidated())
+ if (m_allocationProfileWatchpoint.hasBeenInvalidated())
return 0;
- return m_cachedInheritorID.get();
+ return &m_allocationProfile;
}
- void addInheritorIDWatchpoint(Watchpoint* watchpoint)
- {
- ASSERT(tryGetKnownInheritorID());
- m_inheritorIDWatchpoint.add(watchpoint);
- }
-
- static size_t offsetOfCachedInheritorID()
+ void addAllocationProfileWatchpoint(Watchpoint* watchpoint)
{
- return OBJECT_OFFSETOF(JSFunction, m_cachedInheritorID);
+ ASSERT(tryGetAllocationProfile());
+ m_allocationProfileWatchpoint.add(watchpoint);
}
protected:
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
JS_EXPORT_PRIVATE JSFunction(ExecState*, JSGlobalObject*, Structure*);
- JSFunction(JSGlobalData&, FunctionExecutable*, JSScope*);
+ JSFunction(VM&, FunctionExecutable*, JSScope*);
void finishCreation(ExecState*, NativeExecutable*, int length, const String& name);
using Base::finishCreation;
- Structure* cacheInheritorID(ExecState*);
+ ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
@@ -187,15 +188,10 @@ namespace JSC {
WriteBarrier<ExecutableBase> m_executable;
WriteBarrier<JSScope> m_scope;
- WriteBarrier<Structure> m_cachedInheritorID;
- InlineWatchpointSet m_inheritorIDWatchpoint;
+ ObjectAllocationProfile m_allocationProfile;
+ InlineWatchpointSet m_allocationProfileWatchpoint;
};
- inline bool JSValue::isFunction() const
- {
- return isCell() && (asCell()->inherits(&JSFunction::s_info) || asCell()->inherits(&InternalFunction::s_info));
- }
-
} // namespace JSC
#endif // JSFunction_h
diff --git a/Source/JavaScriptCore/runtime/JSFunctionInlines.h b/Source/JavaScriptCore/runtime/JSFunctionInlines.h
new file mode 100644
index 000000000..4f89acd7b
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSFunctionInlines.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSFunctionInlines_h
+#define JSFunctionInlines_h
+
+#include "Executable.h"
+#include "JSFunction.h"
+
+namespace JSC {
+
+inline JSFunction::JSFunction(VM& vm, FunctionExecutable* executable, JSScope* scope)
+ : Base(vm, scope->globalObject()->functionStructure())
+ , m_executable(vm, this, executable)
+ , m_scope(vm, this, scope)
+ , m_allocationProfileWatchpoint(InitializedBlind) // See comment in JSFunction.cpp concerning the reason for using InitializedBlind as opposed to InitializedWatching.
+{
+}
+
+inline FunctionExecutable* JSFunction::jsExecutable() const
+{
+ ASSERT(!isHostFunctionNonInline());
+ return static_cast<FunctionExecutable*>(m_executable.get());
+}
+
+inline bool JSFunction::isHostFunction() const
+{
+ ASSERT(m_executable);
+ return m_executable->isHostFunction();
+}
+
+inline NativeFunction JSFunction::nativeFunction()
+{
+ ASSERT(isHostFunction());
+ return static_cast<NativeExecutable*>(m_executable.get())->function();
+}
+
+inline NativeFunction JSFunction::nativeConstructor()
+{
+ ASSERT(isHostFunction());
+ return static_cast<NativeExecutable*>(m_executable.get())->constructor();
+}
+
+} // namespace JSC
+
+#endif // JSFunctionInlines_h
+
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 6f20f0e93..2fb5d34be 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -47,6 +47,7 @@
#include "FunctionPrototype.h"
#include "GetterSetter.h"
#include "Interpreter.h"
+#include "JSAPIWrapperObject.h"
#include "JSActivation.h"
#include "JSBoundFunction.h"
#include "JSCallbackConstructor.h"
@@ -58,6 +59,7 @@
#include "JSNameScope.h"
#include "JSONObject.h"
#include "JSWithScope.h"
+#include "LegacyProfiler.h"
#include "Lookup.h"
#include "MathObject.h"
#include "NameConstructor.h"
@@ -67,9 +69,11 @@
#include "NativeErrorPrototype.h"
#include "NumberConstructor.h"
#include "NumberPrototype.h"
+#include "ObjCCallbackFunction.h"
#include "ObjectConstructor.h"
#include "ObjectPrototype.h"
-#include "Profiler.h"
+#include "Operations.h"
+#include "ParserError.h"
#include "RegExpConstructor.h"
#include "RegExpMatchesArray.h"
#include "RegExpObject.h"
@@ -101,14 +105,8 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &all
@end
*/
-// Default number of ticks before a timeout check should be done.
-static const int initialTickCountThreshold = 255;
-
-// Preferred number of milliseconds between each timeout check
-static const int preferredScriptCheckTimeInterval = 1000;
-
-JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
- : Base(globalData, structure, 0)
+JSGlobalObject::JSGlobalObject(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
+ : Base(vm, structure, 0)
, m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
, m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(InitializedWatching)))
, m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
@@ -122,7 +120,7 @@ JSGlobalObject::~JSGlobalObject()
if (m_debugger)
m_debugger->detach(this);
- if (Profiler* profiler = globalData().enabledProfiler())
+ if (LegacyProfiler* profiler = vm().enabledProfiler())
profiler->stopProfiling(this);
}
@@ -131,16 +129,16 @@ void JSGlobalObject::destroy(JSCell* cell)
static_cast<JSGlobalObject*>(cell)->JSGlobalObject::~JSGlobalObject();
}
-void JSGlobalObject::setGlobalThis(JSGlobalData& globalData, JSObject* globalThis)
+void JSGlobalObject::setGlobalThis(VM& vm, JSObject* globalThis)
{
- m_globalThis.set(globalData, this, globalThis);
+ m_globalThis.set(vm, this, globalThis);
}
void JSGlobalObject::init(JSObject* thisValue)
{
- ASSERT(globalData().apiLock().currentThreadIsHoldingLock());
+ ASSERT(vm().apiLock().currentThreadIsHoldingLock());
- setGlobalThis(globalData(), thisValue);
+ setGlobalThis(vm(), thisValue);
JSGlobalObject::globalExec()->init(0, 0, this, CallFrame::noCaller(), 0, 0);
m_debugger = 0;
@@ -163,14 +161,14 @@ void JSGlobalObject::putDirectVirtual(JSObject* object, ExecState* exec, Propert
JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
- if (symbolTablePutWithAttributes(thisObject, exec->globalData(), propertyName, value, attributes))
+ if (symbolTablePutWithAttributes(thisObject, exec->vm(), propertyName, value, attributes))
return;
- JSValue valueBefore = thisObject->getDirect(exec->globalData(), propertyName);
+ JSValue valueBefore = thisObject->getDirect(exec->vm(), propertyName);
PutPropertySlot slot;
Base::put(thisObject, exec, propertyName, value, slot);
if (!valueBefore) {
- JSValue valueAfter = thisObject->getDirect(exec->globalData(), propertyName);
+ JSValue valueAfter = thisObject->getDirect(exec->vm(), propertyName);
if (valueAfter)
JSObject::putDirectVirtual(thisObject, exec, propertyName, valueAfter, attributes);
}
@@ -199,128 +197,131 @@ void JSGlobalObject::reset(JSValue prototype)
{
ExecState* exec = JSGlobalObject::globalExec();
- m_functionPrototype.set(exec->globalData(), this, FunctionPrototype::create(exec, this, FunctionPrototype::createStructure(exec->globalData(), this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
- m_functionStructure.set(exec->globalData(), this, JSFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
- m_boundFunctionStructure.set(exec->globalData(), this, JSBoundFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
- m_namedFunctionStructure.set(exec->globalData(), this, Structure::addPropertyTransition(exec->globalData(), m_functionStructure.get(), exec->globalData().propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset));
- m_internalFunctionStructure.set(exec->globalData(), this, InternalFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
+ m_functionPrototype.set(exec->vm(), this, FunctionPrototype::create(exec, this, FunctionPrototype::createStructure(exec->vm(), this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
+ m_functionStructure.set(exec->vm(), this, JSFunction::createStructure(exec->vm(), this, m_functionPrototype.get()));
+ m_boundFunctionStructure.set(exec->vm(), this, JSBoundFunction::createStructure(exec->vm(), this, m_functionPrototype.get()));
+ m_namedFunctionStructure.set(exec->vm(), this, Structure::addPropertyTransition(exec->vm(), m_functionStructure.get(), exec->vm().propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset));
+ m_internalFunctionStructure.set(exec->vm(), this, InternalFunction::createStructure(exec->vm(), this, m_functionPrototype.get()));
JSFunction* callFunction = 0;
JSFunction* applyFunction = 0;
m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction);
- m_callFunction.set(exec->globalData(), this, callFunction);
- m_applyFunction.set(exec->globalData(), this, applyFunction);
- m_objectPrototype.set(exec->globalData(), this, ObjectPrototype::create(exec, this, ObjectPrototype::createStructure(exec->globalData(), this, jsNull())));
+ m_callFunction.set(exec->vm(), this, callFunction);
+ m_applyFunction.set(exec->vm(), this, applyFunction);
+ m_objectPrototype.set(exec->vm(), this, ObjectPrototype::create(exec, this, ObjectPrototype::createStructure(exec->vm(), this, jsNull())));
GetterSetter* protoAccessor = GetterSetter::create(exec);
- protoAccessor->setGetter(exec->globalData(), JSFunction::create(exec, this, 0, String(), globalFuncProtoGetter));
- protoAccessor->setSetter(exec->globalData(), JSFunction::create(exec, this, 0, String(), globalFuncProtoSetter));
+ protoAccessor->setGetter(exec->vm(), JSFunction::create(exec, this, 0, String(), globalFuncProtoGetter));
+ protoAccessor->setSetter(exec->vm(), JSFunction::create(exec, this, 0, String(), globalFuncProtoSetter));
m_objectPrototype->putDirectAccessor(exec, exec->propertyNames().underscoreProto, protoAccessor, Accessor | DontEnum);
- m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->globalData(), m_objectPrototype.get());
-
- m_nameScopeStructure.set(exec->globalData(), this, JSNameScope::createStructure(exec->globalData(), this, jsNull()));
- m_activationStructure.set(exec->globalData(), this, JSActivation::createStructure(exec->globalData(), this, jsNull()));
- m_strictEvalActivationStructure.set(exec->globalData(), this, StrictEvalActivation::createStructure(exec->globalData(), this, jsNull()));
- m_withScopeStructure.set(exec->globalData(), this, JSWithScope::createStructure(exec->globalData(), this, jsNull()));
-
- m_emptyObjectStructure.set(exec->globalData(), this, m_objectPrototype->inheritorID(exec->globalData()));
- m_nullPrototypeObjectStructure.set(exec->globalData(), this, createEmptyObjectStructure(exec->globalData(), this, jsNull()));
-
- m_callbackFunctionStructure.set(exec->globalData(), this, JSCallbackFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
- m_argumentsStructure.set(exec->globalData(), this, Arguments::createStructure(exec->globalData(), this, m_objectPrototype.get()));
- m_callbackConstructorStructure.set(exec->globalData(), this, JSCallbackConstructor::createStructure(exec->globalData(), this, m_objectPrototype.get()));
- m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
+ m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->vm(), m_objectPrototype.get());
+
+ m_nameScopeStructure.set(exec->vm(), this, JSNameScope::createStructure(exec->vm(), this, jsNull()));
+ m_activationStructure.set(exec->vm(), this, JSActivation::createStructure(exec->vm(), this, jsNull()));
+ m_strictEvalActivationStructure.set(exec->vm(), this, StrictEvalActivation::createStructure(exec->vm(), this, jsNull()));
+ m_withScopeStructure.set(exec->vm(), this, JSWithScope::createStructure(exec->vm(), this, jsNull()));
+
+ m_nullPrototypeObjectStructure.set(exec->vm(), this, JSFinalObject::createStructure(vm(), this, jsNull(), JSFinalObject::defaultInlineCapacity()));
+
+ m_callbackFunctionStructure.set(exec->vm(), this, JSCallbackFunction::createStructure(exec->vm(), this, m_functionPrototype.get()));
+ m_argumentsStructure.set(exec->vm(), this, Arguments::createStructure(exec->vm(), this, m_objectPrototype.get()));
+ m_callbackConstructorStructure.set(exec->vm(), this, JSCallbackConstructor::createStructure(exec->vm(), this, m_objectPrototype.get()));
+ m_callbackObjectStructure.set(exec->vm(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->vm(), this, m_objectPrototype.get()));
+#if JSC_OBJC_API_ENABLED
+ m_objcCallbackFunctionStructure.set(exec->vm(), this, ObjCCallbackFunction::createStructure(exec->vm(), this, m_functionPrototype.get()));
+ m_objcWrapperObjectStructure.set(exec->vm(), this, JSCallbackObject<JSAPIWrapperObject>::createStructure(exec->vm(), this, m_objectPrototype.get()));
+#endif
- m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
+ m_arrayPrototype.set(exec->vm(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->vm(), this, m_objectPrototype.get())));
- m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithUndecided));
- m_originalArrayStructureForIndexingShape[Int32Shape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithInt32));
- m_originalArrayStructureForIndexingShape[DoubleShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithDouble));
- m_originalArrayStructureForIndexingShape[ContiguousShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous));
- m_originalArrayStructureForIndexingShape[ArrayStorageShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
- m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
+ m_originalArrayStructureForIndexingShape[UndecidedShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithUndecided));
+ m_originalArrayStructureForIndexingShape[Int32Shape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithInt32));
+ m_originalArrayStructureForIndexingShape[DoubleShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithDouble));
+ m_originalArrayStructureForIndexingShape[ContiguousShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithContiguous));
+ m_originalArrayStructureForIndexingShape[ArrayStorageShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
+ m_originalArrayStructureForIndexingShape[SlowPutArrayStorageShape >> IndexingShapeShift].set(exec->vm(), this, JSArray::createStructure(exec->vm(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
- m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
+ m_regExpMatchesArrayStructure.set(exec->vm(), this, RegExpMatchesArray::createStructure(exec->vm(), this, m_arrayPrototype.get()));
- m_stringPrototype.set(exec->globalData(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_stringObjectStructure.set(exec->globalData(), this, StringObject::createStructure(exec->globalData(), this, m_stringPrototype.get()));
+ m_stringPrototype.set(exec->vm(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->vm(), this, m_objectPrototype.get())));
+ m_stringObjectStructure.set(exec->vm(), this, StringObject::createStructure(exec->vm(), this, m_stringPrototype.get()));
- m_booleanPrototype.set(exec->globalData(), this, BooleanPrototype::create(exec, this, BooleanPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_booleanObjectStructure.set(exec->globalData(), this, BooleanObject::createStructure(exec->globalData(), this, m_booleanPrototype.get()));
+ m_booleanPrototype.set(exec->vm(), this, BooleanPrototype::create(exec, this, BooleanPrototype::createStructure(exec->vm(), this, m_objectPrototype.get())));
+ m_booleanObjectStructure.set(exec->vm(), this, BooleanObject::createStructure(exec->vm(), this, m_booleanPrototype.get()));
- m_numberPrototype.set(exec->globalData(), this, NumberPrototype::create(exec, this, NumberPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_numberObjectStructure.set(exec->globalData(), this, NumberObject::createStructure(exec->globalData(), this, m_numberPrototype.get()));
+ m_numberPrototype.set(exec->vm(), this, NumberPrototype::create(exec, this, NumberPrototype::createStructure(exec->vm(), this, m_objectPrototype.get())));
+ m_numberObjectStructure.set(exec->vm(), this, NumberObject::createStructure(exec->vm(), this, m_numberPrototype.get()));
- m_datePrototype.set(exec->globalData(), this, DatePrototype::create(exec, this, DatePrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_dateStructure.set(exec->globalData(), this, DateInstance::createStructure(exec->globalData(), this, m_datePrototype.get()));
+ m_datePrototype.set(exec->vm(), this, DatePrototype::create(exec, this, DatePrototype::createStructure(exec->vm(), this, m_objectPrototype.get())));
+ m_dateStructure.set(exec->vm(), this, DateInstance::createStructure(exec->vm(), this, m_datePrototype.get()));
- RegExp* emptyRegex = RegExp::create(exec->globalData(), "", NoFlags);
+ RegExp* emptyRegex = RegExp::create(exec->vm(), "", NoFlags);
- m_regExpPrototype.set(exec->globalData(), this, RegExpPrototype::create(exec, this, RegExpPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()), emptyRegex));
- m_regExpStructure.set(exec->globalData(), this, RegExpObject::createStructure(exec->globalData(), this, m_regExpPrototype.get()));
+ m_regExpPrototype.set(exec->vm(), this, RegExpPrototype::create(exec, this, RegExpPrototype::createStructure(exec->vm(), this, m_objectPrototype.get()), emptyRegex));
+ m_regExpStructure.set(exec->vm(), this, RegExpObject::createStructure(exec->vm(), this, m_regExpPrototype.get()));
- m_errorPrototype.set(exec->globalData(), this, ErrorPrototype::create(exec, this, ErrorPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), this, m_errorPrototype.get()));
+ m_errorPrototype.set(exec->vm(), this, ErrorPrototype::create(exec, this, ErrorPrototype::createStructure(exec->vm(), this, m_objectPrototype.get())));
+ m_errorStructure.set(exec->vm(), this, ErrorInstance::createStructure(exec->vm(), this, m_errorPrototype.get()));
// Constructors
- JSCell* objectConstructor = ObjectConstructor::create(exec, this, ObjectConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_objectPrototype.get());
- JSCell* functionConstructor = FunctionConstructor::create(exec, this, FunctionConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_functionPrototype.get());
- JSCell* arrayConstructor = ArrayConstructor::create(exec, this, ArrayConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_arrayPrototype.get());
- JSCell* stringConstructor = StringConstructor::create(exec, this, StringConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_stringPrototype.get());
- JSCell* booleanConstructor = BooleanConstructor::create(exec, this, BooleanConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_booleanPrototype.get());
- JSCell* numberConstructor = NumberConstructor::create(exec, this, NumberConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_numberPrototype.get());
- JSCell* dateConstructor = DateConstructor::create(exec, this, DateConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_datePrototype.get());
-
- m_regExpConstructor.set(exec->globalData(), this, RegExpConstructor::create(exec, this, RegExpConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_regExpPrototype.get()));
-
- m_errorConstructor.set(exec->globalData(), this, ErrorConstructor::create(exec, this, ErrorConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), m_errorPrototype.get()));
-
- Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->globalData(), this, m_errorPrototype.get());
- Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get());
- m_evalErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("EvalError")));
- m_rangeErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("RangeError")));
- m_referenceErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("ReferenceError")));
- m_syntaxErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("SyntaxError")));
- m_typeErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("TypeError")));
- m_URIErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("URIError")));
-
- m_objectPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum);
- m_functionPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum);
- m_arrayPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
- m_booleanPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
- m_stringPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, stringConstructor, DontEnum);
- m_numberPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, numberConstructor, DontEnum);
- m_datePrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, dateConstructor, DontEnum);
- m_regExpPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum);
- m_errorPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum);
-
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().Object, objectConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Function"), functionConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().Array, arrayConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "String"), stringConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Number"), numberConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Date"), dateConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "RegExp"), m_regExpConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Error"), m_errorConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "EvalError"), m_evalErrorConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "RangeError"), m_rangeErrorConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "ReferenceError"), m_referenceErrorConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "SyntaxError"), m_syntaxErrorConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), m_typeErrorConstructor.get(), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), m_URIErrorConstructor.get(), DontEnum);
-
- m_evalFunction.set(exec->globalData(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.string(), globalFuncEval));
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum);
-
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "JSON"), JSONObject::create(exec, this, JSONObject::createStructure(exec->globalData(), this, m_objectPrototype.get())), DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Math"), MathObject::create(exec, this, MathObject::createStructure(exec->globalData(), this, m_objectPrototype.get())), DontEnum);
+ JSCell* objectConstructor = ObjectConstructor::create(exec, this, ObjectConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_objectPrototype.get());
+ JSCell* functionConstructor = FunctionConstructor::create(exec, this, FunctionConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_functionPrototype.get());
+ JSCell* arrayConstructor = ArrayConstructor::create(exec, this, ArrayConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_arrayPrototype.get());
+ JSCell* stringConstructor = StringConstructor::create(exec, this, StringConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_stringPrototype.get());
+ JSCell* booleanConstructor = BooleanConstructor::create(exec, this, BooleanConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_booleanPrototype.get());
+ JSCell* numberConstructor = NumberConstructor::create(exec, this, NumberConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_numberPrototype.get());
+ JSCell* dateConstructor = DateConstructor::create(exec, this, DateConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_datePrototype.get());
+
+ m_regExpConstructor.set(exec->vm(), this, RegExpConstructor::create(exec, this, RegExpConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_regExpPrototype.get()));
+
+ m_errorConstructor.set(exec->vm(), this, ErrorConstructor::create(exec, this, ErrorConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), m_errorPrototype.get()));
+
+ Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->vm(), this, m_errorPrototype.get());
+ Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->vm(), this, m_functionPrototype.get());
+ m_evalErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("EvalError")));
+ m_rangeErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("RangeError")));
+ m_referenceErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("ReferenceError")));
+ m_syntaxErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("SyntaxError")));
+ m_typeErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("TypeError")));
+ m_URIErrorConstructor.set(exec->vm(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("URIError")));
+
+ m_objectPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, objectConstructor, DontEnum);
+ m_functionPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, functionConstructor, DontEnum);
+ m_arrayPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, arrayConstructor, DontEnum);
+ m_booleanPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, booleanConstructor, DontEnum);
+ m_stringPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, stringConstructor, DontEnum);
+ m_numberPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, numberConstructor, DontEnum);
+ m_datePrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, dateConstructor, DontEnum);
+ m_regExpPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, m_regExpConstructor.get(), DontEnum);
+ m_errorPrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, m_errorConstructor.get(), DontEnum);
+
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Object, objectConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Function, functionConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Array, arrayConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Boolean, booleanConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().String, stringConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Number, numberConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Date, dateConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().RegExp, m_regExpConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Error, m_errorConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().EvalError, m_evalErrorConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().RangeError, m_rangeErrorConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().ReferenceError, m_referenceErrorConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().SyntaxError, m_syntaxErrorConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().TypeError, m_typeErrorConstructor.get(), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().URIError, m_URIErrorConstructor.get(), DontEnum);
+
+ m_evalFunction.set(exec->vm(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.string(), globalFuncEval));
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum);
+
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().JSON, JSONObject::create(exec, this, JSONObject::createStructure(exec->vm(), this, m_objectPrototype.get())), DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().Math, MathObject::create(exec, this, MathObject::createStructure(exec->vm(), this, m_objectPrototype.get())), DontEnum);
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly),
- GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
- GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly)
+ GlobalPropertyInfo(exec->propertyNames().NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(exec->propertyNames().Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
+ GlobalPropertyInfo(exec->propertyNames().undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly)
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
@@ -330,15 +331,15 @@ void JSGlobalObject::reset(JSValue prototype)
m_specialPointers[Special::ArrayConstructor] = arrayConstructor;
if (m_experimentsEnabled) {
- NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()));
- m_privateNameStructure.set(exec->globalData(), this, NameInstance::createStructure(exec->globalData(), this, privateNamePrototype));
+ NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->vm(), this, m_objectPrototype.get()));
+ m_privateNameStructure.set(exec->vm(), this, NameInstance::createStructure(exec->vm(), this, privateNamePrototype));
- JSCell* privateNameConstructor = NameConstructor::create(exec, this, NameConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()), privateNamePrototype);
- privateNamePrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, privateNameConstructor, DontEnum);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "Name"), privateNameConstructor, DontEnum);
+ JSCell* privateNameConstructor = NameConstructor::create(exec, this, NameConstructor::createStructure(exec->vm(), this, m_functionPrototype.get()), privateNamePrototype);
+ privateNamePrototype->putDirectWithoutTransition(exec->vm(), exec->propertyNames().constructor, privateNameConstructor, DontEnum);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "Name"), privateNameConstructor, DontEnum);
}
- resetPrototype(exec->globalData(), prototype);
+ resetPrototype(exec->vm(), prototype);
}
// Private namespace for helpers for JSGlobalObject::haveABadTime()
@@ -404,9 +405,9 @@ void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
} // end private namespace for helpers for JSGlobalObject::haveABadTime()
-void JSGlobalObject::haveABadTime(JSGlobalData& globalData)
+void JSGlobalObject::haveABadTime(VM& vm)
{
- ASSERT(&globalData == &this->globalData());
+ ASSERT(&vm == &this->vm());
if (isHavingABadTime())
return;
@@ -420,18 +421,18 @@ void JSGlobalObject::haveABadTime(JSGlobalData& globalData)
// Make sure that all JSArray allocations that load the appropriate structure from
// this object now load a structure that uses SlowPut.
for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
- m_arrayStructureForIndexingShapeDuringAllocation[i].set(globalData, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
+ m_arrayStructureForIndexingShapeDuringAllocation[i].set(vm, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
// Make sure that all objects that have indexed storage switch to the slow kind of
// indexed storage.
MarkedArgumentBuffer foundObjects; // Use MarkedArgumentBuffer because switchToSlowPutArrayStorage() may GC.
ObjectsWithBrokenIndexingFinder finder(foundObjects, this);
- globalData.heap.objectSpace().forEachLiveCell(finder);
+ vm.heap.objectSpace().forEachLiveCell(finder);
while (!foundObjects.isEmpty()) {
JSObject* object = asObject(foundObjects.last());
foundObjects.removeLast();
ASSERT(hasBrokenIndexing(object));
- object->switchToSlowPutArrayStorage(globalData);
+ object->switchToSlowPutArrayStorage(vm);
}
}
@@ -447,20 +448,20 @@ void JSGlobalObject::createThrowTypeError(ExecState* exec)
{
JSFunction* thrower = JSFunction::create(exec, this, 0, String(), globalFuncThrowTypeError);
GetterSetter* getterSetter = GetterSetter::create(exec);
- getterSetter->setGetter(exec->globalData(), thrower);
- getterSetter->setSetter(exec->globalData(), thrower);
- m_throwTypeErrorGetterSetter.set(exec->globalData(), this, getterSetter);
+ getterSetter->setGetter(exec->vm(), thrower);
+ getterSetter->setSetter(exec->vm(), thrower);
+ m_throwTypeErrorGetterSetter.set(exec->vm(), this, getterSetter);
}
// Set prototype, and also insert the object prototype at the end of the chain.
-void JSGlobalObject::resetPrototype(JSGlobalData& globalData, JSValue prototype)
+void JSGlobalObject::resetPrototype(VM& vm, JSValue prototype)
{
- setPrototype(globalData, prototype);
+ setPrototype(vm, prototype);
JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
JSObject* objectPrototype = m_objectPrototype.get();
if (oldLastInPrototypeChain != objectPrototype)
- oldLastInPrototypeChain->setPrototype(globalData, objectPrototype);
+ oldLastInPrototypeChain->setPrototype(vm, objectPrototype);
}
void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
@@ -510,8 +511,11 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_callbackConstructorStructure);
visitor.append(&thisObject->m_callbackFunctionStructure);
visitor.append(&thisObject->m_callbackObjectStructure);
+#if JSC_OBJC_API_ENABLED
+ visitor.append(&thisObject->m_objcCallbackFunctionStructure);
+ visitor.append(&thisObject->m_objcWrapperObjectStructure);
+#endif
visitor.append(&thisObject->m_dateStructure);
- visitor.append(&thisObject->m_emptyObjectStructure);
visitor.append(&thisObject->m_nullPrototypeObjectStructure);
visitor.append(&thisObject->m_errorStructure);
visitor.append(&thisObject->m_functionStructure);
@@ -546,7 +550,7 @@ void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
int index = symbolTable()->size();
SymbolTableEntry newEntry(index, global.attributes);
symbolTable()->add(global.identifier.impl(), newEntry);
- registerAt(index).set(globalData(), this, global.value);
+ registerAt(index).set(vm(), this, global.value);
}
}
@@ -571,28 +575,29 @@ void JSGlobalObject::clearRareData(JSCell* cell)
jsCast<JSGlobalObject*>(cell)->m_rareData.clear();
}
-DynamicGlobalObjectScope::DynamicGlobalObjectScope(JSGlobalData& globalData, JSGlobalObject* dynamicGlobalObject)
- : m_dynamicGlobalObjectSlot(globalData.dynamicGlobalObject)
+DynamicGlobalObjectScope::DynamicGlobalObjectScope(VM& vm, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(vm.dynamicGlobalObject)
, m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
{
if (!m_dynamicGlobalObjectSlot) {
#if ENABLE(ASSEMBLER)
if (ExecutableAllocator::underMemoryPressure())
- globalData.heap.deleteAllCompiledCode();
+ vm.heap.deleteAllCompiledCode();
#endif
m_dynamicGlobalObjectSlot = dynamicGlobalObject;
// Reset the date cache between JS invocations to force the VM
// to observe time zone changes.
- globalData.resetDateCache();
+ vm.resetDateCache();
}
+ // Clear the exception stack between entries
+ vm.clearExceptionStack();
}
void slowValidateCell(JSGlobalObject* globalObject)
{
- if (!globalObject->isGlobalObject())
- CRASH();
+ RELEASE_ASSERT(globalObject->isGlobalObject());
ASSERT_GC_OBJECT_INHERITS(globalObject, &JSGlobalObject::s_info);
}
@@ -602,7 +607,7 @@ UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* call
JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal;
DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
- UnlinkedProgramCodeBlock* unlinkedCode = globalData().codeCache()->getProgramCodeBlock(globalData(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
+ UnlinkedProgramCodeBlock* unlinkedCode = vm().codeCache()->getProgramCodeBlock(vm(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
if (hasDebugger())
debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message);
@@ -615,13 +620,13 @@ UnlinkedProgramCodeBlock* JSGlobalObject::createProgramCodeBlock(CallFrame* call
return unlinkedCode;
}
-UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, EvalExecutable* executable, JSObject** exception)
+UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CodeCache* cache, CallFrame* callFrame, JSScope* scope, EvalExecutable* executable, JSObject** exception)
{
ParserError error;
JSParserStrictness strictness = executable->isStrictMode() ? JSParseStrict : JSParseNormal;
DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff;
ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff;
- UnlinkedEvalCodeBlock* unlinkedCode = globalData().codeCache()->getEvalCodeBlock(globalData(), executable, executable->source(), strictness, debuggerMode, profilerMode, error);
+ UnlinkedEvalCodeBlock* unlinkedCode = cache->getEvalCodeBlock(vm(), scope, executable, executable->source(), strictness, debuggerMode, profilerMode, error);
if (hasDebugger())
debugger()->sourceParsed(callFrame, executable->source().provider(), error.m_line, error.m_message);
@@ -634,20 +639,4 @@ UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame,
return unlinkedCode;
}
-UnlinkedFunctionExecutable* JSGlobalObject::createFunctionExecutableFromGlobalCode(CallFrame* callFrame, const Identifier& name, const SourceCode& code, JSObject** exception)
-{
- ParserError error;
- UnlinkedFunctionExecutable* executable = globalData().codeCache()->getFunctionExecutableFromGlobalCode(globalData(), name, code, error);
- if (hasDebugger())
- debugger()->sourceParsed(callFrame, code.provider(), error.m_line, error.m_message);
-
- if (error.m_type != ParserError::ErrorNone) {
- *exception = error.toErrorObject(this, code);
- return 0;
- }
-
- return executable;
-}
-
-
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index e6edd0be7..a2c99fccb 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -24,564 +24,524 @@
#include "ArrayAllocationProfile.h"
#include "JSArray.h"
-#include "JSGlobalData.h"
+#include "JSClassRef.h"
+#include "VM.h"
#include "JSSegmentedVariableObject.h"
#include "JSWeakObjectMapRefInternal.h"
#include "NumberPrototype.h"
#include "SpecialPointer.h"
#include "StringPrototype.h"
#include "StructureChain.h"
+#include "StructureRareDataInlines.h"
#include "Watchpoint.h"
+#include <JavaScriptCore/JSBase.h>
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
#include <wtf/RandomNumber.h>
+struct OpaqueJSClass;
+struct OpaqueJSClassContextData;
+
namespace JSC {
- class ArrayPrototype;
- class BooleanPrototype;
- class DatePrototype;
- class Debugger;
- class ErrorConstructor;
- class ErrorPrototype;
- class EvalCodeBlock;
- class EvalExecutable;
- class FunctionCodeBlock;
- class FunctionExecutable;
- class FunctionPrototype;
- class GetterSetter;
- class GlobalCodeBlock;
- class JSStack;
- class LLIntOffsetsExtractor;
- class NativeErrorConstructor;
- class ProgramCodeBlock;
- class ProgramExecutable;
- class RegExpConstructor;
- class RegExpPrototype;
- class SourceCode;
- struct ActivationStackNode;
- struct HashTable;
-
- typedef Vector<ExecState*, 16> ExecStateStack;
+class ArrayPrototype;
+class BooleanPrototype;
+class DatePrototype;
+class Debugger;
+class ErrorConstructor;
+class ErrorPrototype;
+class EvalCodeBlock;
+class EvalExecutable;
+class FunctionCodeBlock;
+class FunctionExecutable;
+class FunctionPrototype;
+class GetterSetter;
+class GlobalCodeBlock;
+class JSStack;
+class LLIntOffsetsExtractor;
+class NativeErrorConstructor;
+class ProgramCodeBlock;
+class ProgramExecutable;
+class RegExpConstructor;
+class RegExpPrototype;
+class SourceCode;
+struct ActivationStackNode;
+struct HashTable;
+
+typedef Vector<ExecState*, 16> ExecStateStack;
- struct GlobalObjectMethodTable {
- typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*);
- AllowsAccessFromFunctionPtr allowsAccessFrom;
-
- typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*);
- SupportsProfilingFunctionPtr supportsProfiling;
-
- typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*);
- SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo;
-
- typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*);
- ShouldInterruptScriptFunctionPtr shouldInterruptScript;
-
- typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*);
- JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled;
- };
-
- class JSGlobalObject : public JSSegmentedVariableObject {
- private:
- typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
-
- struct JSGlobalObjectRareData {
- JSGlobalObjectRareData()
- : profileGroup(0)
- {
- }
-
- WeakMapSet weakMaps;
- unsigned profileGroup;
- };
-
- protected:
-
- Register m_globalCallFrame[JSStack::CallFrameHeaderSize];
-
- WriteBarrier<JSObject> m_globalThis;
-
- WriteBarrier<RegExpConstructor> m_regExpConstructor;
- WriteBarrier<ErrorConstructor> m_errorConstructor;
- WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
- WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
- WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor;
- WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor;
- WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
- WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
-
- WriteBarrier<JSFunction> m_evalFunction;
- WriteBarrier<JSFunction> m_callFunction;
- WriteBarrier<JSFunction> m_applyFunction;
- WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter;
-
- WriteBarrier<ObjectPrototype> m_objectPrototype;
- WriteBarrier<FunctionPrototype> m_functionPrototype;
- WriteBarrier<ArrayPrototype> m_arrayPrototype;
- WriteBarrier<BooleanPrototype> m_booleanPrototype;
- WriteBarrier<StringPrototype> m_stringPrototype;
- WriteBarrier<NumberPrototype> m_numberPrototype;
- WriteBarrier<DatePrototype> m_datePrototype;
- WriteBarrier<RegExpPrototype> m_regExpPrototype;
- WriteBarrier<ErrorPrototype> m_errorPrototype;
-
- WriteBarrier<Structure> m_withScopeStructure;
- WriteBarrier<Structure> m_strictEvalActivationStructure;
- WriteBarrier<Structure> m_activationStructure;
- WriteBarrier<Structure> m_nameScopeStructure;
- WriteBarrier<Structure> m_argumentsStructure;
-
- // Lists the actual structures used for having these particular indexing shapes.
- WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes];
- // Lists the structures we should use during allocation for these particular indexing shapes.
- WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes];
-
- WriteBarrier<Structure> m_booleanObjectStructure;
- WriteBarrier<Structure> m_callbackConstructorStructure;
- WriteBarrier<Structure> m_callbackFunctionStructure;
- WriteBarrier<Structure> m_callbackObjectStructure;
- WriteBarrier<Structure> m_dateStructure;
- WriteBarrier<Structure> m_emptyObjectStructure;
- WriteBarrier<Structure> m_nullPrototypeObjectStructure;
- WriteBarrier<Structure> m_errorStructure;
- WriteBarrier<Structure> m_functionStructure;
- WriteBarrier<Structure> m_boundFunctionStructure;
- WriteBarrier<Structure> m_namedFunctionStructure;
- PropertyOffset m_functionNameOffset;
- WriteBarrier<Structure> m_numberObjectStructure;
- WriteBarrier<Structure> m_privateNameStructure;
- WriteBarrier<Structure> m_regExpMatchesArrayStructure;
- WriteBarrier<Structure> m_regExpStructure;
- WriteBarrier<Structure> m_stringObjectStructure;
- WriteBarrier<Structure> m_internalFunctionStructure;
-
- void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
-
- Debugger* m_debugger;
-
- RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint;
- RefPtr<WatchpointSet> m_havingABadTimeWatchpoint;
-
- OwnPtr<JSGlobalObjectRareData> m_rareData;
-
- WeakRandom m_weakRandom;
-
- bool m_evalEnabled;
- String m_evalDisabledErrorMessage;
- bool m_experimentsEnabled;
-
- static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable;
- const GlobalObjectMethodTable* m_globalObjectMethodTable;
-
- void createRareDataIfNeeded()
- {
- if (m_rareData)
- return;
- m_rareData = adoptPtr(new JSGlobalObjectRareData);
- }
-
- public:
- typedef JSSegmentedVariableObject Base;
-
- static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure)
- {
- JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure);
- globalObject->finishCreation(globalData);
- globalData.heap.addFinalizer(globalObject, destroy);
- return globalObject;
- }
-
- static JS_EXPORTDATA const ClassInfo s_info;
-
- bool hasDebugger() const { return m_debugger; }
- bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); }
-
- protected:
- JS_EXPORT_PRIVATE explicit JSGlobalObject(JSGlobalData&, Structure*, const GlobalObjectMethodTable* = 0);
-
- void finishCreation(JSGlobalData& globalData)
- {
- Base::finishCreation(globalData);
- structure()->setGlobalObject(globalData, this);
- m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this);
- init(this);
- }
-
- void finishCreation(JSGlobalData& globalData, JSObject* thisValue)
- {
- Base::finishCreation(globalData);
- structure()->setGlobalObject(globalData, this);
- m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this);
- init(thisValue);
- }
-
- public:
- JS_EXPORT_PRIVATE ~JSGlobalObject();
- JS_EXPORT_PRIVATE static void destroy(JSCell*);
- // We don't need a destructor because we use a finalizer instead.
- static const bool needsDestruction = false;
-
- JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
+struct GlobalObjectMethodTable {
+ typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*);
+ AllowsAccessFromFunctionPtr allowsAccessFrom;
- JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
- bool hasOwnPropertyForWrite(ExecState*, PropertyName);
- JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
+ typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*);
+ SupportsProfilingFunctionPtr supportsProfiling;
- JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
+ typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*);
+ SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo;
- JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes);
- JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes);
- JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
+ typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*);
+ ShouldInterruptScriptFunctionPtr shouldInterruptScript;
- // We use this in the code generator as we perform symbol table
- // lookups prior to initializing the properties
- bool symbolTableHasProperty(PropertyName);
+ typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*);
+ JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled;
+};
- // The following accessors return pristine values, even if a script
- // replaces the global object's associated property.
+class JSGlobalObject : public JSSegmentedVariableObject {
+private:
+ typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
+ typedef HashMap<OpaqueJSClass*, OwnPtr<OpaqueJSClassContextData> > OpaqueJSClassDataMap;
- RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
-
- ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
- NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
- NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
- NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
- NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); }
- NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
- NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); }
-
- JSFunction* evalFunction() const { return m_evalFunction.get(); }
- JSFunction* callFunction() const { return m_callFunction.get(); }
- JSFunction* applyFunction() const { return m_applyFunction.get(); }
- GetterSetter* throwTypeErrorGetterSetter(ExecState* exec)
+ struct JSGlobalObjectRareData {
+ JSGlobalObjectRareData()
+ : profileGroup(0)
{
- if (!m_throwTypeErrorGetterSetter)
- createThrowTypeError(exec);
- return m_throwTypeErrorGetterSetter.get();
}
- ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
- FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
- ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
- BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
- StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
- NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
- DatePrototype* datePrototype() const { return m_datePrototype.get(); }
- RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
- ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); }
-
- Structure* withScopeStructure() const { return m_withScopeStructure.get(); }
- Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
- Structure* activationStructure() const { return m_activationStructure.get(); }
- Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); }
- Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
- Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
- {
- ASSERT(indexingType & IsArray);
- return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
- }
- Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const
- {
- ASSERT(indexingType & IsArray);
- return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
- }
- Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const
- {
- return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile));
- }
-
- bool isOriginalArrayStructure(Structure* structure)
- {
- return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure;
- }
+ WeakMapSet weakMaps;
+ unsigned profileGroup;
- Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
- Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
- Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
- Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); }
- Structure* dateStructure() const { return m_dateStructure.get(); }
- Structure* emptyObjectStructure() const { return m_emptyObjectStructure.get(); }
- Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
- Structure* errorStructure() const { return m_errorStructure.get(); }
- Structure* functionStructure() const { return m_functionStructure.get(); }
- Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); }
- Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
- PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
- Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
- Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
- Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
- Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
- Structure* regExpStructure() const { return m_regExpStructure.get(); }
- Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
-
- void* actualPointerFor(Special::Pointer pointer)
- {
- ASSERT(pointer < Special::TableSize);
- return m_specialPointers[pointer];
- }
+ OpaqueJSClassDataMap opaqueJSClassData;
+ };
- WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
- WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
+protected:
+
+ Register m_globalCallFrame[JSStack::CallFrameHeaderSize];
+
+ WriteBarrier<JSObject> m_globalThis;
+
+ WriteBarrier<RegExpConstructor> m_regExpConstructor;
+ WriteBarrier<ErrorConstructor> m_errorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
+ WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor;
+
+ WriteBarrier<JSFunction> m_evalFunction;
+ WriteBarrier<JSFunction> m_callFunction;
+ WriteBarrier<JSFunction> m_applyFunction;
+ WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter;
+
+ WriteBarrier<ObjectPrototype> m_objectPrototype;
+ WriteBarrier<FunctionPrototype> m_functionPrototype;
+ WriteBarrier<ArrayPrototype> m_arrayPrototype;
+ WriteBarrier<BooleanPrototype> m_booleanPrototype;
+ WriteBarrier<StringPrototype> m_stringPrototype;
+ WriteBarrier<NumberPrototype> m_numberPrototype;
+ WriteBarrier<DatePrototype> m_datePrototype;
+ WriteBarrier<RegExpPrototype> m_regExpPrototype;
+ WriteBarrier<ErrorPrototype> m_errorPrototype;
+
+ WriteBarrier<Structure> m_withScopeStructure;
+ WriteBarrier<Structure> m_strictEvalActivationStructure;
+ WriteBarrier<Structure> m_activationStructure;
+ WriteBarrier<Structure> m_nameScopeStructure;
+ WriteBarrier<Structure> m_argumentsStructure;
- bool isHavingABadTime() const
- {
- return m_havingABadTimeWatchpoint->hasBeenInvalidated();
- }
+ // Lists the actual structures used for having these particular indexing shapes.
+ WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes];
+ // Lists the structures we should use during allocation for these particular indexing shapes.
+ WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes];
- void haveABadTime(JSGlobalData&);
+ WriteBarrier<Structure> m_booleanObjectStructure;
+ WriteBarrier<Structure> m_callbackConstructorStructure;
+ WriteBarrier<Structure> m_callbackFunctionStructure;
+ WriteBarrier<Structure> m_callbackObjectStructure;
+#if JSC_OBJC_API_ENABLED
+ WriteBarrier<Structure> m_objcCallbackFunctionStructure;
+ WriteBarrier<Structure> m_objcWrapperObjectStructure;
+#endif
+ WriteBarrier<Structure> m_dateStructure;
+ WriteBarrier<Structure> m_nullPrototypeObjectStructure;
+ WriteBarrier<Structure> m_errorStructure;
+ WriteBarrier<Structure> m_functionStructure;
+ WriteBarrier<Structure> m_boundFunctionStructure;
+ WriteBarrier<Structure> m_namedFunctionStructure;
+ PropertyOffset m_functionNameOffset;
+ WriteBarrier<Structure> m_numberObjectStructure;
+ WriteBarrier<Structure> m_privateNameStructure;
+ WriteBarrier<Structure> m_regExpMatchesArrayStructure;
+ WriteBarrier<Structure> m_regExpStructure;
+ WriteBarrier<Structure> m_stringObjectStructure;
+ WriteBarrier<Structure> m_internalFunctionStructure;
- bool arrayPrototypeChainIsSane();
-
- void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
- unsigned profileGroup() const
- {
- if (!m_rareData)
- return 0;
- return m_rareData->profileGroup;
- }
+ void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
- Debugger* debugger() const { return m_debugger; }
- void setDebugger(Debugger* debugger) { m_debugger = debugger; }
+ Debugger* m_debugger;
- const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }
+ RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint;
+ RefPtr<WatchpointSet> m_havingABadTimeWatchpoint;
- static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; }
- static bool supportsProfiling(const JSGlobalObject*) { return false; }
- static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; }
+ OwnPtr<JSGlobalObjectRareData> m_rareData;
- JS_EXPORT_PRIVATE ExecState* globalExec();
+ WeakRandom m_weakRandom;
- static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
- static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; }
+ bool m_evalEnabled;
+ String m_evalDisabledErrorMessage;
+ bool m_experimentsEnabled;
- bool isDynamicScope(bool& requiresDynamicChecks) const;
+ static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable;
+ const GlobalObjectMethodTable* m_globalObjectMethodTable;
- bool evalEnabled() const { return m_evalEnabled; }
- const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
- void setEvalEnabled(bool enabled, const String& errorMessage = String())
- {
- m_evalEnabled = enabled;
- m_evalDisabledErrorMessage = errorMessage;
- }
-
- void resetPrototype(JSGlobalData&, JSValue prototype);
-
- JSGlobalData& globalData() const { return *Heap::heap(this)->globalData(); }
- JSObject* globalThis() const;
+ void createRareDataIfNeeded()
+ {
+ if (m_rareData)
+ return;
+ m_rareData = adoptPtr(new JSGlobalObjectRareData);
+ }
+
+public:
+ typedef JSSegmentedVariableObject Base;
- static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
- {
- return Structure::create(globalData, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
- }
+ static JSGlobalObject* create(VM& vm, Structure* structure)
+ {
+ JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure);
+ globalObject->finishCreation(vm);
+ vm.heap.addFinalizer(globalObject, destroy);
+ return globalObject;
+ }
- void registerWeakMap(OpaqueJSWeakObjectMap* map)
- {
- createRareDataIfNeeded();
- m_rareData->weakMaps.add(map);
- }
+ static JS_EXPORTDATA const ClassInfo s_info;
- void unregisterWeakMap(OpaqueJSWeakObjectMap* map)
- {
- if (m_rareData)
- m_rareData->weakMaps.remove(map);
- }
+ bool hasDebugger() const { return m_debugger; }
+ bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); }
- double weakRandomNumber() { return m_weakRandom.get(); }
- unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
+protected:
+ JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0);
- UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
- UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, JSObject** exception);
- UnlinkedFunctionExecutable* createFunctionExecutableFromGlobalCode(CallFrame*, const Identifier&, const SourceCode&, JSObject** exception);
+ void finishCreation(VM& vm)
+ {
+ Base::finishCreation(vm);
+ structure()->setGlobalObject(vm, this);
+ m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this);
+ init(this);
+ }
- protected:
+ void finishCreation(VM& vm, JSObject* thisValue)
+ {
+ Base::finishCreation(vm);
+ structure()->setGlobalObject(vm, this);
+ m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this);
+ init(thisValue);
+ }
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
+public:
+ JS_EXPORT_PRIVATE ~JSGlobalObject();
+ JS_EXPORT_PRIVATE static void destroy(JSCell*);
+ // We don't need a destructor because we use a finalizer instead.
+ static const bool needsDestruction = false;
- struct GlobalPropertyInfo {
- GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
- : identifier(i)
- , value(v)
- , attributes(a)
- {
- }
+ JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- const Identifier identifier;
- JSValue value;
- unsigned attributes;
- };
- JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
+ JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
+ JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ bool hasOwnPropertyForWrite(ExecState*, PropertyName);
+ JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
- JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*);
+ JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
- JS_EXPORT_PRIVATE void setGlobalThis(JSGlobalData&, JSObject* globalThis);
+ JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes);
+ JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes);
+ JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
- private:
- friend class LLIntOffsetsExtractor;
-
- // FIXME: Fold reset into init.
- JS_EXPORT_PRIVATE void init(JSObject* thisValue);
- void reset(JSValue prototype);
+ // We use this in the code generator as we perform symbol table
+ // lookups prior to initializing the properties
+ bool symbolTableHasProperty(PropertyName);
- void createThrowTypeError(ExecState*);
+ // The following accessors return pristine values, even if a script
+ // replaces the global object's associated property.
- JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
- };
+ RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
- JSGlobalObject* asGlobalObject(JSValue);
+ ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
+ NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); }
+ NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
+ NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); }
+ NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); }
+ NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
+ NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); }
- inline JSGlobalObject* asGlobalObject(JSValue value)
+ JSFunction* evalFunction() const { return m_evalFunction.get(); }
+ JSFunction* callFunction() const { return m_callFunction.get(); }
+ JSFunction* applyFunction() const { return m_applyFunction.get(); }
+ GetterSetter* throwTypeErrorGetterSetter(ExecState* exec)
{
- ASSERT(asObject(value)->isGlobalObject());
- return jsCast<JSGlobalObject*>(asObject(value));
+ if (!m_throwTypeErrorGetterSetter)
+ createThrowTypeError(exec);
+ return m_throwTypeErrorGetterSetter.get();
}
- inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName)
+ ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
+ FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
+ ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
+ BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
+ StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
+ NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); }
+ DatePrototype* datePrototype() const { return m_datePrototype.get(); }
+ RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
+ ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); }
+
+ Structure* withScopeStructure() const { return m_withScopeStructure.get(); }
+ Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
+ Structure* activationStructure() const { return m_activationStructure.get(); }
+ Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); }
+ Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
+ Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
{
- PropertySlot slot;
- if (Base::getOwnPropertySlot(this, exec, propertyName, slot))
- return true;
- bool slotIsWriteable;
- return symbolTableGet(this, propertyName, slot, slotIsWriteable);
+ ASSERT(indexingType & IsArray);
+ return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
}
-
- inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName)
+ Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const
{
- SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
- return !entry.isNull();
+ ASSERT(indexingType & IsArray);
+ return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
}
-
- inline JSValue Structure::prototypeForLookup(JSGlobalObject* globalObject) const
+ Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const
{
- if (isObject())
- return m_prototype.get();
-
- ASSERT(typeInfo().type() == StringType);
- return globalObject->stringPrototype();
+ return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile));
}
-
- inline JSValue Structure::prototypeForLookup(ExecState* exec) const
+
+ bool isOriginalArrayStructure(Structure* structure)
{
- return prototypeForLookup(exec->lexicalGlobalObject());
+ return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure;
}
-
- inline StructureChain* Structure::prototypeChain(JSGlobalData& globalData, JSGlobalObject* globalObject) const
+
+ Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
+ Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
+ Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
+ Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); }
+#if JSC_OBJC_API_ENABLED
+ Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(); }
+ Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(); }
+#endif
+ Structure* dateStructure() const { return m_dateStructure.get(); }
+ Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
+ Structure* errorStructure() const { return m_errorStructure.get(); }
+ Structure* functionStructure() const { return m_functionStructure.get(); }
+ Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); }
+ Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
+ PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
+ Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
+ Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
+ Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
+ Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
+ Structure* regExpStructure() const { return m_regExpStructure.get(); }
+ Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
+
+ void* actualPointerFor(Special::Pointer pointer)
{
- // We cache our prototype chain so our clients can share it.
- if (!isValid(globalObject, m_cachedPrototypeChain.get())) {
- JSValue prototype = prototypeForLookup(globalObject);
- m_cachedPrototypeChain.set(globalData, this, StructureChain::create(globalData, prototype.isNull() ? 0 : asObject(prototype)->structure()));
- }
- return m_cachedPrototypeChain.get();
+ ASSERT(pointer < Special::TableSize);
+ return m_specialPointers[pointer];
}
- inline StructureChain* Structure::prototypeChain(ExecState* exec) const
+ WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
+ WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
+
+ bool isHavingABadTime() const
{
- return prototypeChain(exec->globalData(), exec->lexicalGlobalObject());
+ return m_havingABadTimeWatchpoint->hasBeenInvalidated();
}
+
+ void haveABadTime(VM&);
+
+ bool arrayPrototypeChainIsSane();
- inline bool Structure::isValid(JSGlobalObject* globalObject, StructureChain* cachedPrototypeChain) const
- {
- if (!cachedPrototypeChain)
- return false;
-
- JSValue prototype = prototypeForLookup(globalObject);
- WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
- while(*cachedStructure && !prototype.isNull()) {
- if (asObject(prototype)->structure() != cachedStructure->get())
- return false;
- ++cachedStructure;
- prototype = asObject(prototype)->prototype();
- }
- return prototype.isNull() && !*cachedStructure;
+ void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
+ unsigned profileGroup() const
+ {
+ if (!m_rareData)
+ return 0;
+ return m_rareData->profileGroup;
}
- inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const
- {
- return isValid(exec->lexicalGlobalObject(), cachedPrototypeChain);
- }
+ Debugger* debugger() const { return m_debugger; }
+ void setDebugger(Debugger* debugger) { m_debugger = debugger; }
- inline JSGlobalObject* ExecState::dynamicGlobalObject()
- {
- if (this == lexicalGlobalObject()->globalExec())
- return lexicalGlobalObject();
+ const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }
- // For any ExecState that's not a globalExec, the
- // dynamic global object must be set since code is running
- ASSERT(globalData().dynamicGlobalObject);
- return globalData().dynamicGlobalObject;
- }
+ static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; }
+ static bool supportsProfiling(const JSGlobalObject*) { return false; }
+ static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; }
- inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
- {
- return constructEmptyObject(exec, globalObject->emptyObjectStructure());
- }
+ JS_EXPORT_PRIVATE ExecState* globalExec();
- inline JSObject* constructEmptyObject(ExecState* exec)
- {
- return constructEmptyObject(exec, exec->lexicalGlobalObject());
- }
+ static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
+ static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; }
- inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0)
- {
- return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength));
- }
+ bool isDynamicScope(bool& requiresDynamicChecks) const;
- inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0)
+ bool evalEnabled() const { return m_evalEnabled; }
+ const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
+ void setEvalEnabled(bool enabled, const String& errorMessage = String())
{
- return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength);
+ m_evalEnabled = enabled;
+ m_evalDisabledErrorMessage = errorMessage;
}
-
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values)
+
+ void resetPrototype(VM&, JSValue prototype);
+
+ VM& vm() const { return *Heap::heap(this)->vm(); }
+ JSObject* globalThis() const;
+
+ static Structure* createStructure(VM& vm, JSValue prototype)
{
- return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values));
+ return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values)
+ void registerWeakMap(OpaqueJSWeakObjectMap* map)
{
- return constructArray(exec, profile, exec->lexicalGlobalObject(), values);
+ createRareDataIfNeeded();
+ m_rareData->weakMaps.add(map);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length)
+ void unregisterWeakMap(OpaqueJSWeakObjectMap* map)
{
- return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length));
+ if (m_rareData)
+ m_rareData->weakMaps.remove(map);
}
- inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length)
+ OpaqueJSClassDataMap& opaqueJSClassData()
{
- return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length);
+ createRareDataIfNeeded();
+ return m_rareData->opaqueJSClassData;
}
- class DynamicGlobalObjectScope {
- WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
- public:
- JS_EXPORT_PRIVATE DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*);
+ double weakRandomNumber() { return m_weakRandom.get(); }
+ unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
+
+ UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
+ UnlinkedEvalCodeBlock* createEvalCodeBlock(CodeCache*, CallFrame*, JSScope*, EvalExecutable*, JSObject** exception);
+
+protected:
- ~DynamicGlobalObjectScope()
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
+
+ struct GlobalPropertyInfo {
+ GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
+ : identifier(i)
+ , value(v)
+ , attributes(a)
{
- m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
}
- private:
- JSGlobalObject*& m_dynamicGlobalObjectSlot;
- JSGlobalObject* m_savedDynamicGlobalObject;
+ const Identifier identifier;
+ JSValue value;
+ unsigned attributes;
};
+ JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
- inline bool JSGlobalObject::isDynamicScope(bool&) const
- {
- return true;
- }
+ JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*);
- inline JSObject* JSScope::globalThis()
- {
- return globalObject()->globalThis();
- }
+ JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis);
- inline JSObject* JSGlobalObject::globalThis() const
- {
- return m_globalThis.get();
+private:
+ friend class LLIntOffsetsExtractor;
+
+ // FIXME: Fold reset into init.
+ JS_EXPORT_PRIVATE void init(JSObject* thisValue);
+ void reset(JSValue prototype);
+
+ void createThrowTypeError(ExecState*);
+
+ JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
+};
+
+JSGlobalObject* asGlobalObject(JSValue);
+
+inline JSGlobalObject* asGlobalObject(JSValue value)
+{
+ ASSERT(asObject(value)->isGlobalObject());
+ return jsCast<JSGlobalObject*>(asObject(value));
+}
+
+inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName)
+{
+ PropertySlot slot;
+ if (Base::getOwnPropertySlot(this, exec, propertyName, slot))
+ return true;
+ bool slotIsWriteable;
+ return symbolTableGet(this, propertyName, slot, slotIsWriteable);
+}
+
+inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName)
+{
+ SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
+ return !entry.isNull();
+}
+
+inline JSGlobalObject* ExecState::dynamicGlobalObject()
+{
+ if (this == lexicalGlobalObject()->globalExec())
+ return lexicalGlobalObject();
+
+ // For any ExecState that's not a globalExec, the
+ // dynamic global object must be set since code is running
+ ASSERT(vm().dynamicGlobalObject);
+ return vm().dynamicGlobalObject;
+}
+
+inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0)
+{
+ return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength));
+}
+
+inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0)
+{
+ return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength);
+}
+
+inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values)
+{
+ return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values));
+}
+
+inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values)
+{
+ return constructArray(exec, profile, exec->lexicalGlobalObject(), values);
+}
+
+inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length)
+{
+ return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length));
+}
+
+inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length)
+{
+ return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length);
+}
+
+class DynamicGlobalObjectScope {
+ WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope);
+public:
+ JS_EXPORT_PRIVATE DynamicGlobalObjectScope(VM&, JSGlobalObject*);
+
+ ~DynamicGlobalObjectScope()
+ {
+ m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
}
+private:
+ JSGlobalObject*& m_dynamicGlobalObjectSlot;
+ JSGlobalObject* m_savedDynamicGlobalObject;
+};
+
+inline bool JSGlobalObject::isDynamicScope(bool&) const
+{
+ return true;
+}
+
+inline JSObject* JSScope::globalThis()
+{
+ return globalObject()->globalThis();
+}
+
+inline JSObject* JSGlobalObject::globalThis() const
+{
+ return m_globalThis.get();
+}
+
} // namespace JSC
#endif // JSGlobalObject_h
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 1010ad2b7..0efaf84bc 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -34,6 +34,7 @@
#include "Lexer.h"
#include "LiteralParser.h"
#include "Nodes.h"
+#include "Operations.h"
#include "Parser.h"
#include <wtf/dtoa.h>
#include <stdio.h>
@@ -363,7 +364,7 @@ static double jsHexIntegerLiteral(const CharType*& data, const CharType* end)
template <typename CharType>
static double jsStrDecimalLiteral(const CharType*& data, const CharType* end)
{
- ASSERT(data < end);
+ RELEASE_ASSERT(data < end);
size_t parsedLength;
double number = parseDouble(data, end - data, parsedLength);
@@ -514,7 +515,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
}
JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject();
- EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false);
+ EvalExecutable* eval = EvalExecutable::create(exec, exec->vm().codeCache(), makeSource(s), false);
JSObject* error = eval->compile(exec, calleeGlobalObject);
if (error)
return throwVMError(exec, error);
@@ -559,13 +560,13 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec)
{
- return JSValue::encode(jsBoolean(isnan(exec->argument(0).toNumber(exec))));
+ return JSValue::encode(jsBoolean(std::isnan(exec->argument(0).toNumber(exec))));
}
EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec)
{
double n = exec->argument(0).toNumber(exec);
- return JSValue::encode(jsBoolean(isfinite(n)));
+ return JSValue::encode(jsBoolean(std::isfinite(n)));
}
EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec)
@@ -735,7 +736,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec)
if (!thisObject->isExtensible())
return throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
- if (!thisObject->setPrototypeWithCycleCheck(exec->globalData(), value))
+ if (!thisObject->setPrototypeWithCycleCheck(exec->vm(), value))
throwError(exec, createError(exec, "cyclic __proto__ value"));
return JSValue::encode(jsUndefined());
}
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
index 757c9dcac..f4512e405 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
@@ -24,39 +24,39 @@
#ifndef JSGlobalObjectFunctions_h
#define JSGlobalObjectFunctions_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include <wtf/unicode/Unicode.h>
namespace JSC {
- class ArgList;
- class ExecState;
- class JSObject;
-
- // FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
- // is a 0.5% reduction.
-
- EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState*);
- EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*);
-
- static const double mantissaOverflowLowerBound = 9007199254740992.0;
- double parseIntOverflow(const LChar*, int length, int radix);
- ALWAYS_INLINE double parseIntOverflow(const char* s, int length, int radix) { return parseIntOverflow(reinterpret_cast<const LChar*>(s), length, radix); }
- double parseIntOverflow(const UChar*, int length, int radix);
- bool isStrWhiteSpace(UChar);
- double jsToNumber(const WTF::String&);
+class ArgList;
+class ExecState;
+class JSObject;
+
+// FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
+// is a 0.5% reduction.
+
+EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState*);
+EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*);
+
+static const double mantissaOverflowLowerBound = 9007199254740992.0;
+double parseIntOverflow(const LChar*, int length, int radix);
+ALWAYS_INLINE double parseIntOverflow(const char* s, int length, int radix) { return parseIntOverflow(reinterpret_cast<const LChar*>(s), length, radix); }
+double parseIntOverflow(const UChar*, int length, int radix);
+bool isStrWhiteSpace(UChar);
+double jsToNumber(const WTF::String&);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp
index 5e3d12c92..4baa2a603 100644
--- a/Source/JavaScriptCore/runtime/JSLock.cpp
+++ b/Source/JavaScriptCore/runtime/JSLock.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 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 Library General Public
@@ -25,7 +25,7 @@
#include "CallFrame.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
-
+#include "Operations.h"
#if USE(PTHREADS)
#include <pthread.h>
@@ -51,32 +51,40 @@ void GlobalJSLock::initialize()
}
JSLockHolder::JSLockHolder(ExecState* exec)
- : m_globalData(&exec->globalData())
+ : m_vm(&exec->vm())
+{
+ init();
+}
+
+JSLockHolder::JSLockHolder(VM* vm)
+ : m_vm(vm)
{
- m_globalData->apiLock().lock();
+ init();
}
-JSLockHolder::JSLockHolder(JSGlobalData* globalData)
- : m_globalData(globalData)
+JSLockHolder::JSLockHolder(VM& vm)
+ : m_vm(&vm)
{
- m_globalData->apiLock().lock();
+ init();
}
-JSLockHolder::JSLockHolder(JSGlobalData& globalData)
- : m_globalData(&globalData)
+void JSLockHolder::init()
{
- m_globalData->apiLock().lock();
+ m_vm->apiLock().lock();
}
JSLockHolder::~JSLockHolder()
{
- m_globalData->apiLock().unlock();
+ RefPtr<JSLock> apiLock(&m_vm->apiLock());
+ m_vm.clear();
+ apiLock->unlock();
}
-JSLock::JSLock()
+JSLock::JSLock(VM* vm)
: m_ownerThread(0)
, m_lockCount(0)
, m_lockDropDepth(0)
+ , m_vm(vm)
{
m_spinLock.Init();
}
@@ -85,6 +93,12 @@ JSLock::~JSLock()
{
}
+void JSLock::willDestroyVM(VM* vm)
+{
+ ASSERT_UNUSED(vm, m_vm == vm);
+ m_vm = 0;
+}
+
void JSLock::lock()
{
ThreadIdentifier currentThread = WTF::currentThread();
@@ -119,12 +133,12 @@ void JSLock::unlock()
void JSLock::lock(ExecState* exec)
{
- exec->globalData().apiLock().lock();
+ exec->vm().apiLock().lock();
}
void JSLock::unlock(ExecState* exec)
{
- exec->globalData().apiLock().unlock();
+ exec->vm().apiLock().unlock();
}
bool JSLock::currentThreadIsHoldingLock()
@@ -201,21 +215,21 @@ void JSLock::grabAllLocks(unsigned lockCount)
JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
: m_lockCount(0)
- , m_globalData(&exec->globalData())
+ , m_vm(&exec->vm())
{
- m_lockCount = m_globalData->apiLock().dropAllLocks();
+ m_lockCount = m_vm->apiLock().dropAllLocks();
}
-JSLock::DropAllLocks::DropAllLocks(JSGlobalData* globalData)
+JSLock::DropAllLocks::DropAllLocks(VM* vm)
: m_lockCount(0)
- , m_globalData(globalData)
+ , m_vm(vm)
{
- m_lockCount = m_globalData->apiLock().dropAllLocks();
+ m_lockCount = m_vm->apiLock().dropAllLocks();
}
JSLock::DropAllLocks::~DropAllLocks()
{
- m_globalData->apiLock().grabAllLocks(m_lockCount);
+ m_vm->apiLock().grabAllLocks(m_lockCount);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSLock.h b/Source/JavaScriptCore/runtime/JSLock.h
index 4c42dc0ae..83bcc2425 100644
--- a/Source/JavaScriptCore/runtime/JSLock.h
+++ b/Source/JavaScriptCore/runtime/JSLock.h
@@ -49,10 +49,10 @@ namespace JSC {
// thread acquired it to begin with.
class ExecState;
- class JSGlobalData;
+ class VM;
// This class is used to protect the initialization of the legacy single
- // shared JSGlobalData.
+ // shared VM.
class GlobalJSLock {
WTF_MAKE_NONCOPYABLE(GlobalJSLock);
public:
@@ -66,19 +66,21 @@ namespace JSC {
class JSLockHolder {
public:
- JS_EXPORT_PRIVATE JSLockHolder(JSGlobalData*);
- JS_EXPORT_PRIVATE JSLockHolder(JSGlobalData&);
+ JS_EXPORT_PRIVATE JSLockHolder(VM*);
+ JS_EXPORT_PRIVATE JSLockHolder(VM&);
JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
JS_EXPORT_PRIVATE ~JSLockHolder();
private:
- RefPtr<JSGlobalData> m_globalData;
+ void init();
+
+ RefPtr<VM> m_vm;
};
- class JSLock {
+ class JSLock : public ThreadSafeRefCounted<JSLock> {
WTF_MAKE_NONCOPYABLE(JSLock);
public:
- JSLock();
+ JSLock(VM*);
JS_EXPORT_PRIVATE ~JSLock();
JS_EXPORT_PRIVATE void lock();
@@ -86,8 +88,10 @@ namespace JSC {
static void lock(ExecState*);
static void unlock(ExecState*);
- static void lock(JSGlobalData&);
- static void unlock(JSGlobalData&);
+ static void lock(VM&);
+ static void unlock(VM&);
+
+ VM* vm() { return m_vm; }
JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
@@ -95,16 +99,18 @@ namespace JSC {
unsigned dropAllLocksUnconditionally();
void grabAllLocks(unsigned lockCount);
+ void willDestroyVM(VM*);
+
class DropAllLocks {
WTF_MAKE_NONCOPYABLE(DropAllLocks);
public:
JS_EXPORT_PRIVATE DropAllLocks(ExecState* exec);
- JS_EXPORT_PRIVATE DropAllLocks(JSGlobalData*);
+ JS_EXPORT_PRIVATE DropAllLocks(VM*);
JS_EXPORT_PRIVATE ~DropAllLocks();
private:
intptr_t m_lockCount;
- RefPtr<JSGlobalData> m_globalData;
+ RefPtr<VM> m_vm;
};
private:
@@ -113,6 +119,7 @@ namespace JSC {
ThreadIdentifier m_ownerThread;
intptr_t m_lockCount;
unsigned m_lockDropDepth;
+ VM* m_vm;
};
} // namespace
diff --git a/Source/JavaScriptCore/runtime/JSNameScope.cpp b/Source/JavaScriptCore/runtime/JSNameScope.cpp
index 335631fd0..53468d6a8 100644
--- a/Source/JavaScriptCore/runtime/JSNameScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSNameScope.cpp
@@ -27,6 +27,7 @@
#include "JSNameScope.h"
#include "Error.h"
+#include "Operations.h"
namespace JSC {
@@ -69,7 +70,7 @@ void JSNameScope::put(JSCell* cell, ExecState* exec, PropertyName propertyName,
if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode()))
return;
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
bool JSNameScope::getOwnPropertySlot(JSCell* cell, ExecState*, PropertyName propertyName, PropertySlot& slot)
diff --git a/Source/JavaScriptCore/runtime/JSNameScope.h b/Source/JavaScriptCore/runtime/JSNameScope.h
index e67370d92..43763296c 100644
--- a/Source/JavaScriptCore/runtime/JSNameScope.h
+++ b/Source/JavaScriptCore/runtime/JSNameScope.h
@@ -56,15 +56,15 @@ public:
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(NameScopeObjectType, StructureFlags), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(vm, globalObject, proto, TypeInfo(NameScopeObjectType, StructureFlags), &s_info); }
static const ClassInfo s_info;
protected:
void finishCreation(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes)
{
- Base::finishCreation(exec->globalData());
- m_registerStore.set(exec->globalData(), this, value);
+ Base::finishCreation(exec->vm());
+ m_registerStore.set(exec->vm(), this, value);
symbolTable()->add(identifier.impl(), SymbolTableEntry(-1, attributes));
}
@@ -73,7 +73,7 @@ protected:
private:
JSNameScope(ExecState* exec, JSScope* next)
: Base(
- exec->globalData(),
+ exec->vm(),
exec->lexicalGlobalObject()->nameScopeStructure(),
reinterpret_cast<Register*>(&m_registerStore + 1),
next
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
index 53592ba2b..0e4332eb4 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -30,7 +30,7 @@
#include "config.h"
#include "JSNotAnObject.h"
-#include <wtf/UnusedParam.h>
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.h b/Source/JavaScriptCore/runtime/JSNotAnObject.h
index 3636c9bd4..4ec73ac09 100644
--- a/Source/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/Source/JavaScriptCore/runtime/JSNotAnObject.h
@@ -39,7 +39,7 @@ namespace JSC {
class JSNotAnObject : public JSNonFinalObject {
private:
JSNotAnObject(ExecState* exec)
- : JSNonFinalObject(exec->globalData(), exec->globalData().notAnObjectStructure.get())
+ : JSNonFinalObject(exec->vm(), exec->vm().notAnObjectStructure.get())
{
}
@@ -49,13 +49,13 @@ namespace JSC {
static JSNotAnObject* create(ExecState* exec)
{
JSNotAnObject* object = new (NotNull, allocateCell<JSNotAnObject>(*exec->heap())) JSNotAnObject(exec);
- object->finishCreation(exec->globalData());
+ object->finishCreation(exec->vm());
return object;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp
index e051ec7d9..91b412ec3 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSONObject.cpp
@@ -35,6 +35,8 @@
#include "Local.h"
#include "LocalScope.h"
#include "Lookup.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
#include <wtf/MathExtras.h>
#include <wtf/text/StringBuilder.h>
@@ -53,13 +55,13 @@ static EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*);
namespace JSC {
JSONObject::JSONObject(JSGlobalObject* globalObject, Structure* structure)
- : JSNonFinalObject(globalObject->globalData(), structure)
+ : JSNonFinalObject(globalObject->vm(), structure)
{
}
void JSONObject::finishCreation(JSGlobalObject* globalObject)
{
- Base::finishCreation(globalObject->globalData());
+ Base::finishCreation(globalObject->vm());
ASSERT(inherits(&s_info));
}
@@ -88,7 +90,7 @@ public:
private:
class Holder {
public:
- Holder(JSGlobalData&, JSObject*);
+ Holder(VM&, JSObject*);
JSObject* object() const { return m_object.get(); }
@@ -125,7 +127,7 @@ private:
CallData m_replacerCallData;
const String m_gap;
- Vector<Holder, 16> m_holderStack;
+ Vector<Holder, 16, UnsafeVectorOverflow> m_holderStack;
String m_repeatedGap;
String m_indent;
};
@@ -215,7 +217,7 @@ Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const
if (m_replacer.asObject()->inherits(&JSArray::s_info)) {
m_usingArrayReplacer = true;
Handle<JSObject> array = m_replacer.asObject();
- unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
+ unsigned length = array->get(exec, exec->vm().propertyNames->length).toUInt32(exec);
for (unsigned i = 0; i < length; ++i) {
JSValue name = array->get(exec, i);
if (exec->hadException())
@@ -238,18 +240,18 @@ Local<Unknown> Stringifier::stringify(Handle<Unknown> value)
{
JSObject* object = constructEmptyObject(m_exec);
if (m_exec->hadException())
- return Local<Unknown>(m_exec->globalData(), jsNull());
+ return Local<Unknown>(m_exec->vm(), jsNull());
- PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
- object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value.get());
+ PropertyNameForFunctionCall emptyPropertyName(m_exec->vm().propertyNames->emptyIdentifier);
+ object->putDirect(m_exec->vm(), m_exec->vm().propertyNames->emptyIdentifier, value.get());
StringBuilder result;
if (appendStringifiedValue(result, value.get(), object, emptyPropertyName) != StringifySucceeded)
- return Local<Unknown>(m_exec->globalData(), jsUndefined());
+ return Local<Unknown>(m_exec->vm(), jsUndefined());
if (m_exec->hadException())
- return Local<Unknown>(m_exec->globalData(), jsNull());
+ return Local<Unknown>(m_exec->vm(), jsNull());
- return Local<Unknown>(m_exec->globalData(), jsString(m_exec, result.toString()));
+ return Local<Unknown>(m_exec->vm(), jsString(m_exec, result.toString()));
}
template <typename CharType>
@@ -318,10 +320,10 @@ void Stringifier::appendQuotedString(StringBuilder& builder, const String& value
inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName)
{
ASSERT(!m_exec->hadException());
- if (!value.isObject() || !asObject(value)->hasProperty(m_exec, m_exec->globalData().propertyNames->toJSON))
+ if (!value.isObject() || !asObject(value)->hasProperty(m_exec, m_exec->vm().propertyNames->toJSON))
return value;
- JSValue toJSONFunction = asObject(value)->get(m_exec, m_exec->globalData().propertyNames->toJSON);
+ JSValue toJSONFunction = asObject(value)->get(m_exec, m_exec->vm().propertyNames->toJSON);
if (m_exec->hadException())
return jsNull();
@@ -385,7 +387,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
if (value.isNumber()) {
double number = value.asNumber();
- if (!isfinite(number))
+ if (!std::isfinite(number))
builder.appendLiteral("null");
else
builder.append(String::numberToStringECMAScript(number));
@@ -414,25 +416,14 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
}
}
bool holderStackWasEmpty = m_holderStack.isEmpty();
- m_holderStack.append(Holder(m_exec->globalData(), object));
+ m_holderStack.append(Holder(m_exec->vm(), object));
if (!holderStackWasEmpty)
return StringifySucceeded;
- // If this is the outermost call, then loop to handle everything on the holder stack.
- TimeoutChecker localTimeoutChecker(m_exec->globalData().timeoutChecker);
- localTimeoutChecker.reset();
- unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck();
do {
while (m_holderStack.last().appendNextProperty(*this, builder)) {
if (m_exec->hadException())
return StringifyFailed;
- if (!--tickCount) {
- if (localTimeoutChecker.didTimeOut(m_exec)) {
- throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData()));
- return StringifyFailed;
- }
- tickCount = localTimeoutChecker.ticksUntilNextCheck();
- }
}
m_holderStack.removeLast();
} while (!m_holderStack.isEmpty());
@@ -468,8 +459,8 @@ inline void Stringifier::startNewLine(StringBuilder& builder) const
builder.append(m_indent);
}
-inline Stringifier::Holder::Holder(JSGlobalData& globalData, JSObject* object)
- : m_object(globalData, object)
+inline Stringifier::Holder::Holder(VM& vm, JSObject* object)
+ : m_object(vm, object)
, m_isArray(object->inherits(&JSArray::s_info))
, m_index(0)
#ifndef NDEBUG
@@ -488,7 +479,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
if (!m_index) {
if (m_isArray) {
m_isJSArray = isJSArray(m_object.get());
- m_size = m_object->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
+ m_size = m_object->get(exec, exec->vm().propertyNames->length).toUInt32(exec);
builder.append('[');
} else {
if (stringifier.m_usingArrayReplacer)
@@ -613,7 +604,7 @@ class Walker {
public:
Walker(ExecState* exec, Handle<JSObject> function, CallType callType, CallData callData)
: m_exec(exec)
- , m_function(exec->globalData(), function)
+ , m_function(exec->vm(), function)
, m_callType(callType)
, m_callData(callData)
{
@@ -636,26 +627,22 @@ private:
CallData m_callData;
};
-// We clamp recursion well beyond anything reasonable, but we also have a timeout check
-// to guard against "infinite" execution by inserting arbitrarily large objects.
+// We clamp recursion well beyond anything reasonable.
static const unsigned maximumFilterRecursion = 40000;
enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
{
- Vector<PropertyNameArray, 16> propertyStack;
- Vector<uint32_t, 16> indexStack;
- LocalStack<JSObject, 16> objectStack(m_exec->globalData());
- LocalStack<JSArray, 16> arrayStack(m_exec->globalData());
+ Vector<PropertyNameArray, 16, UnsafeVectorOverflow> propertyStack;
+ Vector<uint32_t, 16, UnsafeVectorOverflow> indexStack;
+ LocalStack<JSObject, 16> objectStack(m_exec->vm());
+ LocalStack<JSArray, 16> arrayStack(m_exec->vm());
- Vector<WalkerState, 16> stateStack;
+ Vector<WalkerState, 16, UnsafeVectorOverflow> stateStack;
WalkerState state = StateUnknown;
JSValue inValue = unfiltered;
JSValue outValue = jsNull();
- TimeoutChecker localTimeoutChecker(m_exec->globalData().timeoutChecker);
- localTimeoutChecker.reset();
- unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck();
while (1) {
switch (state) {
arrayStartState:
@@ -672,12 +659,6 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
}
arrayStartVisitMember:
case ArrayStartVisitMember: {
- if (!--tickCount) {
- if (localTimeoutChecker.didTimeOut(m_exec))
- return throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData()));
- tickCount = localTimeoutChecker.ticksUntilNextCheck();
- }
-
JSArray* array = arrayStack.peek();
uint32_t index = indexStack.last();
if (index == array->length()) {
@@ -731,12 +712,6 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
}
objectStartVisitMember:
case ObjectStartVisitMember: {
- if (!--tickCount) {
- if (localTimeoutChecker.didTimeOut(m_exec))
- return throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData()));
- tickCount = localTimeoutChecker.ticksUntilNextCheck();
- }
-
JSObject* object = objectStack.peek();
uint32_t index = indexStack.last();
PropertyNameArray& properties = propertyStack.last();
@@ -794,16 +769,10 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
state = stateStack.last();
stateStack.removeLast();
-
- if (!--tickCount) {
- if (localTimeoutChecker.didTimeOut(m_exec))
- return throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData()));
- tickCount = localTimeoutChecker.ticksUntilNextCheck();
- }
}
JSObject* finalHolder = constructEmptyObject(m_exec);
PutPropertySlot slot;
- finalHolder->methodTable()->put(finalHolder, m_exec, m_exec->globalData().propertyNames->emptyIdentifier, outValue, slot);
+ finalHolder->methodTable()->put(finalHolder, m_exec, m_exec->vm().propertyNames->emptyIdentifier, outValue, slot);
return callReviver(finalHolder, jsEmptyString(m_exec), outValue);
}
@@ -817,7 +786,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
return JSValue::encode(jsNull());
JSValue unfiltered;
- LocalScope scope(exec->globalData());
+ LocalScope scope(exec->vm());
if (source.is8Bit()) {
LiteralParser<LChar> jsonParser(exec, source.characters8(), source.length(), StrictJSON);
unfiltered = jsonParser.tryLiteralParse();
@@ -838,7 +807,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
CallType callType = getCallData(function, callData);
if (callType == CallTypeNone)
return JSValue::encode(unfiltered);
- return JSValue::encode(Walker(exec, Local<JSObject>(exec->globalData(), asObject(function)), callType, callData).walk(unfiltered));
+ return JSValue::encode(Walker(exec, Local<JSObject>(exec->vm(), asObject(function)), callType, callData).walk(unfiltered));
}
// ECMA-262 v5 15.12.3
@@ -846,17 +815,17 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec)
{
if (!exec->argumentCount())
return throwVMError(exec, createError(exec, ASCIILiteral("No input to stringify")));
- LocalScope scope(exec->globalData());
- Local<Unknown> value(exec->globalData(), exec->argument(0));
- Local<Unknown> replacer(exec->globalData(), exec->argument(1));
- Local<Unknown> space(exec->globalData(), exec->argument(2));
+ LocalScope scope(exec->vm());
+ Local<Unknown> value(exec->vm(), exec->argument(0));
+ Local<Unknown> replacer(exec->vm(), exec->argument(1));
+ Local<Unknown> space(exec->vm(), exec->argument(2));
return JSValue::encode(Stringifier(exec, replacer, space).stringify(value).get());
}
String JSONStringify(ExecState* exec, JSValue value, unsigned indent)
{
- LocalScope scope(exec->globalData());
- Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->globalData(), jsNull()), Local<Unknown>(exec->globalData(), jsNumber(indent))).stringify(Local<Unknown>(exec->globalData(), value));
+ LocalScope scope(exec->vm());
+ Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->vm(), jsNull()), Local<Unknown>(exec->vm(), jsNumber(indent))).stringify(Local<Unknown>(exec->vm(), value));
if (result.isUndefinedOrNull())
return String();
return result.getString(exec);
diff --git a/Source/JavaScriptCore/runtime/JSONObject.h b/Source/JavaScriptCore/runtime/JSONObject.h
index b537b9144..c02809083 100644
--- a/Source/JavaScriptCore/runtime/JSONObject.h
+++ b/Source/JavaScriptCore/runtime/JSONObject.h
@@ -43,9 +43,9 @@ namespace JSC {
return object;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index e6f95bdfa..48fc23186 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007 Eric Seidel (eric@webkit.org)
*
* This library is free software; you can redistribute it and/or
@@ -30,6 +30,7 @@
#include "CopyVisitorInlines.h"
#include "DatePrototype.h"
#include "ErrorConstructor.h"
+#include "Executable.h"
#include "GetterSetter.h"
#include "IndexingHeaderInlines.h"
#include "JSFunction.h"
@@ -133,9 +134,9 @@ ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butt
case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_INT32_INDEXING_TYPES:
case ALL_DOUBLE_INDEXING_TYPES: {
- currentTarget = newButterfly->contiguous();
- currentSource = butterfly->contiguous();
- ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength());
+ currentTarget = newButterfly->contiguous().data();
+ currentSource = butterfly->contiguous().data();
+ RELEASE_ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength());
count = newButterfly->vectorLength();
break;
}
@@ -189,7 +190,7 @@ ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* but
// Mark the array if appropriate.
switch (structure->indexingType()) {
case ALL_CONTIGUOUS_INDEXING_TYPES:
- visitor.appendValues(butterfly->contiguous(), butterfly->publicLength());
+ visitor.appendValues(butterfly->contiguous().data(), butterfly->publicLength());
break;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
visitor.appendValues(butterfly->arrayStorage()->m_vector, butterfly->arrayStorage()->vectorLength());
@@ -328,7 +329,7 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -341,7 +342,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
JSObject* thisObject = jsCast<JSObject*>(cell);
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// Try indexed put first. This is required for correctness, since loads on property names that appear like
// valid indices will never look in the named property storage.
@@ -357,8 +358,8 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
for (JSObject* obj = thisObject; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) {
prototype = obj->prototype();
if (prototype.isNull()) {
- ASSERT(!thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->globalData(), propertyName));
- if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value))
+ ASSERT(!thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName));
+ if (!thisObject->putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot, getCallableObject(value))
&& slot.isStrictMode())
throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
return;
@@ -370,19 +371,19 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
for (obj = thisObject; ; obj = asObject(prototype)) {
unsigned attributes;
JSCell* specificValue;
- PropertyOffset offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
+ PropertyOffset offset = obj->structure()->get(vm, propertyName, attributes, specificValue);
if (isValidOffset(offset)) {
if (attributes & ReadOnly) {
- ASSERT(thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->globalData(), propertyName) || obj == thisObject);
+ ASSERT(thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName) || obj == thisObject);
if (slot.isStrictMode())
throwError(exec, createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)));
return;
}
- JSValue gs = obj->getDirectOffset(offset);
+ JSValue gs = obj->getDirect(offset);
if (gs.isGetterSetter()) {
ASSERT(attributes & Accessor);
- ASSERT(thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->globalData(), propertyName) || obj == thisObject);
+ ASSERT(thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName) || obj == thisObject);
JSObject* setterFunc = asGetterSetter(gs)->setter();
if (!setterFunc) {
if (slot.isStrictMode())
@@ -411,8 +412,8 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
break;
}
- ASSERT(!thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->globalData(), propertyName) || obj == thisObject);
- if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
+ ASSERT(!thisObject->structure()->prototypeChainMayInterceptStoreTo(exec->vm(), propertyName) || obj == thisObject);
+ if (!thisObject->putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode())
throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError));
return;
}
@@ -432,7 +433,7 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
break;
case ALL_UNDECIDED_INDEXING_TYPES: {
- thisObject->convertUndecidedForValue(exec->globalData(), value);
+ thisObject->convertUndecidedForValue(exec->vm(), value);
// Reloop.
putByIndex(cell, exec, propertyName, value, shouldThrow);
return;
@@ -440,7 +441,7 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
case ALL_INT32_INDEXING_TYPES: {
if (!value.isInt32()) {
- thisObject->convertInt32ForValue(exec->globalData(), value);
+ thisObject->convertInt32ForValue(exec->vm(), value);
putByIndex(cell, exec, propertyName, value, shouldThrow);
return;
}
@@ -451,7 +452,7 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
Butterfly* butterfly = thisObject->m_butterfly;
if (propertyName >= butterfly->vectorLength())
break;
- butterfly->contiguous()[propertyName].set(exec->globalData(), thisObject, value);
+ butterfly->contiguous()[propertyName].set(exec->vm(), thisObject, value);
if (propertyName >= butterfly->publicLength())
butterfly->setPublicLength(propertyName + 1);
return;
@@ -459,14 +460,14 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
case ALL_DOUBLE_INDEXING_TYPES: {
if (!value.isNumber()) {
- thisObject->convertDoubleToContiguous(exec->globalData());
+ thisObject->convertDoubleToContiguous(exec->vm());
// Reloop.
putByIndex(cell, exec, propertyName, value, shouldThrow);
return;
}
double valueAsDouble = value.asNumber();
if (valueAsDouble != valueAsDouble) {
- thisObject->convertDoubleToContiguous(exec->globalData());
+ thisObject->convertDoubleToContiguous(exec->vm());
// Reloop.
putByIndex(cell, exec, propertyName, value, shouldThrow);
return;
@@ -498,7 +499,7 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
} else if (!valueSlot)
++storage->m_numValuesInVector;
- valueSlot.set(exec->globalData(), thisObject, value);
+ valueSlot.set(exec->vm(), thisObject, value);
return;
}
@@ -525,23 +526,23 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
++storage->m_numValuesInVector;
}
- valueSlot.set(exec->globalData(), thisObject, value);
+ valueSlot.set(exec->vm(), thisObject, value);
return;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
thisObject->putByIndexBeyondVectorLength(exec, propertyName, value, shouldThrow);
}
-ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(JSGlobalData& globalData, ArrayStorage* storage)
+ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(VM& vm, ArrayStorage* storage)
{
SparseArrayValueMap* map = storage->m_sparseMap.get();
if (!map)
- map = allocateSparseIndexMap(globalData);
+ map = allocateSparseIndexMap(vm);
if (map->sparseMode())
return storage;
@@ -554,34 +555,34 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists
// This will always be a new entry in the map, so no need to check we can write,
// and attributes are default so no need to set them.
if (value)
- map->add(this, i).iterator->value.set(globalData, this, value);
+ map->add(this, i).iterator->value.set(vm, this, value);
}
- Butterfly* newButterfly = storage->butterfly()->resizeArray(globalData, structure(), 0, ArrayStorage::sizeFor(0));
- if (!newButterfly)
- CRASH();
+ Butterfly* newButterfly = storage->butterfly()->resizeArray(vm, structure(), 0, ArrayStorage::sizeFor(0));
+ RELEASE_ASSERT(newButterfly);
m_butterfly = newButterfly;
newButterfly->arrayStorage()->m_indexBias = 0;
newButterfly->arrayStorage()->setVectorLength(0);
- newButterfly->arrayStorage()->m_sparseMap.set(globalData, this, map);
+ newButterfly->arrayStorage()->m_sparseMap.set(vm, this, map);
return newButterfly->arrayStorage();
}
-void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData)
+void JSObject::enterDictionaryIndexingMode(VM& vm)
{
switch (structure()->indexingType()) {
+ case ALL_BLANK_INDEXING_TYPES:
case ALL_UNDECIDED_INDEXING_TYPES:
case ALL_INT32_INDEXING_TYPES:
case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
// NOTE: this is horribly inefficient, as it will perform two conversions. We could optimize
// this case if we ever cared.
- enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, ensureArrayStorageSlow(globalData));
+ enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, ensureArrayStorageSlow(vm));
break;
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
+ enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, m_butterfly->arrayStorage());
break;
default:
@@ -589,20 +590,20 @@ void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData)
}
}
-void JSObject::notifyPresenceOfIndexedAccessors(JSGlobalData& globalData)
+void JSObject::notifyPresenceOfIndexedAccessors(VM& vm)
{
if (mayInterceptIndexedAccesses())
return;
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AddIndexedAccessors));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AddIndexedAccessors));
- if (!mayBeUsedAsPrototype(globalData))
+ if (!vm.prototypeMap.isPrototype(this))
return;
- globalObject()->haveABadTime(globalData);
+ globalObject()->haveABadTime(vm);
}
-Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsigned length, size_t elementSize)
+Butterfly* JSObject::createInitialIndexedStorage(VM& vm, unsigned length, size_t elementSize)
{
ASSERT(length < MAX_ARRAY_INDEX);
IndexingType oldType = structure()->indexingType();
@@ -611,105 +612,105 @@ Butterfly* JSObject::createInitialIndexedStorage(JSGlobalData& globalData, unsig
ASSERT(!indexingShouldBeSparse());
unsigned vectorLength = std::max(length, BASE_VECTOR_LEN);
Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(m_butterfly,
- globalData, structure(), structure()->outOfLineCapacity(), false, 0,
+ vm, structure(), structure()->outOfLineCapacity(), false, 0,
elementSize * vectorLength);
newButterfly->setPublicLength(length);
newButterfly->setVectorLength(vectorLength);
return newButterfly;
}
-Butterfly* JSObject::createInitialUndecided(JSGlobalData& globalData, unsigned length)
+Butterfly* JSObject::createInitialUndecided(VM& vm, unsigned length)
{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue));
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateUndecided);
- setButterfly(globalData, newButterfly, newStructure);
+ Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(EncodedJSValue));
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), AllocateUndecided);
+ setButterfly(vm, newButterfly, newStructure);
return newButterfly;
}
-WriteBarrier<Unknown>* JSObject::createInitialInt32(JSGlobalData& globalData, unsigned length)
+ContiguousJSValues JSObject::createInitialInt32(VM& vm, unsigned length)
{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue));
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateInt32);
- setButterfly(globalData, newButterfly, newStructure);
+ Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(EncodedJSValue));
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), AllocateInt32);
+ setButterfly(vm, newButterfly, newStructure);
return newButterfly->contiguousInt32();
}
-double* JSObject::createInitialDouble(JSGlobalData& globalData, unsigned length)
+ContiguousDoubles JSObject::createInitialDouble(VM& vm, unsigned length)
{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(double));
+ Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(double));
for (unsigned i = newButterfly->vectorLength(); i--;)
newButterfly->contiguousDouble()[i] = QNaN;
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateDouble);
- setButterfly(globalData, newButterfly, newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), AllocateDouble);
+ setButterfly(vm, newButterfly, newStructure);
return newButterfly->contiguousDouble();
}
-WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length)
+ContiguousJSValues JSObject::createInitialContiguous(VM& vm, unsigned length)
{
- Butterfly* newButterfly = createInitialIndexedStorage(globalData, length, sizeof(EncodedJSValue));
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous);
- setButterfly(globalData, newButterfly, newStructure);
+ Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(EncodedJSValue));
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), AllocateContiguous);
+ setButterfly(vm, newButterfly, newStructure);
return newButterfly->contiguous();
}
-ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned length, unsigned vectorLength)
+ArrayStorage* JSObject::createArrayStorage(VM& vm, unsigned length, unsigned vectorLength)
{
IndexingType oldType = structure()->indexingType();
ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType));
Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(m_butterfly,
- globalData, structure(), structure()->outOfLineCapacity(), false, 0,
+ vm, structure(), structure()->outOfLineCapacity(), false, 0,
ArrayStorage::sizeFor(vectorLength));
- if (!newButterfly)
- CRASH();
+ RELEASE_ASSERT(newButterfly);
+
ArrayStorage* result = newButterfly->arrayStorage();
result->setLength(length);
result->setVectorLength(vectorLength);
result->m_sparseMap.clear();
result->m_numValuesInVector = 0;
result->m_indexBias = 0;
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedArrayStorageTransition());
- setButterfly(globalData, newButterfly, newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), structure()->suggestedArrayStorageTransition());
+ setButterfly(vm, newButterfly, newStructure);
return result;
}
-ArrayStorage* JSObject::createInitialArrayStorage(JSGlobalData& globalData)
+ArrayStorage* JSObject::createInitialArrayStorage(VM& vm)
{
- return createArrayStorage(globalData, 0, BASE_VECTOR_LEN);
+ return createArrayStorage(vm, 0, BASE_VECTOR_LEN);
}
-WriteBarrier<Unknown>* JSObject::convertUndecidedToInt32(JSGlobalData& globalData)
+ContiguousJSValues JSObject::convertUndecidedToInt32(VM& vm)
{
ASSERT(hasUndecided(structure()->indexingType()));
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateInt32));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateInt32));
return m_butterfly->contiguousInt32();
}
-double* JSObject::convertUndecidedToDouble(JSGlobalData& globalData)
+ContiguousDoubles JSObject::convertUndecidedToDouble(VM& vm)
{
ASSERT(hasUndecided(structure()->indexingType()));
for (unsigned i = m_butterfly->vectorLength(); i--;)
m_butterfly->contiguousDouble()[i] = QNaN;
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateDouble));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateDouble));
return m_butterfly->contiguousDouble();
}
-WriteBarrier<Unknown>* JSObject::convertUndecidedToContiguous(JSGlobalData& globalData)
+ContiguousJSValues JSObject::convertUndecidedToContiguous(VM& vm)
{
ASSERT(hasUndecided(structure()->indexingType()));
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous));
return m_butterfly->contiguous();
}
-ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(JSGlobalData& globalData, unsigned neededLength)
+ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(VM& vm, unsigned neededLength)
{
unsigned publicLength = m_butterfly->publicLength();
unsigned propertyCapacity = structure()->outOfLineCapacity();
unsigned propertySize = structure()->outOfLineSize();
Butterfly* newButterfly = Butterfly::createUninitialized(
- globalData, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength));
+ vm, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength));
memcpy(
newButterfly->propertyStorage() - propertySize,
@@ -726,29 +727,29 @@ ArrayStorage* JSObject::constructConvertedArrayStorageWithoutCopyingElements(JSG
return newStorage;
}
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
{
ASSERT(hasUndecided(structure()->indexingType()));
- ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
+ ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
// No need to copy elements.
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, storage->butterfly(), newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), transition);
+ setButterfly(vm, storage->butterfly(), newStructure);
return storage;
}
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
+ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm, NonPropertyTransition transition)
{
- return convertUndecidedToArrayStorage(globalData, transition, m_butterfly->vectorLength());
+ return convertUndecidedToArrayStorage(vm, transition, m_butterfly->vectorLength());
}
-ArrayStorage* JSObject::convertUndecidedToArrayStorage(JSGlobalData& globalData)
+ArrayStorage* JSObject::convertUndecidedToArrayStorage(VM& vm)
{
- return convertUndecidedToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
+ return convertUndecidedToArrayStorage(vm, structure()->suggestedArrayStorageTransition());
}
-double* JSObject::convertInt32ToDouble(JSGlobalData& globalData)
+ContiguousDoubles JSObject::convertInt32ToDouble(VM& vm)
{
ASSERT(hasInt32(structure()->indexingType()));
@@ -764,23 +765,23 @@ double* JSObject::convertInt32ToDouble(JSGlobalData& globalData)
*currentAsDouble = v.asInt32();
}
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateDouble));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateDouble));
return m_butterfly->contiguousDouble();
}
-WriteBarrier<Unknown>* JSObject::convertInt32ToContiguous(JSGlobalData& globalData)
+ContiguousJSValues JSObject::convertInt32ToContiguous(VM& vm)
{
ASSERT(hasInt32(structure()->indexingType()));
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous));
return m_butterfly->contiguous();
}
-ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
{
ASSERT(hasInt32(structure()->indexingType()));
- ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
+ ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
for (unsigned i = m_butterfly->publicLength(); i--;) {
JSValue v = m_butterfly->contiguous()[i].get();
if (!v)
@@ -789,22 +790,23 @@ ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, Non
newStorage->m_numValuesInVector++;
}
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newStorage->butterfly(), newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), transition);
+ setButterfly(vm, newStorage->butterfly(), newStructure);
return newStorage;
}
-ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
+ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm, NonPropertyTransition transition)
{
- return convertInt32ToArrayStorage(globalData, transition, m_butterfly->vectorLength());
+ return convertInt32ToArrayStorage(vm, transition, m_butterfly->vectorLength());
}
-ArrayStorage* JSObject::convertInt32ToArrayStorage(JSGlobalData& globalData)
+ArrayStorage* JSObject::convertInt32ToArrayStorage(VM& vm)
{
- return convertInt32ToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
+ return convertInt32ToArrayStorage(vm, structure()->suggestedArrayStorageTransition());
}
-WriteBarrier<Unknown>* JSObject::convertDoubleToContiguous(JSGlobalData& globalData)
+template<JSObject::DoubleToContiguousMode mode>
+ContiguousJSValues JSObject::genericConvertDoubleToContiguous(VM& vm)
{
ASSERT(hasDouble(structure()->indexingType()));
@@ -816,18 +818,38 @@ WriteBarrier<Unknown>* JSObject::convertDoubleToContiguous(JSGlobalData& globalD
currentAsValue->clear();
continue;
}
- currentAsValue->setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));
+ JSValue v;
+ switch (mode) {
+ case EncodeValueAsDouble:
+ v = JSValue(JSValue::EncodeAsDouble, value);
+ break;
+ case RageConvertDoubleToValue:
+ v = jsNumber(value);
+ break;
+ }
+ ASSERT(v.isNumber());
+ currentAsValue->setWithoutWriteBarrier(v);
}
- setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous));
+ setStructure(vm, Structure::nonPropertyTransition(vm, structure(), AllocateContiguous));
return m_butterfly->contiguous();
}
-ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
+ContiguousJSValues JSObject::convertDoubleToContiguous(VM& vm)
+{
+ return genericConvertDoubleToContiguous<EncodeValueAsDouble>(vm);
+}
+
+ContiguousJSValues JSObject::rageConvertDoubleToContiguous(VM& vm)
+{
+ return genericConvertDoubleToContiguous<RageConvertDoubleToValue>(vm);
+}
+
+ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
{
ASSERT(hasDouble(structure()->indexingType()));
- ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
+ ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
for (unsigned i = m_butterfly->publicLength(); i--;) {
double value = m_butterfly->contiguousDouble()[i];
if (value != value)
@@ -836,26 +858,26 @@ ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, No
newStorage->m_numValuesInVector++;
}
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newStorage->butterfly(), newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), transition);
+ setButterfly(vm, newStorage->butterfly(), newStructure);
return newStorage;
}
-ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
+ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm, NonPropertyTransition transition)
{
- return convertDoubleToArrayStorage(globalData, transition, m_butterfly->vectorLength());
+ return convertDoubleToArrayStorage(vm, transition, m_butterfly->vectorLength());
}
-ArrayStorage* JSObject::convertDoubleToArrayStorage(JSGlobalData& globalData)
+ArrayStorage* JSObject::convertDoubleToArrayStorage(VM& vm)
{
- return convertDoubleToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
+ return convertDoubleToArrayStorage(vm, structure()->suggestedArrayStorageTransition());
}
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength)
+ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, NonPropertyTransition transition, unsigned neededLength)
{
ASSERT(hasContiguous(structure()->indexingType()));
- ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(globalData, neededLength);
+ ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, neededLength);
for (unsigned i = m_butterfly->publicLength(); i--;) {
JSValue v = m_butterfly->contiguous()[i].get();
if (!v)
@@ -864,200 +886,220 @@ ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData
newStorage->m_numValuesInVector++;
}
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition);
- setButterfly(globalData, newStorage->butterfly(), newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), transition);
+ setButterfly(vm, newStorage->butterfly(), newStructure);
return newStorage;
}
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition)
+ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm, NonPropertyTransition transition)
{
- return convertContiguousToArrayStorage(globalData, transition, m_butterfly->vectorLength());
+ return convertContiguousToArrayStorage(vm, transition, m_butterfly->vectorLength());
}
-ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData)
+ArrayStorage* JSObject::convertContiguousToArrayStorage(VM& vm)
{
- return convertContiguousToArrayStorage(globalData, structure()->suggestedArrayStorageTransition());
+ return convertContiguousToArrayStorage(vm, structure()->suggestedArrayStorageTransition());
}
-void JSObject::convertUndecidedForValue(JSGlobalData& globalData, JSValue value)
+void JSObject::convertUndecidedForValue(VM& vm, JSValue value)
{
if (value.isInt32()) {
- convertUndecidedToInt32(globalData);
+ convertUndecidedToInt32(vm);
return;
}
if (value.isDouble()) {
- convertUndecidedToDouble(globalData);
+ convertUndecidedToDouble(vm);
return;
}
- convertUndecidedToContiguous(globalData);
+ convertUndecidedToContiguous(vm);
}
-void JSObject::convertInt32ForValue(JSGlobalData& globalData, JSValue value)
+void JSObject::convertInt32ForValue(VM& vm, JSValue value)
{
ASSERT(!value.isInt32());
if (value.isDouble()) {
- convertInt32ToDouble(globalData);
+ convertInt32ToDouble(vm);
return;
}
- convertInt32ToContiguous(globalData);
+ convertInt32ToContiguous(vm);
}
-void JSObject::setIndexQuicklyToUndecided(JSGlobalData& globalData, unsigned index, JSValue value)
+void JSObject::setIndexQuicklyToUndecided(VM& vm, unsigned index, JSValue value)
{
ASSERT(index < m_butterfly->publicLength());
ASSERT(index < m_butterfly->vectorLength());
- convertUndecidedForValue(globalData, value);
- setIndexQuickly(globalData, index, value);
+ convertUndecidedForValue(vm, value);
+ setIndexQuickly(vm, index, value);
}
-void JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(JSGlobalData& globalData, unsigned index, JSValue value)
+void JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(VM& vm, unsigned index, JSValue value)
{
ASSERT(!value.isInt32());
- convertInt32ForValue(globalData, value);
- setIndexQuickly(globalData, index, value);
+ convertInt32ForValue(vm, value);
+ setIndexQuickly(vm, index, value);
}
-void JSObject::convertDoubleToContiguousWhilePerformingSetIndex(JSGlobalData& globalData, unsigned index, JSValue value)
+void JSObject::convertDoubleToContiguousWhilePerformingSetIndex(VM& vm, unsigned index, JSValue value)
{
ASSERT(!value.isNumber() || value.asNumber() != value.asNumber());
- convertDoubleToContiguous(globalData);
- setIndexQuickly(globalData, index, value);
+ convertDoubleToContiguous(vm);
+ setIndexQuickly(vm, index, value);
}
-WriteBarrier<Unknown>* JSObject::ensureInt32Slow(JSGlobalData& globalData)
+ContiguousJSValues JSObject::ensureInt32Slow(VM& vm)
{
+ ASSERT(inherits(&s_info));
+
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
- return 0;
- return createInitialInt32(globalData, 0);
+ return ContiguousJSValues();
+ return createInitialInt32(vm, 0);
case ALL_UNDECIDED_INDEXING_TYPES:
- return convertUndecidedToInt32(globalData);
+ return convertUndecidedToInt32(vm);
case ALL_DOUBLE_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return 0;
+ return ContiguousJSValues();
default:
CRASH();
- return 0;
+ return ContiguousJSValues();
}
}
-double* JSObject::ensureDoubleSlow(JSGlobalData& globalData)
+ContiguousDoubles JSObject::ensureDoubleSlow(VM& vm)
{
+ ASSERT(inherits(&s_info));
+
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
- return 0;
- return createInitialDouble(globalData, 0);
+ return ContiguousDoubles();
+ return createInitialDouble(vm, 0);
case ALL_UNDECIDED_INDEXING_TYPES:
- return convertUndecidedToDouble(globalData);
+ return convertUndecidedToDouble(vm);
case ALL_INT32_INDEXING_TYPES:
- return convertInt32ToDouble(globalData);
+ return convertInt32ToDouble(vm);
case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return 0;
+ return ContiguousDoubles();
default:
CRASH();
- return 0;
+ return ContiguousDoubles();
}
}
-WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData)
+ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm, DoubleToContiguousMode mode)
{
+ ASSERT(inherits(&s_info));
+
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing()))
- return 0;
- return createInitialContiguous(globalData, 0);
+ return ContiguousJSValues();
+ return createInitialContiguous(vm, 0);
case ALL_UNDECIDED_INDEXING_TYPES:
- return convertUndecidedToContiguous(globalData);
+ return convertUndecidedToContiguous(vm);
case ALL_INT32_INDEXING_TYPES:
- return convertInt32ToContiguous(globalData);
+ return convertInt32ToContiguous(vm);
case ALL_DOUBLE_INDEXING_TYPES:
- return convertDoubleToContiguous(globalData);
+ if (mode == RageConvertDoubleToValue)
+ return rageConvertDoubleToContiguous(vm);
+ return convertDoubleToContiguous(vm);
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return 0;
+ return ContiguousJSValues();
default:
CRASH();
- return 0;
+ return ContiguousJSValues();
}
}
-ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData)
+ContiguousJSValues JSObject::ensureContiguousSlow(VM& vm)
{
+ return ensureContiguousSlow(vm, EncodeValueAsDouble);
+}
+
+ContiguousJSValues JSObject::rageEnsureContiguousSlow(VM& vm)
+{
+ return ensureContiguousSlow(vm, RageConvertDoubleToValue);
+}
+
+ArrayStorage* JSObject::ensureArrayStorageSlow(VM& vm)
+{
+ ASSERT(inherits(&s_info));
+
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES:
if (UNLIKELY(indexingShouldBeSparse()))
- return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData);
- return createInitialArrayStorage(globalData);
+ return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(vm);
+ return createInitialArrayStorage(vm);
case ALL_UNDECIDED_INDEXING_TYPES:
ASSERT(!indexingShouldBeSparse());
ASSERT(!structure()->needsSlowPutIndexing());
- return convertUndecidedToArrayStorage(globalData);
+ return convertUndecidedToArrayStorage(vm);
case ALL_INT32_INDEXING_TYPES:
ASSERT(!indexingShouldBeSparse());
ASSERT(!structure()->needsSlowPutIndexing());
- return convertInt32ToArrayStorage(globalData);
+ return convertInt32ToArrayStorage(vm);
case ALL_DOUBLE_INDEXING_TYPES:
ASSERT(!indexingShouldBeSparse());
ASSERT(!structure()->needsSlowPutIndexing());
- return convertDoubleToArrayStorage(globalData);
+ return convertDoubleToArrayStorage(vm);
case ALL_CONTIGUOUS_INDEXING_TYPES:
ASSERT(!indexingShouldBeSparse());
ASSERT(!structure()->needsSlowPutIndexing());
- return convertContiguousToArrayStorage(globalData);
+ return convertContiguousToArrayStorage(vm);
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
}
-ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData& globalData)
+ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(VM& vm)
{
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES: {
- createArrayStorage(globalData, 0, 0);
- SparseArrayValueMap* map = allocateSparseIndexMap(globalData);
+ createArrayStorage(vm, 0, 0);
+ SparseArrayValueMap* map = allocateSparseIndexMap(vm);
map->setSparseMode();
return arrayStorage();
}
case ALL_UNDECIDED_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertUndecidedToArrayStorage(globalData));
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, convertUndecidedToArrayStorage(vm));
case ALL_INT32_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertInt32ToArrayStorage(globalData));
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, convertInt32ToArrayStorage(vm));
case ALL_DOUBLE_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertDoubleToArrayStorage(globalData));
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, convertDoubleToArrayStorage(vm));
case ALL_CONTIGUOUS_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData));
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, convertContiguousToArrayStorage(vm));
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
+ return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(vm, m_butterfly->arrayStorage());
default:
CRASH();
@@ -1065,29 +1107,29 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J
}
}
-void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData)
+void JSObject::switchToSlowPutArrayStorage(VM& vm)
{
switch (structure()->indexingType()) {
case ALL_UNDECIDED_INDEXING_TYPES:
- convertUndecidedToArrayStorage(globalData, AllocateSlowPutArrayStorage);
+ convertUndecidedToArrayStorage(vm, AllocateSlowPutArrayStorage);
break;
case ALL_INT32_INDEXING_TYPES:
- convertInt32ToArrayStorage(globalData, AllocateSlowPutArrayStorage);
+ convertInt32ToArrayStorage(vm, AllocateSlowPutArrayStorage);
break;
case ALL_DOUBLE_INDEXING_TYPES:
- convertDoubleToArrayStorage(globalData, AllocateSlowPutArrayStorage);
+ convertDoubleToArrayStorage(vm, AllocateSlowPutArrayStorage);
break;
case ALL_CONTIGUOUS_INDEXING_TYPES:
- convertContiguousToArrayStorage(globalData, AllocateSlowPutArrayStorage);
+ convertContiguousToArrayStorage(vm, AllocateSlowPutArrayStorage);
break;
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage: {
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), SwitchToSlowPutArrayStorage);
- setStructure(globalData, newStructure);
+ Structure* newStructure = Structure::nonPropertyTransition(vm, structure(), SwitchToSlowPutArrayStorage);
+ setStructure(vm, newStructure);
break;
}
@@ -1101,23 +1143,23 @@ void JSObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getCallableObject(value));
+ object->putDirectInternal<PutModeDefineOwnProperty>(exec->vm(), propertyName, value, attributes, slot, getCallableObject(value));
}
-void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
+void JSObject::setPrototype(VM& vm, JSValue prototype)
{
ASSERT(prototype);
if (prototype.isObject())
- asObject(prototype)->notifyUsedAsPrototype(globalData);
+ vm.prototypeMap.addPrototype(asObject(prototype));
- Structure* newStructure = Structure::changePrototypeTransition(globalData, structure(), prototype);
- setStructure(globalData, newStructure);
+ Structure* newStructure = Structure::changePrototypeTransition(vm, structure(), prototype);
+ setStructure(vm, newStructure);
if (!newStructure->anyObjectInChainMayInterceptIndexedAccesses())
return;
- if (mayBeUsedAsPrototype(globalData)) {
- newStructure->globalObject()->haveABadTime(globalData);
+ if (vm.prototypeMap.isPrototype(this)) {
+ newStructure->globalObject()->haveABadTime(vm);
return;
}
@@ -1127,10 +1169,10 @@ void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
if (shouldUseSlowPut(structure()->indexingType()))
return;
- switchToSlowPutArrayStorage(globalData);
+ switchToSlowPutArrayStorage(vm);
}
-bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
+bool JSObject::setPrototypeWithCycleCheck(VM& vm, JSValue prototype)
{
JSValue checkFor = this;
if (this->isGlobalObject())
@@ -1142,33 +1184,10 @@ bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prot
return false;
nextPrototype = asObject(nextPrototype)->prototype();
}
- setPrototype(globalData, prototype);
+ setPrototype(vm, prototype);
return true;
}
-void JSObject::resetInheritorID(JSGlobalData& globalData)
-{
- PropertyOffset offset = structure()->get(globalData, globalData.m_inheritorIDKey);
- if (!isValidOffset(offset))
- return;
-
- putDirectOffset(globalData, offset, jsUndefined());
-}
-
-Structure* JSObject::inheritorID(JSGlobalData& globalData)
-{
- if (WriteBarrierBase<Unknown>* location = getDirectLocation(globalData, globalData.m_inheritorIDKey)) {
- JSValue value = location->get();
- if (value.isCell()) {
- Structure* inheritorID = jsCast<Structure*>(value);
- ASSERT(inheritorID->isEmpty());
- return inheritorID;
- }
- ASSERT(value.isUndefined());
- }
- return createInheritorID(globalData);
-}
-
bool JSObject::allowsAccessFrom(ExecState* exec)
{
JSGlobalObject* globalObject = this->globalObject();
@@ -1185,21 +1204,21 @@ void JSObject::putDirectAccessor(ExecState* exec, PropertyName propertyName, JSV
return;
}
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getCallableObject(value));
+ putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
// putDirect will change our Structure if we add a new property. For
// getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
if (slot.type() != PutPropertySlot::NewProperty)
- setStructure(globalData, Structure::attributeChangeTransition(globalData, structure(), propertyName, attributes));
+ setStructure(vm, Structure::attributeChangeTransition(vm, structure(), propertyName, attributes));
if (attributes & ReadOnly)
structure()->setContainsReadOnlyProperties();
- structure()->setHasGetterSetterProperties(propertyName == globalData.propertyNames->underscoreProto);
+ structure()->setHasGetterSetterProperties(propertyName == vm.propertyNames->underscoreProto);
}
bool JSObject::hasProperty(ExecState* exec, PropertyName propertyName) const
@@ -1228,19 +1247,22 @@ bool JSObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName proper
unsigned attributes;
JSCell* specificValue;
- if (isValidOffset(thisObject->structure()->get(exec->globalData(), propertyName, attributes, specificValue))) {
- if (attributes & DontDelete && !exec->globalData().isInDefineOwnProperty())
+ if (isValidOffset(thisObject->structure()->get(exec->vm(), propertyName, attributes, specificValue))) {
+ if (attributes & DontDelete && !exec->vm().isInDefineOwnProperty())
return false;
- thisObject->removeDirect(exec->globalData(), propertyName);
+ thisObject->removeDirect(exec->vm(), propertyName);
return true;
}
// Look in the static hashtable of properties
const HashEntry* entry = thisObject->findPropertyHashEntry(exec, propertyName);
- if (entry && entry->attributes() & DontDelete && !exec->globalData().isInDefineOwnProperty())
- return false; // this builtin property can't be deleted
+ if (entry) {
+ if (entry->attributes() & DontDelete && !exec->vm().isInDefineOwnProperty())
+ return false; // this builtin property can't be deleted
+
+ putEntry(exec, entry, propertyName, jsUndefined(), thisObject);
+ }
- // FIXME: Should the code here actually do some deletion?
return true;
}
@@ -1301,7 +1323,7 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
@@ -1378,7 +1400,7 @@ bool JSObject::hasInstance(ExecState* exec, JSValue value)
return defaultHasInstance(exec, value, get(exec, exec->propertyNames().prototype));
if (info.implementsHasInstance())
return methodTable()->customHasInstance(this, exec, value);
- throwError(exec, createInvalidParamError(exec, "instanceof" , this));
+ throwError(exec, createInvalidParameterError(exec, "instanceof" , this));
return false;
}
@@ -1411,7 +1433,7 @@ bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyN
bool JSObject::getPropertySpecificValue(ExecState* exec, PropertyName propertyName, JSCell*& specificValue) const
{
unsigned attributes;
- if (isValidOffset(structure()->get(exec->globalData(), propertyName, attributes, specificValue)))
+ if (isValidOffset(structure()->get(exec->vm(), propertyName, attributes, specificValue)))
return true;
// This could be a function within the static table? - should probably
@@ -1488,13 +1510,13 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
}
if (SparseArrayValueMap* map = storage->m_sparseMap.get()) {
- Vector<unsigned> keys;
- keys.reserveCapacity(map->size());
+ Vector<unsigned, 0, UnsafeVectorOverflow> keys;
+ keys.reserveInitialCapacity(map->size());
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) {
if (mode == IncludeDontEnumProperties || !(it->value.attributes & DontEnum))
- keys.append(static_cast<unsigned>(it->key));
+ keys.uncheckedAppend(static_cast<unsigned>(it->key));
}
std::sort(keys.begin(), keys.end());
@@ -1505,7 +1527,7 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
object->methodTable()->getOwnNonIndexPropertyNames(object, exec, propertyNames, mode);
@@ -1516,7 +1538,7 @@ void JSObject::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, Pr
getClassPropertyNames(exec, object->classInfo(), propertyNames, mode, object->staticFunctionsReified());
bool canCachePropertiesFromStructure = !propertyNames.size();
- object->structure()->getPropertyNamesFromStructure(exec->globalData(), propertyNames, mode);
+ object->structure()->getPropertyNamesFromStructure(exec->vm(), propertyNames, mode);
if (canCachePropertiesFromStructure)
propertyNames.setNumCacheableSlotsForObject(object, propertyNames.size());
@@ -1543,27 +1565,27 @@ JSObject* JSObject::toThisObject(JSCell* cell, ExecState*)
return jsCast<JSObject*>(cell);
}
-void JSObject::seal(JSGlobalData& globalData)
+void JSObject::seal(VM& vm)
{
- if (isSealed(globalData))
+ if (isSealed(vm))
return;
- preventExtensions(globalData);
- setStructure(globalData, Structure::sealTransition(globalData, structure()));
+ preventExtensions(vm);
+ setStructure(vm, Structure::sealTransition(vm, structure()));
}
-void JSObject::freeze(JSGlobalData& globalData)
+void JSObject::freeze(VM& vm)
{
- if (isFrozen(globalData))
+ if (isFrozen(vm))
return;
- preventExtensions(globalData);
- setStructure(globalData, Structure::freezeTransition(globalData, structure()));
+ preventExtensions(vm);
+ setStructure(vm, Structure::freezeTransition(vm, structure()));
}
-void JSObject::preventExtensions(JSGlobalData& globalData)
+void JSObject::preventExtensions(VM& vm)
{
- enterDictionaryIndexingMode(globalData);
+ enterDictionaryIndexingMode(vm);
if (isExtensible())
- setStructure(globalData, Structure::preventExtensionsTransition(globalData, structure()));
+ setStructure(vm, Structure::preventExtensionsTransition(vm, structure()));
}
// This presently will flatten to an uncachable dictionary; this is suitable
@@ -1571,7 +1593,7 @@ void JSObject::preventExtensions(JSGlobalData& globalData)
void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
{
ASSERT(!staticFunctionsReified());
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// If this object's ClassInfo has no static properties, then nothing to reify!
// We can safely set the flag to avoid the expensive check again in the future.
@@ -1581,46 +1603,46 @@ void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
}
if (!structure()->isUncacheableDictionary())
- setStructure(globalData, Structure::toUncacheableDictionaryTransition(globalData, structure()));
+ setStructure(vm, Structure::toUncacheableDictionaryTransition(vm, structure()));
for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
const HashTable* hashTable = info->propHashTable(globalObject()->globalExec());
if (!hashTable)
continue;
PropertySlot slot;
- for (HashTable::ConstIterator iter = hashTable->begin(globalData); iter != hashTable->end(globalData); ++iter) {
+ for (HashTable::ConstIterator iter = hashTable->begin(vm); iter != hashTable->end(vm); ++iter) {
if (iter->attributes() & Function)
- setUpStaticFunctionSlot(globalObject()->globalExec(), *iter, this, Identifier(&globalData, iter->key()), slot);
+ setUpStaticFunctionSlot(globalObject()->globalExec(), *iter, this, Identifier(&vm, iter->key()), slot);
}
}
structure()->setStaticFunctionsReified();
}
-bool JSObject::removeDirect(JSGlobalData& globalData, PropertyName propertyName)
+bool JSObject::removeDirect(VM& vm, PropertyName propertyName)
{
- if (!isValidOffset(structure()->get(globalData, propertyName)))
+ if (!isValidOffset(structure()->get(vm, propertyName)))
return false;
PropertyOffset offset;
if (structure()->isUncacheableDictionary()) {
- offset = structure()->removePropertyWithoutTransition(globalData, propertyName);
+ offset = structure()->removePropertyWithoutTransition(vm, propertyName);
if (offset == invalidOffset)
return false;
- putUndefinedAtDirectOffset(offset);
+ putDirectUndefined(offset);
return true;
}
- setStructure(globalData, Structure::removePropertyTransition(globalData, structure(), propertyName, offset));
+ setStructure(vm, Structure::removePropertyTransition(vm, structure(), propertyName, offset));
if (offset == invalidOffset)
return false;
- putUndefinedAtDirectOffset(offset);
+ putDirectUndefined(offset);
return true;
}
NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, PropertyOffset offset)
{
- if (JSObject* getterFunction = asGetterSetter(getDirectOffset(offset))->getter()) {
+ if (JSObject* getterFunction = asGetterSetter(getDirect(offset))->getter()) {
if (!structure()->isDictionary())
slot.setCacheableGetterSlot(this, getterFunction, offset);
else
@@ -1629,49 +1651,13 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, PropertyO
slot.setUndefined();
}
-void JSObject::notifyUsedAsPrototype(JSGlobalData& globalData)
-{
- PropertyOffset offset = structure()->get(globalData, globalData.m_inheritorIDKey);
- if (isValidOffset(offset))
- return;
-
- PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, globalData.m_inheritorIDKey, jsUndefined(), DontEnum, slot, 0);
-
- // Note that this method makes the somewhat odd decision to not check if this
- // object currently has indexed accessors. We could do that check here, and if
- // indexed accessors were found, we could tell the global object to have a bad
- // time. But we avoid this, to allow the following to be always fast:
- //
- // 1) Create an object.
- // 2) Give it a setter or read-only property that happens to have a numeric name.
- // 3) Allocate objects that use this object as a prototype.
- //
- // This avoids anyone having a bad time. Even if the instance objects end up
- // having indexed storage, the creation of indexed storage leads to a prototype
- // chain walk that detects the presence of indexed setters and then does the
- // right thing. As a result, having a bad time only happens if you add an
- // indexed setter (or getter, or read-only field) to an object that is already
- // used as a prototype.
-}
-
-Structure* JSObject::createInheritorID(JSGlobalData& globalData)
-{
- Structure* inheritorID = createEmptyObjectStructure(globalData, globalObject(), this);
- ASSERT(inheritorID->isEmpty());
-
- PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, globalData.m_inheritorIDKey, inheritorID, DontEnum, slot, 0);
- return inheritorID;
-}
-
void JSObject::putIndexedDescriptor(ExecState* exec, SparseArrayEntry* entryInMap, PropertyDescriptor& descriptor, PropertyDescriptor& oldDescriptor)
{
if (descriptor.isDataDescriptor()) {
if (descriptor.value())
- entryInMap->set(exec->globalData(), this, descriptor.value());
+ entryInMap->set(exec->vm(), this, descriptor.value());
else if (oldDescriptor.isAccessorDescriptor())
- entryInMap->set(exec->globalData(), this, jsUndefined());
+ entryInMap->set(exec->vm(), this, jsUndefined());
entryInMap->attributes = descriptor.attributesOverridingCurrent(oldDescriptor) & ~Accessor;
return;
}
@@ -1690,11 +1676,11 @@ void JSObject::putIndexedDescriptor(ExecState* exec, SparseArrayEntry* entryInMa
GetterSetter* accessor = GetterSetter::create(exec);
if (getter)
- accessor->setGetter(exec->globalData(), getter);
+ accessor->setGetter(exec->vm(), getter);
if (setter)
- accessor->setSetter(exec->globalData(), setter);
+ accessor->setSetter(exec->vm(), setter);
- entryInMap->set(exec->globalData(), this, accessor);
+ entryInMap->set(exec->vm(), this, accessor);
entryInMap->attributes = descriptor.attributesOverridingCurrent(oldDescriptor) & ~ReadOnly;
return;
}
@@ -1718,14 +1704,14 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, Propert
return putDirectIndex(exec, index, descriptor.value(), 0, throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
}
- ensureArrayStorageExistsAndEnterDictionaryIndexingMode(exec->globalData());
+ ensureArrayStorageExistsAndEnterDictionaryIndexingMode(exec->vm());
}
if (descriptor.attributes() & (ReadOnly | Accessor))
- notifyPresenceOfIndexedAccessors(exec->globalData());
+ notifyPresenceOfIndexedAccessors(exec->vm());
SparseArrayValueMap* map = m_butterfly->arrayStorage()->m_sparseMap.get();
- ASSERT(map);
+ RELEASE_ASSERT(map);
// 1. Let current be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
SparseArrayValueMap::AddResult result = map->add(this, index);
@@ -1825,10 +1811,10 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, Propert
return true;
}
-SparseArrayValueMap* JSObject::allocateSparseIndexMap(JSGlobalData& globalData)
+SparseArrayValueMap* JSObject::allocateSparseIndexMap(VM& vm)
{
- SparseArrayValueMap* result = SparseArrayValueMap::create(globalData);
- arrayStorage()->m_sparseMap.set(globalData, this, result);
+ SparseArrayValueMap* result = SparseArrayValueMap::create(vm);
+ arrayStorage()->m_sparseMap.set(vm, this, result);
return result;
}
@@ -1882,23 +1868,23 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un
// or equal to the vector length.
ASSERT(i >= m_butterfly->vectorLength());
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
if (i >= MAX_ARRAY_INDEX - 1
|| (i >= MIN_SPARSE_ARRAY_INDEX
&& !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly)))) {
ASSERT(i <= MAX_ARRAY_INDEX);
- ensureArrayStorageSlow(globalData);
- SparseArrayValueMap* map = allocateSparseIndexMap(globalData);
+ ensureArrayStorageSlow(vm);
+ SparseArrayValueMap* map = allocateSparseIndexMap(vm);
map->putEntry(exec, this, i, value, false);
ASSERT(i >= arrayStorage()->length());
arrayStorage()->setLength(i + 1);
return;
}
- ensureLength(globalData, i + 1);
+ ensureLength(vm, i + 1);
- ASSERT(i < m_butterfly->vectorLength());
+ RELEASE_ASSERT(i < m_butterfly->vectorLength());
switch (indexingShape) {
case Int32Shape:
ASSERT(value.isInt32());
@@ -1914,7 +1900,7 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un
}
case ContiguousShape:
- m_butterfly->contiguous()[i].set(globalData, this, value);
+ m_butterfly->contiguous()[i].set(vm, this, value);
break;
default:
@@ -1924,7 +1910,7 @@ void JSObject::putByIndexBeyondVectorLengthWithoutAttributes(ExecState* exec, un
void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, ArrayStorage* storage)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// i should be a valid array index that is outside of the current vector.
ASSERT(i <= MAX_ARRAY_INDEX);
@@ -1942,15 +1928,15 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns
storage->setLength(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))) {
+ if (LIKELY((isDenseEnoughForVector(i, storage->m_numValuesInVector)) && increaseVectorLength(vm, i + 1))) {
// success! - reread m_storage since it has likely been reallocated, and store to the vector.
storage = arrayStorage();
- storage->m_vector[i].set(globalData, this, value);
+ storage->m_vector[i].set(vm, this, value);
++storage->m_numValuesInVector;
return;
}
// We don't want to, or can't use a vector to hold this property - allocate a sparse map & add the value.
- map = allocateSparseIndexMap(exec->globalData());
+ map = allocateSparseIndexMap(exec->vm());
map->putEntry(exec, this, i, value, shouldThrow);
return;
}
@@ -1971,7 +1957,7 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns
// 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)) {
+ if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->vm(), length)) {
map->putEntry(exec, this, i, value, shouldThrow);
return;
}
@@ -1984,19 +1970,19 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns
WriteBarrier<Unknown>* vector = storage->m_vector;
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
- vector[it->key].set(globalData, this, it->value.getNonSparseMode());
+ vector[it->key].set(vm, this, it->value.getNonSparseMode());
deallocateSparseIndexMap();
// Store the new property into the vector.
WriteBarrier<Unknown>& valueSlot = vector[i];
if (!valueSlot)
++storage->m_numValuesInVector;
- valueSlot.set(globalData, this, value);
+ valueSlot.set(vm, this, value);
}
void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// i should be a valid array index that is outside of the current vector.
ASSERT(i <= MAX_ARRAY_INDEX);
@@ -2006,22 +1992,22 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
if (indexingShouldBeSparse()) {
putByIndexBeyondVectorLengthWithArrayStorage(
exec, i, value, shouldThrow,
- ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
+ ensureArrayStorageExistsAndEnterDictionaryIndexingMode(vm));
break;
}
if (i >= MIN_SPARSE_ARRAY_INDEX) {
putByIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, shouldThrow, createArrayStorage(globalData, 0, 0));
+ exec, i, value, shouldThrow, createArrayStorage(vm, 0, 0));
break;
}
if (structure()->needsSlowPutIndexing()) {
- ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1));
- storage->m_vector[i].set(globalData, this, value);
+ ArrayStorage* storage = createArrayStorage(vm, i + 1, getNewVectorLength(0, 0, i + 1));
+ storage->m_vector[i].set(vm, this, value);
storage->m_numValuesInVector++;
break;
}
- createInitialContiguous(globalData, i + 1)[i].set(globalData, this, value);
+ createInitialContiguous(vm, i + 1)[i].set(vm, this, value);
break;
}
@@ -2060,13 +2046,13 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode, ArrayStorage* storage)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// i should be a valid array index that is outside of the current vector.
ASSERT(hasArrayStorage(structure()->indexingType()));
@@ -2089,15 +2075,15 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec,
if (LIKELY(
!attributes
&& (isDenseEnoughForVector(i, storage->m_numValuesInVector))
- && increaseVectorLength(globalData, i + 1))) {
+ && increaseVectorLength(vm, i + 1))) {
// success! - reread m_storage since it has likely been reallocated, and store to the vector.
storage = arrayStorage();
- storage->m_vector[i].set(globalData, this, value);
+ storage->m_vector[i].set(vm, 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.
- map = allocateSparseIndexMap(exec->globalData());
+ map = allocateSparseIndexMap(exec->vm());
return map->putDirect(exec, this, i, value, attributes, mode);
}
@@ -2118,7 +2104,7 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec,
// 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() || attributes || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->globalData(), length))
+ if (map->sparseMode() || attributes || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->vm(), length))
return map->putDirect(exec, this, i, value, attributes, mode);
// Reread m_storage after increaseVectorLength, update m_numValuesInVector.
@@ -2129,51 +2115,51 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec,
WriteBarrier<Unknown>* vector = storage->m_vector;
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
- vector[it->key].set(globalData, this, it->value.getNonSparseMode());
+ vector[it->key].set(vm, this, it->value.getNonSparseMode());
deallocateSparseIndexMap();
// Store the new property into the vector.
WriteBarrier<Unknown>& valueSlot = vector[i];
if (!valueSlot)
++storage->m_numValuesInVector;
- valueSlot.set(globalData, this, value);
+ valueSlot.set(vm, this, value);
return true;
}
bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
// i should be a valid array index that is outside of the current vector.
ASSERT(i <= MAX_ARRAY_INDEX);
if (attributes & (ReadOnly | Accessor))
- notifyPresenceOfIndexedAccessors(globalData);
+ notifyPresenceOfIndexedAccessors(vm);
switch (structure()->indexingType()) {
case ALL_BLANK_INDEXING_TYPES: {
if (indexingShouldBeSparse() || attributes) {
return putDirectIndexBeyondVectorLengthWithArrayStorage(
exec, i, value, attributes, mode,
- ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
+ ensureArrayStorageExistsAndEnterDictionaryIndexingMode(vm));
}
if (i >= MIN_SPARSE_ARRAY_INDEX) {
return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, createArrayStorage(globalData, 0, 0));
+ exec, i, value, attributes, mode, createArrayStorage(vm, 0, 0));
}
if (structure()->needsSlowPutIndexing()) {
- ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1));
- storage->m_vector[i].set(globalData, this, value);
+ ArrayStorage* storage = createArrayStorage(vm, i + 1, getNewVectorLength(0, 0, i + 1));
+ storage->m_vector[i].set(vm, this, value);
storage->m_numValuesInVector++;
return true;
}
- createInitialContiguous(globalData, i + 1)[i].set(globalData, this, value);
+ createInitialContiguous(vm, i + 1)[i].set(vm, this, value);
return true;
}
case ALL_UNDECIDED_INDEXING_TYPES: {
- convertUndecidedForValue(exec->globalData(), value);
+ convertUndecidedForValue(exec->vm(), value);
// Reloop.
return putDirectIndex(exec, i, value, attributes, mode);
}
@@ -2181,10 +2167,10 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
case ALL_INT32_INDEXING_TYPES: {
if (attributes & (ReadOnly | Accessor)) {
return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, convertInt32ToArrayStorage(globalData));
+ exec, i, value, attributes, mode, convertInt32ToArrayStorage(vm));
}
if (!value.isInt32()) {
- convertInt32ForValue(globalData, value);
+ convertInt32ForValue(vm, value);
return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
}
putByIndexBeyondVectorLengthWithoutAttributes<Int32Shape>(exec, i, value);
@@ -2194,15 +2180,15 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
case ALL_DOUBLE_INDEXING_TYPES: {
if (attributes & (ReadOnly | Accessor)) {
return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, convertDoubleToArrayStorage(globalData));
+ exec, i, value, attributes, mode, convertDoubleToArrayStorage(vm));
}
if (!value.isNumber()) {
- convertDoubleToContiguous(globalData);
+ convertDoubleToContiguous(vm);
return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
}
double valueAsDouble = value.asNumber();
if (valueAsDouble != valueAsDouble) {
- convertDoubleToContiguous(globalData);
+ convertDoubleToContiguous(vm);
return putDirectIndexBeyondVectorLength(exec, i, value, attributes, mode);
}
putByIndexBeyondVectorLengthWithoutAttributes<DoubleShape>(exec, i, value);
@@ -2212,7 +2198,7 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
case ALL_CONTIGUOUS_INDEXING_TYPES: {
if (attributes & (ReadOnly | Accessor)) {
return putDirectIndexBeyondVectorLengthWithArrayStorage(
- exec, i, value, attributes, mode, convertContiguousToArrayStorage(globalData));
+ exec, i, value, attributes, mode, convertContiguousToArrayStorage(vm));
}
putByIndexBeyondVectorLengthWithoutAttributes<ContiguousShape>(exec, i, value);
return true;
@@ -2222,11 +2208,21 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, arrayStorage());
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
+void JSObject::putDirectNativeFunction(ExecState* exec, JSGlobalObject* globalObject, const PropertyName& propertyName, unsigned functionLength, NativeFunction nativeFunction, Intrinsic intrinsic, unsigned attributes)
+{
+ StringImpl* name = propertyName.publicName();
+ ASSERT(name);
+
+ JSFunction* function =
+ JSFunction::create(exec, globalObject, functionLength, name, nativeFunction, intrinsic);
+ putDirect(exec->vm(), propertyName, function, attributes);
+}
+
ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned currentVectorLength, unsigned currentLength, unsigned desiredLength)
{
ASSERT(desiredLength <= MAX_STORAGE_VECTOR_LENGTH);
@@ -2313,7 +2309,7 @@ unsigned JSObject::countElements()
}
}
-bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength)
+bool JSObject::increaseVectorLength(VM& vm, unsigned newLength)
{
// This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
// to the vector. Callers have to account for that, because they can do it more efficiently.
@@ -2333,7 +2329,7 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
// Fast case - there is no precapacity. In these cases a realloc makes sense.
if (LIKELY(!indexBias)) {
- Butterfly* newButterfly = storage->butterfly()->growArrayRight(globalData, structure(), structure()->outOfLineCapacity(), true, ArrayStorage::sizeFor(vectorLength), ArrayStorage::sizeFor(newVectorLength));
+ Butterfly* newButterfly = storage->butterfly()->growArrayRight(vm, structure(), structure()->outOfLineCapacity(), true, ArrayStorage::sizeFor(vectorLength), ArrayStorage::sizeFor(newVectorLength));
if (!newButterfly)
return false;
m_butterfly = newButterfly;
@@ -2344,7 +2340,7 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
// Remove some, but not all of the precapacity. Atomic decay, & capped to not overflow array length.
unsigned newIndexBias = std::min(indexBias >> 1, MAX_STORAGE_VECTOR_LENGTH - newVectorLength);
Butterfly* newButterfly = storage->butterfly()->resizeArray(
- globalData,
+ vm,
structure()->outOfLineCapacity(), true, ArrayStorage::sizeFor(vectorLength),
newIndexBias, true, ArrayStorage::sizeFor(newVectorLength));
if (!newButterfly)
@@ -2356,7 +2352,7 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength
return true;
}
-void JSObject::ensureLengthSlow(JSGlobalData& globalData, unsigned length)
+void JSObject::ensureLengthSlow(VM& vm, unsigned length)
{
ASSERT(length < MAX_ARRAY_INDEX);
ASSERT(hasContiguous(structure()->indexingType()) || hasInt32(structure()->indexingType()) || hasDouble(structure()->indexingType()) || hasUndecided(structure()->indexingType()));
@@ -2367,33 +2363,33 @@ void JSObject::ensureLengthSlow(JSGlobalData& globalData, unsigned length)
MAX_STORAGE_VECTOR_LENGTH);
unsigned oldVectorLength = m_butterfly->vectorLength();
m_butterfly = m_butterfly->growArrayRight(
- globalData, structure(), structure()->outOfLineCapacity(), true,
+ vm, structure(), structure()->outOfLineCapacity(), true,
oldVectorLength * sizeof(EncodedJSValue),
newVectorLength * sizeof(EncodedJSValue));
if (hasDouble(structure()->indexingType())) {
for (unsigned i = oldVectorLength; i < newVectorLength; ++i)
- m_butterfly->contiguousDouble()[i] = QNaN;
+ m_butterfly->contiguousDouble().data()[i] = QNaN;
}
m_butterfly->setVectorLength(newVectorLength);
}
-Butterfly* JSObject::growOutOfLineStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
+Butterfly* JSObject::growOutOfLineStorage(VM& vm, size_t oldSize, size_t newSize)
{
ASSERT(newSize > oldSize);
// It's important that this function not rely on structure(), for the property
// capacity, since we might have already mutated the structure in-place.
- return m_butterfly->growPropertyStorage(globalData, structure(), oldSize, newSize);
+ return m_butterfly->growPropertyStorage(vm, structure(), oldSize, newSize);
}
bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
{
unsigned attributes = 0;
JSCell* cell = 0;
- PropertyOffset offset = object->structure()->get(exec->globalData(), propertyName, attributes, cell);
+ PropertyOffset offset = object->structure()->get(exec->vm(), propertyName, attributes, cell);
if (isValidOffset(offset)) {
- descriptor.setDescriptor(object->getDirectOffset(offset), attributes);
+ descriptor.setDescriptor(object->getDirect(offset), attributes);
return true;
}
@@ -2451,7 +2447,7 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
@@ -2475,9 +2471,9 @@ static bool putDescriptor(ExecState* exec, JSObject* target, PropertyName proper
if (descriptor.isGenericDescriptor() && oldDescriptor.isAccessorDescriptor()) {
GetterSetter* accessor = GetterSetter::create(exec);
if (oldDescriptor.getterPresent())
- accessor->setGetter(exec->globalData(), oldDescriptor.getterObject());
+ accessor->setGetter(exec->vm(), oldDescriptor.getterObject());
if (oldDescriptor.setterPresent())
- accessor->setSetter(exec->globalData(), oldDescriptor.setterObject());
+ accessor->setSetter(exec->vm(), oldDescriptor.setterObject());
target->putDirectAccessor(exec, propertyName, accessor, attributes | Accessor);
return true;
}
@@ -2486,7 +2482,7 @@ static bool putDescriptor(ExecState* exec, JSObject* target, PropertyName proper
newValue = descriptor.value();
else if (oldDescriptor.value())
newValue = oldDescriptor.value();
- target->putDirect(exec->globalData(), propertyName, newValue, attributes & ~Accessor);
+ target->putDirect(exec->vm(), propertyName, newValue, attributes & ~Accessor);
if (attributes & ReadOnly)
target->structure()->setContainsReadOnlyProperties();
return true;
@@ -2495,13 +2491,13 @@ static bool putDescriptor(ExecState* exec, JSObject* target, PropertyName proper
GetterSetter* accessor = GetterSetter::create(exec);
if (descriptor.getterPresent())
- accessor->setGetter(exec->globalData(), descriptor.getterObject());
+ accessor->setGetter(exec->vm(), descriptor.getterObject());
else if (oldDescriptor.getterPresent())
- accessor->setGetter(exec->globalData(), oldDescriptor.getterObject());
+ accessor->setGetter(exec->vm(), oldDescriptor.getterObject());
if (descriptor.setterPresent())
- accessor->setSetter(exec->globalData(), descriptor.setterObject());
+ accessor->setSetter(exec->vm(), descriptor.setterObject());
else if (oldDescriptor.setterPresent())
- accessor->setSetter(exec->globalData(), oldDescriptor.setterObject());
+ accessor->setSetter(exec->vm(), oldDescriptor.setterObject());
target->putDirectAccessor(exec, propertyName, accessor, attributes | Accessor);
return true;
@@ -2511,7 +2507,7 @@ void JSObject::putDirectMayBeIndex(ExecState* exec, PropertyName propertyName, J
{
unsigned asIndex = propertyName.asIndex();
if (asIndex == PropertyName::NotAnIndex)
- putDirect(exec->globalData(), propertyName, value);
+ putDirect(exec->vm(), propertyName, value);
else
putDirectIndex(exec, asIndex, value);
}
@@ -2519,18 +2515,18 @@ void JSObject::putDirectMayBeIndex(ExecState* exec, PropertyName propertyName, J
class DefineOwnPropertyScope {
public:
DefineOwnPropertyScope(ExecState* exec)
- : m_globalData(exec->globalData())
+ : m_vm(exec->vm())
{
- m_globalData.setInDefineOwnProperty(true);
+ m_vm.setInDefineOwnProperty(true);
}
~DefineOwnPropertyScope()
{
- m_globalData.setInDefineOwnProperty(false);
+ m_vm.setInDefineOwnProperty(false);
}
private:
- JSGlobalData& m_globalData;
+ VM& m_vm;
};
bool JSObject::defineOwnNonIndexProperty(ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException)
@@ -2631,14 +2627,14 @@ bool JSObject::defineOwnNonIndexProperty(ExecState* exec, PropertyName propertyN
return false;
}
}
- JSValue accessor = getDirect(exec->globalData(), propertyName);
+ JSValue accessor = getDirect(exec->vm(), propertyName);
if (!accessor)
return false;
GetterSetter* getterSetter = asGetterSetter(accessor);
if (descriptor.setterPresent())
- getterSetter->setSetter(exec->globalData(), descriptor.setterObject());
+ getterSetter->setSetter(exec->vm(), descriptor.setterObject());
if (descriptor.getterPresent())
- getterSetter->setGetter(exec->globalData(), descriptor.getterObject());
+ getterSetter->setGetter(exec->vm(), descriptor.getterObject());
if (current.attributesEqual(descriptor))
return true;
methodTable()->deleteProperty(this, exec, propertyName);
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 428e51f3c..c62dc2aec 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -37,7 +37,7 @@
#include "PutPropertySlot.h"
#include "Structure.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSString.h"
#include "SlotVisitorInlines.h"
#include "SparseArrayValueMap.h"
@@ -121,16 +121,8 @@ public:
JS_EXPORT_PRIVATE static String className(const JSObject*);
JSValue prototype() const;
- void setPrototype(JSGlobalData&, JSValue prototype);
- bool setPrototypeWithCycleCheck(JSGlobalData&, JSValue prototype);
-
- Structure* inheritorID(JSGlobalData&);
- void notifyUsedAsPrototype(JSGlobalData&);
-
- bool mayBeUsedAsPrototype(JSGlobalData& globalData)
- {
- return isValidOffset(structure()->get(globalData, globalData.m_inheritorIDKey));
- }
+ void setPrototype(VM&, JSValue prototype);
+ bool setPrototypeWithCycleCheck(VM&, JSValue prototype);
bool mayInterceptIndexedAccesses()
{
@@ -170,7 +162,7 @@ public:
void putByIndexInline(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
if (canSetIndexQuickly(propertyName)) {
- setIndexQuickly(exec->globalData(), propertyName, value);
+ setIndexQuickly(exec->vm(), propertyName, value);
return;
}
methodTable()->putByIndex(this, exec, propertyName, value, shouldThrow);
@@ -184,7 +176,7 @@ public:
bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes, PutDirectIndexMode mode)
{
if (!attributes && canSetIndexQuicklyForPutDirect(propertyName)) {
- setIndexQuickly(exec->globalData(), propertyName, value);
+ setIndexQuickly(exec->vm(), propertyName, value);
return true;
}
return putDirectIndexBeyondVectorLength(exec, propertyName, value, attributes, mode);
@@ -217,7 +209,7 @@ public:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i];
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
@@ -233,7 +225,7 @@ public:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->m_vector[i].get();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return JSValue();
}
}
@@ -262,7 +254,7 @@ public:
return m_butterfly->arrayStorage()->m_vector[i].get();
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
return JSValue();
@@ -302,7 +294,7 @@ public:
return i < m_butterfly->arrayStorage()->vectorLength()
&& !!m_butterfly->arrayStorage()->m_vector[i];
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
@@ -319,25 +311,25 @@ public:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->vectorLength();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
- void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v)
+ void setIndexQuickly(VM& vm, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
case ALL_INT32_INDEXING_TYPES: {
ASSERT(i < m_butterfly->vectorLength());
if (!v.isInt32()) {
- convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(globalData, i, v);
+ convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(vm, i, v);
return;
}
// Fall through to contiguous case.
}
case ALL_CONTIGUOUS_INDEXING_TYPES: {
ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, v);
+ m_butterfly->contiguous()[i].set(vm, this, v);
if (i >= m_butterfly->publicLength())
m_butterfly->setPublicLength(i + 1);
break;
@@ -345,12 +337,12 @@ public:
case ALL_DOUBLE_INDEXING_TYPES: {
ASSERT(i < m_butterfly->vectorLength());
if (!v.isNumber()) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
+ convertDoubleToContiguousWhilePerformingSetIndex(vm, i, v);
return;
}
double value = v.asNumber();
if (value != value) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
+ convertDoubleToContiguousWhilePerformingSetIndex(vm, i, v);
return;
}
m_butterfly->contiguousDouble()[i] = value;
@@ -362,7 +354,7 @@ public:
ArrayStorage* storage = m_butterfly->arrayStorage();
WriteBarrier<Unknown>& x = storage->m_vector[i];
JSValue old = x.get();
- x.set(globalData, this, v);
+ x.set(vm, this, v);
if (!old) {
++storage->m_numValuesInVector;
if (i >= storage->length())
@@ -371,22 +363,22 @@ public:
break;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
- void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v)
+ void initializeIndex(VM& vm, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
case ALL_UNDECIDED_INDEXING_TYPES: {
- setIndexQuicklyToUndecided(globalData, i, v);
+ setIndexQuicklyToUndecided(vm, i, v);
break;
}
case ALL_INT32_INDEXING_TYPES: {
ASSERT(i < m_butterfly->publicLength());
ASSERT(i < m_butterfly->vectorLength());
if (!v.isInt32()) {
- convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(globalData, i, v);
+ convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(vm, i, v);
break;
}
// Fall through.
@@ -394,19 +386,19 @@ public:
case ALL_CONTIGUOUS_INDEXING_TYPES: {
ASSERT(i < m_butterfly->publicLength());
ASSERT(i < m_butterfly->vectorLength());
- m_butterfly->contiguous()[i].set(globalData, this, v);
+ m_butterfly->contiguous()[i].set(vm, this, v);
break;
}
case ALL_DOUBLE_INDEXING_TYPES: {
ASSERT(i < m_butterfly->publicLength());
ASSERT(i < m_butterfly->vectorLength());
if (!v.isNumber()) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
+ convertDoubleToContiguousWhilePerformingSetIndex(vm, i, v);
return;
}
double value = v.asNumber();
if (value != value) {
- convertDoubleToContiguousWhilePerformingSetIndex(globalData, i, v);
+ convertDoubleToContiguousWhilePerformingSetIndex(vm, i, v);
return;
}
m_butterfly->contiguousDouble()[i] = value;
@@ -416,11 +408,11 @@ public:
ArrayStorage* storage = m_butterfly->arrayStorage();
ASSERT(i < storage->length());
ASSERT(i < storage->m_numValuesInVector);
- storage->m_vector[i].set(globalData, this, v);
+ storage->m_vector[i].set(vm, this, v);
break;
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
@@ -436,7 +428,7 @@ public:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->m_sparseMap;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
@@ -453,12 +445,12 @@ public:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->inSparseMode();
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
}
- void enterDictionaryIndexingMode(JSGlobalData&);
+ void enterDictionaryIndexingMode(VM&);
// putDirect is effectively an unchecked vesion of 'defineOwnProperty':
// - the prototype chain is not consulted
@@ -466,9 +458,9 @@ public:
// - attributes will be respected (after the call the property will exist with the given attributes)
// - the property name is assumed to not be an index.
JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
- void putDirect(JSGlobalData&, PropertyName, JSValue, unsigned attributes = 0);
- void putDirect(JSGlobalData&, PropertyName, JSValue, PutPropertySlot&);
- void putDirectWithoutTransition(JSGlobalData&, PropertyName, JSValue, unsigned attributes = 0);
+ void putDirect(VM&, PropertyName, JSValue, unsigned attributes = 0);
+ void putDirect(VM&, PropertyName, JSValue, PutPropertySlot&);
+ void putDirectWithoutTransition(VM&, PropertyName, JSValue, unsigned attributes = 0);
void putDirectAccessor(ExecState*, PropertyName, JSValue, unsigned attributes);
bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
@@ -501,25 +493,18 @@ public:
bool getPropertySpecificValue(ExecState*, PropertyName, JSCell*& specificFunction) const;
// This get function only looks at the property map.
- JSValue getDirect(JSGlobalData& globalData, PropertyName propertyName) const
+ JSValue getDirect(VM& vm, PropertyName propertyName) const
{
- PropertyOffset offset = structure()->get(globalData, propertyName);
- checkOffset(offset, structure()->typeInfo().type());
- return offset != invalidOffset ? getDirectOffset(offset) : JSValue();
+ PropertyOffset offset = structure()->get(vm, propertyName);
+ checkOffset(offset, structure()->inlineCapacity());
+ return offset != invalidOffset ? getDirect(offset) : JSValue();
}
- WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, PropertyName propertyName)
+ PropertyOffset getDirectOffset(VM& vm, PropertyName propertyName)
{
- PropertyOffset offset = structure()->get(globalData, propertyName);
- checkOffset(offset, structure()->typeInfo().type());
- return isValidOffset(offset) ? locationForOffset(offset) : 0;
- }
-
- WriteBarrierBase<Unknown>* getDirectLocation(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes)
- {
- JSCell* specificFunction;
- PropertyOffset offset = structure()->get(globalData, propertyName, attributes, specificFunction);
- return isValidOffset(offset) ? locationForOffset(offset) : 0;
+ PropertyOffset offset = structure()->get(vm, propertyName);
+ checkOffset(offset, structure()->inlineCapacity());
+ return offset;
}
bool hasInlineStorage() const { return structure()->hasInlineStorage(); }
@@ -562,21 +547,9 @@ public:
return &outOfLineStorage()[offsetInOutOfLineStorage(offset)];
}
- PropertyOffset offsetForLocation(WriteBarrierBase<Unknown>* location) const
- {
- PropertyOffset result;
- size_t offsetInInlineStorage = location - inlineStorageUnsafe();
- if (offsetInInlineStorage < static_cast<size_t>(firstOutOfLineOffset))
- result = offsetInInlineStorage;
- else
- result = outOfLineStorage() - location + (firstOutOfLineOffset - 1);
- validateOffset(result, structure()->typeInfo().type());
- return result;
- }
+ void transitionTo(VM&, Structure*);
- void transitionTo(JSGlobalData&, Structure*);
-
- bool removeDirect(JSGlobalData&, PropertyName); // Return true if anything is removed.
+ bool removeDirect(VM&, PropertyName); // Return true if anything is removed.
bool hasCustomProperties() { return structure()->didTransition(); }
bool hasGetterSetterProperties() { return structure()->hasGetterSetterProperties(); }
@@ -585,26 +558,29 @@ public:
// - provides no special handling for __proto__
// - does not walk the prototype chain (to check for accessors or non-writable properties).
// This is used by JSActivation.
- bool putOwnDataProperty(JSGlobalData&, PropertyName, JSValue, PutPropertySlot&);
+ bool putOwnDataProperty(VM&, PropertyName, JSValue, PutPropertySlot&);
// Fast access to known property offsets.
- JSValue getDirectOffset(PropertyOffset offset) const { return locationForOffset(offset)->get(); }
- void putDirectOffset(JSGlobalData& globalData, PropertyOffset offset, JSValue value) { locationForOffset(offset)->set(globalData, this, value); }
- void putUndefinedAtDirectOffset(PropertyOffset offset) { locationForOffset(offset)->setUndefined(); }
+ JSValue getDirect(PropertyOffset offset) const { return locationForOffset(offset)->get(); }
+ void putDirect(VM& vm, PropertyOffset offset, JSValue value) { locationForOffset(offset)->set(vm, this, value); }
+ void putDirectUndefined(PropertyOffset offset) { locationForOffset(offset)->setUndefined(); }
+
+ void putDirectNativeFunction(ExecState*, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow);
bool isGlobalObject() const;
bool isVariableObject() const;
+ bool isStaticScopeObject() const;
bool isNameScopeObject() const;
bool isActivationObject() const;
bool isErrorInstance() const;
- void seal(JSGlobalData&);
- void freeze(JSGlobalData&);
- JS_EXPORT_PRIVATE void preventExtensions(JSGlobalData&);
- bool isSealed(JSGlobalData& globalData) { return structure()->isSealed(globalData); }
- bool isFrozen(JSGlobalData& globalData) { return structure()->isFrozen(globalData); }
+ void seal(VM&);
+ void freeze(VM&);
+ JS_EXPORT_PRIVATE void preventExtensions(VM&);
+ bool isSealed(VM& vm) { return structure()->isSealed(vm); }
+ bool isFrozen(VM& vm) { return structure()->isFrozen(vm); }
bool isExtensible() { return structure()->isExtensible(); }
bool indexingShouldBeSparse()
{
@@ -615,16 +591,16 @@ public:
bool staticFunctionsReified() { return structure()->staticFunctionsReified(); }
void reifyStaticFunctionsForDelete(ExecState* exec);
- JS_EXPORT_PRIVATE Butterfly* growOutOfLineStorage(JSGlobalData&, size_t oldSize, size_t newSize);
- void setButterfly(JSGlobalData&, Butterfly*, Structure*);
+ JS_EXPORT_PRIVATE Butterfly* growOutOfLineStorage(VM&, size_t oldSize, size_t newSize);
+ void setButterfly(VM&, Butterfly*, Structure*);
void setButterflyWithoutChangingStructure(Butterfly*); // You probably don't want to call this.
- void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, unsigned oldCapacity, Structure*);
- void setStructureAndReallocateStorageIfNecessary(JSGlobalData&, Structure*);
+ void setStructureAndReallocateStorageIfNecessary(VM&, unsigned oldCapacity, Structure*);
+ void setStructureAndReallocateStorageIfNecessary(VM&, Structure*);
- void flattenDictionaryObject(JSGlobalData& globalData)
+ void flattenDictionaryObject(VM& vm)
{
- structure()->flattenDictionaryStructure(globalData, this);
+ structure()->flattenDictionaryStructure(vm, this);
}
JSGlobalObject* globalObject() const
@@ -634,7 +610,7 @@ public:
return structure()->globalObject();
}
- void switchToSlowPutArrayStorage(JSGlobalData&);
+ void switchToSlowPutArrayStorage(VM&);
// The receiver is the prototype in this case. The following:
//
@@ -649,46 +625,57 @@ public:
// indexing should be sparse, we're having a bad time, or because
// we already have a more general form of storage (double,
// contiguous, array storage).
- WriteBarrier<Unknown>* ensureInt32(JSGlobalData& globalData)
+ ContiguousJSValues ensureInt32(VM& vm)
{
if (LIKELY(hasInt32(structure()->indexingType())))
return m_butterfly->contiguousInt32();
- return ensureInt32Slow(globalData);
+ return ensureInt32Slow(vm);
}
// Returns 0 if double storage cannot be created - either because
// indexing should be sparse, we're having a bad time, or because
// we already have a more general form of storage (contiguous,
// or array storage).
- double* ensureDouble(JSGlobalData& globalData)
+ ContiguousDoubles ensureDouble(VM& vm)
{
if (LIKELY(hasDouble(structure()->indexingType())))
return m_butterfly->contiguousDouble();
- return ensureDoubleSlow(globalData);
+ return ensureDoubleSlow(vm);
}
// Returns 0 if contiguous storage cannot be created - either because
// indexing should be sparse or because we're having a bad time.
- WriteBarrier<Unknown>* ensureContiguous(JSGlobalData& globalData)
+ ContiguousJSValues ensureContiguous(VM& vm)
{
if (LIKELY(hasContiguous(structure()->indexingType())))
return m_butterfly->contiguous();
- return ensureContiguousSlow(globalData);
+ return ensureContiguousSlow(vm);
+ }
+
+ // Same as ensureContiguous(), except that if the indexed storage is in
+ // double mode, then it does a rage conversion to contiguous: it
+ // attempts to convert each double to an int32.
+ ContiguousJSValues rageEnsureContiguous(VM& vm)
+ {
+ if (LIKELY(hasContiguous(structure()->indexingType())))
+ return m_butterfly->contiguous();
+
+ return rageEnsureContiguousSlow(vm);
}
// Ensure that the object is in a mode where it has array storage. Use
// this if you're about to perform actions that would have required the
// object to be converted to have array storage, if it didn't have it
// already.
- ArrayStorage* ensureArrayStorage(JSGlobalData& globalData)
+ ArrayStorage* ensureArrayStorage(VM& vm)
{
if (LIKELY(hasArrayStorage(structure()->indexingType())))
return m_butterfly->arrayStorage();
- return ensureArrayStorageSlow(globalData);
+ return ensureArrayStorageSlow(vm);
}
static size_t offsetOfInlineStorage();
@@ -706,9 +693,9 @@ public:
static JS_EXPORTDATA const ClassInfo s_info;
protected:
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
ASSERT(!structure()->outOfLineCapacity());
ASSERT(structure()->isEmpty());
@@ -717,16 +704,14 @@ protected:
ASSERT(classInfo());
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
// To instantiate objects you likely want JSFinalObject, below.
// To create derived types you likely want JSNonFinalObject, below.
- JSObject(JSGlobalData&, Structure*, Butterfly* = 0);
-
- void resetInheritorID(JSGlobalData&);
+ JSObject(VM&, Structure*, Butterfly* = 0);
void visitButterfly(SlotVisitor&, Butterfly*, size_t storageSize);
void copyButterfly(CopyVisitor&, Butterfly*, size_t storageSize);
@@ -752,41 +737,42 @@ protected:
}
}
- Butterfly* createInitialUndecided(JSGlobalData&, unsigned length);
- WriteBarrier<Unknown>* createInitialInt32(JSGlobalData&, unsigned length);
- double* createInitialDouble(JSGlobalData&, unsigned length);
- WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length);
+ Butterfly* createInitialUndecided(VM&, unsigned length);
+ ContiguousJSValues createInitialInt32(VM&, unsigned length);
+ ContiguousDoubles createInitialDouble(VM&, unsigned length);
+ ContiguousJSValues createInitialContiguous(VM&, unsigned length);
- void convertUndecidedForValue(JSGlobalData&, JSValue);
- void convertInt32ForValue(JSGlobalData&, JSValue);
+ void convertUndecidedForValue(VM&, JSValue);
+ void convertInt32ForValue(VM&, JSValue);
- ArrayStorage* createArrayStorage(JSGlobalData&, unsigned length, unsigned vectorLength);
- ArrayStorage* createInitialArrayStorage(JSGlobalData&);
+ ArrayStorage* createArrayStorage(VM&, unsigned length, unsigned vectorLength);
+ ArrayStorage* createInitialArrayStorage(VM&);
- WriteBarrier<Unknown>* convertUndecidedToInt32(JSGlobalData&);
- double* convertUndecidedToDouble(JSGlobalData&);
- WriteBarrier<Unknown>* convertUndecidedToContiguous(JSGlobalData&);
- ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertUndecidedToArrayStorage(JSGlobalData&);
+ ContiguousJSValues convertUndecidedToInt32(VM&);
+ ContiguousDoubles convertUndecidedToDouble(VM&);
+ ContiguousJSValues convertUndecidedToContiguous(VM&);
+ ArrayStorage* convertUndecidedToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
+ ArrayStorage* convertUndecidedToArrayStorage(VM&, NonPropertyTransition);
+ ArrayStorage* convertUndecidedToArrayStorage(VM&);
- double* convertInt32ToDouble(JSGlobalData&);
- WriteBarrier<Unknown>* convertInt32ToContiguous(JSGlobalData&);
- ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertInt32ToArrayStorage(JSGlobalData&);
-
- WriteBarrier<Unknown>* convertDoubleToContiguous(JSGlobalData&);
- ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertDoubleToArrayStorage(JSGlobalData&);
+ ContiguousDoubles convertInt32ToDouble(VM&);
+ ContiguousJSValues convertInt32ToContiguous(VM&);
+ ArrayStorage* convertInt32ToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
+ ArrayStorage* convertInt32ToArrayStorage(VM&, NonPropertyTransition);
+ ArrayStorage* convertInt32ToArrayStorage(VM&);
+
+ ContiguousJSValues convertDoubleToContiguous(VM&);
+ ContiguousJSValues rageConvertDoubleToContiguous(VM&);
+ ArrayStorage* convertDoubleToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
+ ArrayStorage* convertDoubleToArrayStorage(VM&, NonPropertyTransition);
+ ArrayStorage* convertDoubleToArrayStorage(VM&);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition);
- ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&);
+ ArrayStorage* convertContiguousToArrayStorage(VM&, NonPropertyTransition, unsigned neededLength);
+ ArrayStorage* convertContiguousToArrayStorage(VM&, NonPropertyTransition);
+ ArrayStorage* convertContiguousToArrayStorage(VM&);
- ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData&);
+ ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(VM&);
bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException);
@@ -794,24 +780,24 @@ protected:
void putByIndexBeyondVectorLengthWithoutAttributes(ExecState*, unsigned propertyName, JSValue);
void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*);
- bool increaseVectorLength(JSGlobalData&, unsigned newLength);
+ bool increaseVectorLength(VM&, unsigned newLength);
void deallocateSparseIndexMap();
bool defineOwnIndexedProperty(ExecState*, unsigned, PropertyDescriptor&, bool throwException);
- SparseArrayValueMap* allocateSparseIndexMap(JSGlobalData&);
+ SparseArrayValueMap* allocateSparseIndexMap(VM&);
- void notifyPresenceOfIndexedAccessors(JSGlobalData&);
+ void notifyPresenceOfIndexedAccessors(VM&);
bool attemptToInterceptPutByIndexOnHole(ExecState*, unsigned index, JSValue, bool shouldThrow);
// Call this if you want setIndexQuickly to succeed and you're sure that
// the array is contiguous.
- void ensureLength(JSGlobalData& globalData, unsigned length)
+ void ensureLength(VM& vm, unsigned length)
{
ASSERT(length < MAX_ARRAY_INDEX);
ASSERT(hasContiguous(structure()->indexingType()) || hasInt32(structure()->indexingType()) || hasDouble(structure()->indexingType()) || hasUndecided(structure()->indexingType()));
if (m_butterfly->vectorLength() < length)
- ensureLengthSlow(globalData, length);
+ ensureLengthSlow(vm, length);
if (m_butterfly->publicLength() < length)
m_butterfly->setPublicLength(length);
@@ -827,7 +813,7 @@ protected:
// as if it contained JSValues. But it won't always contain JSValues.
// Make sure you cast this to the appropriate type before using.
template<IndexingType indexingType>
- WriteBarrier<Unknown>* indexingData()
+ ContiguousJSValues indexingData()
{
switch (indexingType) {
case ALL_INT32_INDEXING_TYPES:
@@ -836,15 +822,15 @@ protected:
return m_butterfly->contiguous();
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_vector;
-
+ return m_butterfly->arrayStorage()->vector();
+
default:
CRASH();
- return 0;
+ return ContiguousJSValues();
}
}
- WriteBarrier<Unknown>* currentIndexingData()
+ ContiguousJSValues currentIndexingData()
{
switch (structure()->indexingType()) {
case ALL_INT32_INDEXING_TYPES:
@@ -852,11 +838,11 @@ protected:
return m_butterfly->contiguous();
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
- return m_butterfly->arrayStorage()->m_vector;
+ return m_butterfly->arrayStorage()->vector();
default:
CRASH();
- return 0;
+ return ContiguousJSValues();
}
}
@@ -931,18 +917,17 @@ private:
void isObject();
void isString();
- Butterfly* createInitialIndexedStorage(JSGlobalData&, unsigned length, size_t elementSize);
+ Butterfly* createInitialIndexedStorage(VM&, unsigned length, size_t elementSize);
- ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(JSGlobalData&, ArrayStorage*);
+ ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(VM&, ArrayStorage*);
template<PutMode>
- bool putDirectInternal(JSGlobalData&, PropertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*);
+ bool putDirectInternal(VM&, PropertyName, JSValue, unsigned attr, PutPropertySlot&, JSCell*);
bool inlineGetOwnPropertySlot(ExecState*, PropertyName, PropertySlot&);
JS_EXPORT_PRIVATE void fillGetterPropertySlot(PropertySlot&, PropertyOffset);
const HashEntry* findPropertyHashEntry(ExecState*, PropertyName) const;
- Structure* createInheritorID(JSGlobalData&);
void putIndexedDescriptor(ExecState*, SparseArrayEntry*, PropertyDescriptor&, PropertyDescriptor& old);
@@ -955,24 +940,29 @@ private:
JS_EXPORT_PRIVATE bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&);
- ArrayStorage* constructConvertedArrayStorageWithoutCopyingElements(JSGlobalData&, unsigned neededLength);
-
- JS_EXPORT_PRIVATE void setIndexQuicklyToUndecided(JSGlobalData&, unsigned index, JSValue);
- JS_EXPORT_PRIVATE void convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(JSGlobalData&, unsigned index, JSValue);
- JS_EXPORT_PRIVATE void convertDoubleToContiguousWhilePerformingSetIndex(JSGlobalData&, unsigned index, JSValue);
+ ArrayStorage* constructConvertedArrayStorageWithoutCopyingElements(VM&, unsigned neededLength);
- void ensureLengthSlow(JSGlobalData&, unsigned length);
+ JS_EXPORT_PRIVATE void setIndexQuicklyToUndecided(VM&, unsigned index, JSValue);
+ JS_EXPORT_PRIVATE void convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(VM&, unsigned index, JSValue);
+ JS_EXPORT_PRIVATE void convertDoubleToContiguousWhilePerformingSetIndex(VM&, unsigned index, JSValue);
- WriteBarrier<Unknown>* ensureInt32Slow(JSGlobalData&);
- double* ensureDoubleSlow(JSGlobalData&);
- WriteBarrier<Unknown>* ensureContiguousSlow(JSGlobalData&);
- ArrayStorage* ensureArrayStorageSlow(JSGlobalData&);
+ void ensureLengthSlow(VM&, unsigned length);
+ ContiguousJSValues ensureInt32Slow(VM&);
+ ContiguousDoubles ensureDoubleSlow(VM&);
+ ContiguousJSValues ensureContiguousSlow(VM&);
+ ContiguousJSValues rageEnsureContiguousSlow(VM&);
+ ArrayStorage* ensureArrayStorageSlow(VM&);
+
+ enum DoubleToContiguousMode { EncodeValueAsDouble, RageConvertDoubleToValue };
+ template<DoubleToContiguousMode mode>
+ ContiguousJSValues genericConvertDoubleToContiguous(VM&);
+ ContiguousJSValues ensureContiguousSlow(VM&, DoubleToContiguousMode);
+
protected:
Butterfly* m_butterfly;
};
-
// JSNonFinalObject is a type of JSObject that has some internal storage,
// but also preserves some space in the collector cell for additional
// data members in derived types.
@@ -982,20 +972,20 @@ class JSNonFinalObject : public JSObject {
public:
typedef JSObject Base;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
- explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0)
- : JSObject(globalData, structure, butterfly)
+ explicit JSNonFinalObject(VM& vm, Structure* structure, Butterfly* butterfly = 0)
+ : JSObject(vm, structure, butterfly)
{
}
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(!this->structure()->totalStorageCapacity());
ASSERT(classInfo());
}
@@ -1011,10 +1001,22 @@ class JSFinalObject : public JSObject {
public:
typedef JSObject Base;
+ static const unsigned defaultSize = 64;
+ static inline unsigned defaultInlineCapacity()
+ {
+ return (defaultSize - allocationSize(0)) / sizeof(WriteBarrier<Unknown>);
+ }
+
+ static const unsigned maxSize = 512;
+ static inline unsigned maxInlineCapacity()
+ {
+ return (maxSize - allocationSize(0)) / sizeof(WriteBarrier<Unknown>);
+ }
+
static JSFinalObject* create(ExecState*, Structure*);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, unsigned inlineCapacity)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info, NonArray, INLINE_STORAGE_CAPACITY);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info, NonArray, inlineCapacity);
}
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
@@ -1024,9 +1026,9 @@ public:
protected:
void visitChildrenCommon(SlotVisitor&);
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(structure()->totalStorageCapacity() == structure()->inlineCapacity());
ASSERT(classInfo());
}
@@ -1034,8 +1036,8 @@ protected:
private:
friend class LLIntOffsetsExtractor;
- explicit JSFinalObject(JSGlobalData& globalData, Structure* structure)
- : JSObject(globalData, structure)
+ explicit JSFinalObject(VM& vm, Structure* structure)
+ : JSObject(vm, structure)
{
}
@@ -1050,8 +1052,8 @@ inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structur
*exec->heap(),
allocationSize(structure->inlineCapacity())
)
- ) JSFinalObject(exec->globalData(), structure);
- finalObject->finishCreation(exec->globalData());
+ ) JSFinalObject(exec->vm(), structure);
+ finalObject->finishCreation(exec->vm());
return finalObject;
}
@@ -1080,6 +1082,14 @@ inline bool JSObject::isVariableObject() const
return structure()->typeInfo().type() >= VariableObjectType;
}
+
+inline bool JSObject::isStaticScopeObject() const
+{
+ JSType type = structure()->typeInfo().type();
+ return type == NameScopeObjectType || type == ActivationObjectType;
+}
+
+
inline bool JSObject::isNameScopeObject() const
{
return structure()->typeInfo().type() == NameScopeObjectType;
@@ -1095,11 +1105,11 @@ inline bool JSObject::isErrorInstance() const
return structure()->typeInfo().type() == ErrorInstanceType;
}
-inline void JSObject::setButterfly(JSGlobalData& globalData, Butterfly* butterfly, Structure* structure)
+inline void JSObject::setButterfly(VM& vm, Butterfly* butterfly, Structure* structure)
{
ASSERT(structure);
ASSERT(!butterfly == (!structure->outOfLineCapacity() && !hasIndexingHeader(structure->indexingType())));
- setStructure(globalData, structure);
+ setStructure(vm, structure);
m_butterfly = butterfly;
}
@@ -1108,11 +1118,6 @@ inline void JSObject::setButterflyWithoutChangingStructure(Butterfly* butterfly)
m_butterfly = butterfly;
}
-inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
-{
- return JSFinalObject::create(exec, structure);
-}
-
inline CallType getCallData(JSValue value, CallData& callData)
{
CallType result = value.isCell() ? value.asCell()->methodTable()->getCallData(value.asCell(), callData) : CallTypeNone;
@@ -1127,11 +1132,6 @@ inline ConstructType getConstructData(JSValue value, ConstructData& constructDat
return result;
}
-inline Structure* createEmptyObjectStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
-{
- return JSFinalObject::createStructure(globalData, globalObject, prototype);
-}
-
inline JSObject* asObject(JSCell* cell)
{
ASSERT(cell->isObject());
@@ -1143,8 +1143,8 @@ inline JSObject* asObject(JSValue value)
return asObject(value.asCell());
}
-inline JSObject::JSObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly)
- : JSCell(globalData, structure)
+inline JSObject::JSObject(VM& vm, Structure* structure, Butterfly* butterfly)
+ : JSCell(vm, structure)
, m_butterfly(butterfly)
{
}
@@ -1154,32 +1154,11 @@ inline JSValue JSObject::prototype() const
return structure()->storedPrototype();
}
-inline const MethodTable* JSCell::methodTable() const
-{
- return &classInfo()->methodTable;
-}
-
-inline bool JSCell::inherits(const ClassInfo* info) const
-{
- return classInfo()->isSubClassOf(info);
-}
-
-// this method is here to be after the inline declaration of JSCell::inherits
-inline bool JSValue::inherits(const ClassInfo* classInfo) const
-{
- return isCell() && asCell()->inherits(classInfo);
-}
-
-inline JSObject* JSValue::toThisObject(ExecState* exec) const
-{
- return isCell() ? asCell()->methodTable()->toThisObject(asCell(), exec) : toThisObjectSlowCase(exec);
-}
-
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
- PropertyOffset offset = structure()->get(exec->globalData(), propertyName);
+ PropertyOffset offset = structure()->get(exec->vm(), propertyName);
if (LIKELY(isValidOffset(offset))) {
- JSValue value = getDirectOffset(offset);
+ JSValue value = getDirect(offset);
if (structure()->hasGetterSetterProperties() && value.isGetterSetter())
fillGetterPropertySlot(slot, offset);
else
@@ -1198,29 +1177,6 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, P
return jsCast<JSObject*>(cell)->inlineGetOwnPropertySlot(exec, propertyName, slot);
}
-ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
- if (!structure()->typeInfo().overridesGetOwnPropertySlot())
- return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
- return methodTable()->getOwnPropertySlot(this, exec, propertyName, slot);
-}
-
-// Fast call to get a property where we may not yet have converted the string to an
-// identifier. The first time we perform a property access with a given string, try
-// performing the property map lookup without forming an identifier. We detect this
-// case by checking whether the hash has yet been set for this string.
-ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const String& name)
-{
- if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) {
- PropertyOffset offset = name.impl()->hasHash()
- ? structure()->get(exec->globalData(), Identifier(exec, name))
- : structure()->get(exec->globalData(), name);
- if (offset != invalidOffset)
- return asObject(this)->locationForOffset(offset)->get();
- }
- return JSValue();
-}
-
// It may seem crazy to inline a function this large but it makes a big difference
// since this is function very hot in variable lookup
ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -1268,7 +1224,7 @@ inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
}
template<JSObject::PutMode mode>
-inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot, JSCell* specificFunction)
+inline bool JSObject::putDirectInternal(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes, PutPropertySlot& slot, JSCell* specificFunction)
{
ASSERT(value);
ASSERT(value.isGetterSetter() == !!(attributes & Accessor));
@@ -1278,16 +1234,16 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p
if (structure()->isDictionary()) {
unsigned currentAttributes;
JSCell* currentSpecificFunction;
- PropertyOffset offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
+ PropertyOffset offset = structure()->get(vm, propertyName, currentAttributes, currentSpecificFunction);
if (offset != invalidOffset) {
// If there is currently a specific function, and there now either isn't,
// or the new value is different, then despecify.
if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
- structure()->despecifyDictionaryFunction(globalData, propertyName);
+ structure()->despecifyDictionaryFunction(vm, propertyName);
if ((mode == PutModePut) && currentAttributes & ReadOnly)
return false;
- putDirectOffset(globalData, offset, value);
+ putDirect(vm, offset, value);
// At this point, the objects structure only has a specific value set if previously there
// had been one set, and if the new value being specified is the same (otherwise we would
// have despecified, above). So, if currentSpecificFunction is not set, or if the new
@@ -1304,13 +1260,13 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p
Butterfly* newButterfly = m_butterfly;
if (structure()->putWillGrowOutOfLineStorage())
- newButterfly = growOutOfLineStorage(globalData, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
- offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
- setButterfly(globalData, newButterfly, structure());
+ newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
+ offset = structure()->addPropertyWithoutTransition(vm, propertyName, attributes, specificFunction);
+ setButterfly(vm, newButterfly, structure());
validateOffset(offset);
ASSERT(structure()->isValidOffset(offset));
- putDirectOffset(globalData, offset, value);
+ putDirect(vm, offset, value);
// See comment on setNewProperty call below.
if (!specificFunction)
slot.setNewProperty(this, offset);
@@ -1324,12 +1280,12 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p
if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {
Butterfly* newButterfly = m_butterfly;
if (currentCapacity != structure->outOfLineCapacity())
- newButterfly = growOutOfLineStorage(globalData, currentCapacity, structure->outOfLineCapacity());
+ newButterfly = growOutOfLineStorage(vm, currentCapacity, structure->outOfLineCapacity());
validateOffset(offset);
ASSERT(structure->isValidOffset(offset));
- setButterfly(globalData, newButterfly, structure);
- putDirectOffset(globalData, offset, value);
+ setButterfly(vm, newButterfly, structure);
+ putDirect(vm, offset, value);
// This is a new property; transitions with specific values are not currently cachable,
// so leave the slot in an uncachable state.
if (!specificFunction)
@@ -1339,7 +1295,7 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p
unsigned currentAttributes;
JSCell* currentSpecificFunction;
- offset = structure()->get(globalData, propertyName, currentAttributes, currentSpecificFunction);
+ offset = structure()->get(vm, propertyName, currentAttributes, currentSpecificFunction);
if (offset != invalidOffset) {
if ((mode == PutModePut) && currentAttributes & ReadOnly)
return false;
@@ -1356,29 +1312,29 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p
if (currentSpecificFunction) {
// case (1) Do the put, then return leaving the slot uncachable.
if (specificFunction == currentSpecificFunction) {
- putDirectOffset(globalData, offset, value);
+ putDirect(vm, offset, value);
return true;
}
// case (2) Despecify, fall through to (3).
- setStructure(globalData, Structure::despecifyFunctionTransition(globalData, structure(), propertyName));
+ setStructure(vm, Structure::despecifyFunctionTransition(vm, structure(), propertyName));
}
// case (3) set the slot, do the put, return.
slot.setExistingProperty(this, offset);
- putDirectOffset(globalData, offset, value);
+ putDirect(vm, offset, value);
return true;
}
if ((mode == PutModePut) && !isExtensible())
return false;
- Structure* structure = Structure::addPropertyTransition(globalData, this->structure(), propertyName, attributes, specificFunction, offset);
+ Structure* structure = Structure::addPropertyTransition(vm, this->structure(), propertyName, attributes, specificFunction, offset);
validateOffset(offset);
ASSERT(structure->isValidOffset(offset));
- setStructureAndReallocateStorageIfNecessary(globalData, structure);
+ setStructureAndReallocateStorageIfNecessary(vm, structure);
- putDirectOffset(globalData, offset, value);
+ putDirect(vm, offset, value);
// This is a new property; transitions with specific values are not currently cachable,
// so leave the slot in an uncachable state.
if (!specificFunction)
@@ -1388,57 +1344,57 @@ inline bool JSObject::putDirectInternal(JSGlobalData& globalData, PropertyName p
return true;
}
-inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, unsigned oldCapacity, Structure* newStructure)
+inline void JSObject::setStructureAndReallocateStorageIfNecessary(VM& vm, unsigned oldCapacity, Structure* newStructure)
{
ASSERT(oldCapacity <= newStructure->outOfLineCapacity());
if (oldCapacity == newStructure->outOfLineCapacity()) {
- setStructure(globalData, newStructure);
+ setStructure(vm, newStructure);
return;
}
Butterfly* newButterfly = growOutOfLineStorage(
- globalData, oldCapacity, newStructure->outOfLineCapacity());
- setButterfly(globalData, newButterfly, newStructure);
+ vm, oldCapacity, newStructure->outOfLineCapacity());
+ setButterfly(vm, newButterfly, newStructure);
}
-inline void JSObject::setStructureAndReallocateStorageIfNecessary(JSGlobalData& globalData, Structure* newStructure)
+inline void JSObject::setStructureAndReallocateStorageIfNecessary(VM& vm, Structure* newStructure)
{
setStructureAndReallocateStorageIfNecessary(
- globalData, structure()->outOfLineCapacity(), newStructure);
+ vm, structure()->outOfLineCapacity(), newStructure);
}
-inline bool JSObject::putOwnDataProperty(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+inline bool JSObject::putOwnDataProperty(VM& vm, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
ASSERT(!structure()->hasGetterSetterProperties());
- return putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value));
+ return putDirectInternal<PutModePut>(vm, propertyName, value, 0, slot, getCallableObject(value));
}
-inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
+inline void JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
PutPropertySlot slot;
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, attributes, slot, getCallableObject(value));
+ putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, attributes, slot, getCallableObject(value));
}
-inline void JSObject::putDirect(JSGlobalData& globalData, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
+inline void JSObject::putDirect(VM& vm, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(!value.isGetterSetter());
- putDirectInternal<PutModeDefineOwnProperty>(globalData, propertyName, value, 0, slot, getCallableObject(value));
+ putDirectInternal<PutModeDefineOwnProperty>(vm, propertyName, value, 0, slot, getCallableObject(value));
}
-inline void JSObject::putDirectWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, JSValue value, unsigned attributes)
+inline void JSObject::putDirectWithoutTransition(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
Butterfly* newButterfly = m_butterfly;
if (structure()->putWillGrowOutOfLineStorage())
- newButterfly = growOutOfLineStorage(globalData, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
- PropertyOffset offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getCallableObject(value));
- setButterfly(globalData, newButterfly, structure());
- putDirectOffset(globalData, offset, value);
+ newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
+ PropertyOffset offset = structure()->addPropertyWithoutTransition(vm, propertyName, attributes, getCallableObject(value));
+ setButterfly(vm, newButterfly, structure());
+ putDirect(vm, offset, value);
}
inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
@@ -1446,74 +1402,6 @@ inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType pre
return methodTable()->defaultValue(this, exec, preferredType);
}
-inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName) const
-{
- PropertySlot slot(asValue());
- return get(exec, propertyName, slot);
-}
-
-inline JSValue JSValue::get(ExecState* exec, PropertyName propertyName, PropertySlot& slot) const
-{
- if (UNLIKELY(!isCell())) {
- JSObject* prototype = synthesizePrototype(exec);
- if (!prototype->getPropertySlot(exec, propertyName, slot))
- return jsUndefined();
- return slot.getValue(exec, propertyName);
- }
- JSCell* cell = asCell();
- while (true) {
- if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
- return slot.getValue(exec, propertyName);
- JSValue prototype = asObject(cell)->prototype();
- if (!prototype.isObject())
- return jsUndefined();
- cell = asObject(prototype);
- }
-}
-
-inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
-{
- PropertySlot slot(asValue());
- return get(exec, propertyName, slot);
-}
-
-inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
-{
- if (UNLIKELY(!isCell())) {
- JSObject* prototype = synthesizePrototype(exec);
- if (!prototype->getPropertySlot(exec, propertyName, slot))
- return jsUndefined();
- return slot.getValue(exec, propertyName);
- }
- JSCell* cell = const_cast<JSCell*>(asCell());
- while (true) {
- if (cell->methodTable()->getOwnPropertySlotByIndex(cell, exec, propertyName, slot))
- return slot.getValue(exec, propertyName);
- JSValue prototype = asObject(cell)->prototype();
- if (!prototype.isObject())
- return jsUndefined();
- cell = prototype.asCell();
- }
-}
-
-inline void JSValue::put(ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
-{
- if (UNLIKELY(!isCell())) {
- putToPrimitive(exec, propertyName, value, slot);
- return;
- }
- asCell()->methodTable()->put(asCell(), exec, propertyName, value, slot);
-}
-
-inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
-{
- if (UNLIKELY(!isCell())) {
- putToPrimitiveByIndex(exec, propertyName, value, shouldThrow);
- return;
- }
- asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
-}
-
ALWAYS_INLINE JSObject* Register::function() const
{
if (!jsValue())
@@ -1533,7 +1421,7 @@ inline size_t offsetInButterfly(PropertyOffset offset)
return offsetInOutOfLineStorage(offset) + Butterfly::indexOfPropertyStorage();
}
-// This is a helper for patching code where you want to emit a load or store and
+// Helpers for patching code where you want to emit a load or store and
// the base is:
// For inline offsets: a pointer to the out-of-line storage pointer.
// For out-of-line offsets: the base of the out-of-line storage.
@@ -1544,6 +1432,17 @@ inline size_t offsetRelativeToPatchedStorage(PropertyOffset offset)
return JSObject::offsetOfInlineStorage() - JSObject::butterflyOffset() + sizeof(EncodedJSValue) * offsetInInlineStorage(offset);
}
+// Returns the maximum offset (away from zero) a load instruction will encode.
+inline size_t maxOffsetRelativeToPatchedStorage(PropertyOffset offset)
+{
+ ptrdiff_t addressOffset = static_cast<ptrdiff_t>(offsetRelativeToPatchedStorage(offset));
+#if USE(JSVALUE32_64)
+ if (addressOffset >= 0)
+ return static_cast<size_t>(addressOffset) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag);
+#endif
+ return static_cast<size_t>(addressOffset);
+}
+
inline int indexRelativeToBase(PropertyOffset offset)
{
if (isOutOfLineOffset(offset))
@@ -1561,37 +1460,30 @@ inline int offsetRelativeToBase(PropertyOffset offset)
COMPILE_ASSERT(!(sizeof(JSObject) % sizeof(WriteBarrierBase<Unknown>)), JSObject_inline_storage_has_correct_alignment);
-class JSDestructibleObject : public JSNonFinalObject {
-public:
- typedef JSNonFinalObject Base;
-
- static const bool needsDestruction = true;
-
- const ClassInfo* classInfo() const { return m_classInfo; }
-
-protected:
- JSDestructibleObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0)
- : JSNonFinalObject(globalData, structure, butterfly)
- , m_classInfo(structure->classInfo())
- {
- ASSERT(m_classInfo);
- }
-
-private:
- const ClassInfo* m_classInfo;
-};
+ALWAYS_INLINE Identifier makeIdentifier(ExecState* exec, const char* name)
+{
+ return Identifier(exec, name);
+}
-inline const ClassInfo* JSCell::classInfo() const
+ALWAYS_INLINE Identifier makeIdentifier(ExecState*, const Identifier& name)
{
- if (MarkedBlock::blockFor(this)->destructorType() == MarkedBlock::Normal)
- return static_cast<const JSDestructibleObject*>(this)->classInfo();
-#if ENABLE(GC_VALIDATION)
- return m_structure.unvalidatedGet()->classInfo();
-#else
- return m_structure->classInfo();
-#endif
+ return name;
}
+// Helper for defining native functions, if you're not using a static hash table.
+// Use this macro from within finishCreation() methods in prototypes. This assumes
+// you've defined variables called exec, globalObject, and vm, and they
+// have the expected meanings.
+#define JSC_NATIVE_INTRINSIC_FUNCTION(jsName, cppName, attributes, length, intrinsic) \
+ putDirectNativeFunction(\
+ exec, globalObject, makeIdentifier(exec, (jsName)), (length), cppName, \
+ (intrinsic), (attributes))
+
+// As above, but this assumes that the function you're defining doesn't have an
+// intrinsic.
+#define JSC_NATIVE_FUNCTION(jsName, cppName, attributes, length) \
+ JSC_NATIVE_INTRINSIC_FUNCTION(jsName, cppName, (attributes), (length), NoIntrinsic)
+
} // namespace JSC
#endif // JSObject_h
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 496799501..78b8aaee9 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -36,7 +36,7 @@ namespace JSC {
const ClassInfo JSPropertyNameIterator::s_info = { "JSPropertyNameIterator", 0, 0, 0, CREATE_METHOD_TABLE(JSPropertyNameIterator) };
inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
- : JSCell(exec->globalData(), exec->globalData().propertyNameIteratorStructure.get())
+ : JSCell(exec->vm(), exec->vm().propertyNameIteratorStructure.get())
, m_numCacheableSlots(numCacheableSlots)
, m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
, m_jsStrings(adoptArrayPtr(new WriteBarrier<Unknown>[m_jsStringsSize]))
@@ -76,9 +76,9 @@ JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject
return jsPropertyNameIterator;
}
- jsPropertyNameIterator->setCachedPrototypeChain(exec->globalData(), structureChain);
- jsPropertyNameIterator->setCachedStructure(exec->globalData(), o->structure());
- o->structure()->setEnumerationCache(exec->globalData(), jsPropertyNameIterator);
+ jsPropertyNameIterator->setCachedPrototypeChain(exec->vm(), structureChain);
+ jsPropertyNameIterator->setCachedStructure(exec->vm(), o->structure());
+ o->structure()->setEnumerationCache(exec->vm(), jsPropertyNameIterator);
return jsPropertyNameIterator;
}
diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
index e59a5c6a4..ba931b131 100644
--- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -52,9 +52,9 @@ namespace JSC {
static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info);
}
static void visitChildren(JSCell*, SlotVisitor&);
@@ -62,26 +62,26 @@ namespace JSC {
JSValue get(ExecState*, JSObject*, size_t i);
size_t size() { return m_jsStringsSize; }
- void setCachedStructure(JSGlobalData& globalData, Structure* structure)
+ void setCachedStructure(VM& vm, Structure* structure)
{
ASSERT(!m_cachedStructure);
ASSERT(structure);
- m_cachedStructure.set(globalData, this, structure);
+ m_cachedStructure.set(vm, this, structure);
}
Structure* cachedStructure() { return m_cachedStructure.get(); }
- void setCachedPrototypeChain(JSGlobalData& globalData, StructureChain* cachedPrototypeChain) { m_cachedPrototypeChain.set(globalData, this, cachedPrototypeChain); }
+ void setCachedPrototypeChain(VM& vm, StructureChain* cachedPrototypeChain) { m_cachedPrototypeChain.set(vm, this, cachedPrototypeChain); }
StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
- static const ClassInfo s_info;
+ static JS_EXPORTDATA const ClassInfo s_info;
protected:
void finishCreation(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, JSObject* object)
{
- Base::finishCreation(exec->globalData());
+ Base::finishCreation(exec->vm());
PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
for (size_t i = 0; i < m_jsStringsSize; ++i)
- m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].string()));
+ m_jsStrings[i].set(exec->vm(), this, jsOwnedString(exec, propertyNameVector[i].string()));
m_cachedStructureInlineCapacity = object->structure()->inlineCapacity();
}
@@ -98,20 +98,19 @@ namespace JSC {
OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings;
};
- inline void Structure::setEnumerationCache(JSGlobalData& globalData, JSPropertyNameIterator* enumerationCache)
+ ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
{
- ASSERT(!isDictionary());
- m_enumerationCache.set(globalData, this, enumerationCache);
+ return jsCast<JSPropertyNameIterator*>(jsValue().asCell());
}
- inline JSPropertyNameIterator* Structure::enumerationCache()
+ inline JSPropertyNameIterator* StructureRareData::enumerationCache()
{
return m_enumerationCache.get();
}
-
- ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
+
+ inline void StructureRareData::setEnumerationCache(VM& vm, const Structure* owner, JSPropertyNameIterator* value)
{
- return jsCast<JSPropertyNameIterator*>(jsValue().asCell());
+ m_enumerationCache.set(vm, owner, value);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSProxy.cpp b/Source/JavaScriptCore/runtime/JSProxy.cpp
index 7108dcfa0..e0f9d69e6 100644
--- a/Source/JavaScriptCore/runtime/JSProxy.cpp
+++ b/Source/JavaScriptCore/runtime/JSProxy.cpp
@@ -27,6 +27,7 @@
#include "JSProxy.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
namespace JSC {
@@ -46,12 +47,21 @@ void JSProxy::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_target);
}
-void JSProxy::setTarget(JSGlobalData& globalData, JSGlobalObject* globalObject)
+void JSProxy::setTarget(VM& vm, JSGlobalObject* globalObject)
{
ASSERT_ARG(globalObject, globalObject);
- m_target.set(globalData, this, globalObject);
- setPrototype(globalData, globalObject->prototype());
- resetInheritorID(globalData);
+ m_target.set(vm, this, globalObject);
+ setPrototype(vm, globalObject->prototype());
+
+ PrototypeMap& prototypeMap = vm.prototypeMap;
+ if (!prototypeMap.isPrototype(this))
+ return;
+
+ // This is slow but constant time. We think it's very rare for a proxy
+ // to be a prototype, and reasonably rare to retarget a proxy,
+ // so slow constant time is OK.
+ for (size_t i = 0; i <= JSFinalObject::maxInlineCapacity(); ++i)
+ prototypeMap.clearEmptyObjectStructureForPrototype(this, i);
}
String JSProxy::className(const JSObject* object)
diff --git a/Source/JavaScriptCore/runtime/JSProxy.h b/Source/JavaScriptCore/runtime/JSProxy.h
index 144085a79..9b6bed52e 100644
--- a/Source/JavaScriptCore/runtime/JSProxy.h
+++ b/Source/JavaScriptCore/runtime/JSProxy.h
@@ -34,16 +34,16 @@ class JSProxy : public JSDestructibleObject {
public:
typedef JSDestructibleObject Base;
- static JSProxy* create(JSGlobalData& globalData, Structure* structure, JSObject* target)
+ static JSProxy* create(VM& vm, Structure* structure, JSObject* target)
{
- JSProxy* proxy = new (NotNull, allocateCell<JSProxy>(globalData.heap)) JSProxy(globalData, structure);
- proxy->finishCreation(globalData, target);
+ JSProxy* proxy = new (NotNull, allocateCell<JSProxy>(vm.heap)) JSProxy(vm, structure);
+ proxy->finishCreation(vm, target);
return proxy;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ProxyType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ProxyType, StructureFlags), &s_info);
}
static JS_EXPORTDATA const ClassInfo s_info;
@@ -51,27 +51,27 @@ public:
JSObject* target() const { return m_target.get(); }
protected:
- JSProxy(JSGlobalData& globalData, Structure* structure)
- : JSDestructibleObject(globalData, structure)
+ JSProxy(VM& vm, Structure* structure)
+ : JSDestructibleObject(vm, structure)
{
}
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
}
- void finishCreation(JSGlobalData& globalData, JSObject* target)
+ void finishCreation(VM& vm, JSObject* target)
{
- Base::finishCreation(globalData);
- m_target.set(globalData, this, target);
+ Base::finishCreation(vm);
+ m_target.set(vm, this, target);
}
- static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
+ static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | Base::StructureFlags;
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- JS_EXPORT_PRIVATE void setTarget(JSGlobalData&, JSGlobalObject*);
+ JS_EXPORT_PRIVATE void setTarget(VM&, JSGlobalObject*);
JS_EXPORT_PRIVATE static String className(const JSObject*);
JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
diff --git a/Source/JavaScriptCore/runtime/JSScope.cpp b/Source/JavaScriptCore/runtime/JSScope.cpp
index 8651a76ba..69ff1e478 100644
--- a/Source/JavaScriptCore/runtime/JSScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSScope.cpp
@@ -30,6 +30,7 @@
#include "JSGlobalObject.h"
#include "JSNameScope.h"
#include "JSWithScope.h"
+#include "Operations.h"
namespace JSC {
@@ -56,7 +57,7 @@ bool JSScope::isDynamicScope(bool& requiresDynamicChecks) const
case NameScopeObjectType:
return static_cast<const JSNameScope*>(this)->isDynamicScope(requiresDynamicChecks);
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
break;
}
@@ -166,7 +167,7 @@ static bool executeResolveOperations(CallFrame* callFrame, JSScope* scope, const
case ResolveOperation::GetAndReturnGlobalProperty: {
JSGlobalObject* globalObject = scope->globalObject();
if (globalObject->structure() == pc->m_structure.get()) {
- result.setValue(globalObject->getDirectOffset(pc->m_offset));
+ result.setValue(globalObject->getDirect(pc->m_offset));
return true;
}
@@ -186,7 +187,7 @@ static bool executeResolveOperations(CallFrame* callFrame, JSScope* scope, const
return true;
}
- pc->m_structure.set(callFrame->globalData(), callFrame->codeBlock()->ownerExecutable(), structure);
+ pc->m_structure.set(callFrame->vm(), callFrame->codeBlock()->ownerExecutable(), structure);
pc->m_offset = slot.cachedOffset();
result.setValue(value);
return true;
@@ -302,7 +303,7 @@ template <JSScope::LookupMode mode, JSScope::ReturnValues returnValues> JSObject
if (putToBaseOperation) {
putToBaseOperation->m_isDynamic = requiresDynamicChecks;
putToBaseOperation->m_kind = PutToBaseOperation::GlobalPropertyPut;
- putToBaseOperation->m_structure.set(callFrame->globalData(), callFrame->codeBlock()->ownerExecutable(), globalObject->structure());
+ putToBaseOperation->m_structure.set(callFrame->vm(), callFrame->codeBlock()->ownerExecutable(), globalObject->structure());
setPutPropertyAccessOffset(putToBaseOperation, slot.cachedOffset());
}
switch (returnValues) {
@@ -345,7 +346,7 @@ template <JSScope::LookupMode mode, JSScope::ReturnValues returnValues> JSObject
if (putToBaseOperation) {
putToBaseOperation->m_kind = entry.isReadOnly() ? PutToBaseOperation::Readonly : PutToBaseOperation::VariablePut;
- putToBaseOperation->m_structure.set(callFrame->globalData(), callFrame->codeBlock()->ownerExecutable(), callFrame->lexicalGlobalObject()->activationStructure());
+ putToBaseOperation->m_structure.set(callFrame->vm(), callFrame->codeBlock()->ownerExecutable(), callFrame->lexicalGlobalObject()->activationStructure());
putToBaseOperation->m_offset = entry.getIndex();
putToBaseOperation->m_scopeDepth = (skipTopScopeNode ? 1 : 0) + scopeCount;
}
@@ -498,7 +499,7 @@ JSValue JSScope::resolveWithBase(CallFrame* callFrame, const Identifier& identif
if (JSObject* propertyBase = JSScope::resolveContainingScope<ReturnBaseAndValue>(callFrame, identifier, slot, operations, putToBaseOperations, false)) {
ASSERT(operations->size());
JSValue value = slot.getValue(callFrame, identifier);
- if (callFrame->globalData().exception)
+ if (callFrame->vm().exception)
return JSValue();
*base = propertyBase;
@@ -528,7 +529,7 @@ JSValue JSScope::resolveWithThis(CallFrame* callFrame, const Identifier& identif
if (JSObject* propertyBase = JSScope::resolveContainingScope<ReturnThisAndValue>(callFrame, identifier, slot, operations, 0, false)) {
ASSERT(operations->size());
JSValue value = slot.getValue(callFrame, identifier);
- if (callFrame->globalData().exception)
+ if (callFrame->vm().exception)
return JSValue();
ASSERT(value);
*base = propertyBase->structure()->typeInfo().isEnvironmentRecord() ? jsUndefined() : JSValue(propertyBase);
@@ -563,7 +564,7 @@ void JSScope::resolvePut(CallFrame* callFrame, JSValue base, const Identifier& p
goto genericHandler;
}
}
- operation->m_registerAddress->set(callFrame->globalData(), base.asCell(), value);
+ operation->m_registerAddress->set(callFrame->vm(), base.asCell(), value);
return;
case PutToBaseOperation::VariablePut: {
@@ -573,7 +574,7 @@ void JSScope::resolvePut(CallFrame* callFrame, JSValue base, const Identifier& p
goto genericHandler;
}
JSVariableObject* variableObject = jsCast<JSVariableObject*>(base);
- variableObject->registerAt(operation->m_offset).set(callFrame->globalData(), variableObject, value);
+ variableObject->registerAt(operation->m_offset).set(callFrame->vm(), variableObject, value);
return;
}
@@ -581,7 +582,7 @@ void JSScope::resolvePut(CallFrame* callFrame, JSValue base, const Identifier& p
JSObject* object = jsCast<JSObject*>(base);
if (operation->m_structure.get() != object->structure())
break;
- object->putDirectOffset(callFrame->globalData(), operation->m_offset, value);
+ object->putDirect(callFrame->vm(), operation->m_offset, value);
return;
}
@@ -606,7 +607,7 @@ void JSScope::resolvePut(CallFrame* callFrame, JSValue base, const Identifier& p
if (slot.base() != baseObject)
return;
ASSERT(!baseObject->hasInlineStorage());
- operation->m_structure.set(callFrame->globalData(), callFrame->codeBlock()->ownerExecutable(), baseObject->structure());
+ operation->m_structure.set(callFrame->vm(), callFrame->codeBlock()->ownerExecutable(), baseObject->structure());
setPutPropertyAccessOffset(operation, slot.cachedOffset());
return;
}
diff --git a/Source/JavaScriptCore/runtime/JSScope.h b/Source/JavaScriptCore/runtime/JSScope.h
index a9a9dd8d8..95db8ad56 100644
--- a/Source/JavaScriptCore/runtime/JSScope.h
+++ b/Source/JavaScriptCore/runtime/JSScope.h
@@ -59,11 +59,11 @@ public:
int localDepth();
JSGlobalObject* globalObject();
- JSGlobalData* globalData();
+ VM* vm();
JSObject* globalThis();
protected:
- JSScope(JSGlobalData&, Structure*, JSScope* next);
+ JSScope(VM&, Structure*, JSScope* next);
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
private:
@@ -80,9 +80,9 @@ private:
template <ReturnValues> static JSObject* resolveContainingScope(CallFrame*, const Identifier&, PropertySlot&, ResolveOperations*, PutToBaseOperation*, bool isStrict);
};
-inline JSScope::JSScope(JSGlobalData& globalData, Structure* structure, JSScope* next)
- : Base(globalData, structure)
- , m_next(globalData, this, next, WriteBarrier<JSScope>::MayBeNull)
+inline JSScope::JSScope(VM& vm, Structure* structure, JSScope* next)
+ : Base(vm, structure)
+ , m_next(vm, this, next, WriteBarrier<JSScope>::MayBeNull)
{
}
@@ -127,9 +127,9 @@ inline JSGlobalObject* JSScope::globalObject()
return structure()->globalObject();
}
-inline JSGlobalData* JSScope::globalData()
+inline VM* JSScope::vm()
{
- return Heap::heap(this)->globalData();
+ return Heap::heap(this)->vm();
}
inline Register& Register::operator=(JSScope* scope)
@@ -143,10 +143,10 @@ inline JSScope* Register::scope() const
return jsCast<JSScope*>(jsValue());
}
-inline JSGlobalData& ExecState::globalData() const
+inline VM& ExecState::vm() const
{
- ASSERT(scope()->globalData());
- return *scope()->globalData();
+ ASSERT(scope()->vm());
+ return *scope()->vm();
}
inline JSGlobalObject* ExecState::lexicalGlobalObject() const
diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
index c65d2b1b9..01c070451 100644
--- a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
@@ -29,6 +29,8 @@
#include "config.h"
#include "JSSegmentedVariableObject.h"
+#include "Operations.h"
+
namespace JSC {
int JSSegmentedVariableObject::findRegisterIndex(void* registerAddress)
diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
index 1fd96c17a..3a6f625ce 100644
--- a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
@@ -35,7 +35,6 @@
#include "SymbolTable.h"
#include <wtf/OwnArrayPtr.h>
#include <wtf/SegmentedVector.h>
-#include <wtf/UnusedParam.h>
namespace JSC {
@@ -82,14 +81,14 @@ public:
protected:
static const unsigned StructureFlags = OverridesVisitChildren | JSSymbolTableObject::StructureFlags;
- JSSegmentedVariableObject(JSGlobalData& globalData, Structure* structure, JSScope* scope)
- : JSSymbolTableObject(globalData, structure, scope)
+ JSSegmentedVariableObject(VM& vm, Structure* structure, JSScope* scope)
+ : JSSymbolTableObject(vm, structure, scope)
{
}
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
}
SegmentedVector<WriteBarrier<Unknown>, 16> m_registers;
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index f0e796d89..86704d715 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -40,7 +40,7 @@ void JSRopeString::RopeBuilder::expand()
{
ASSERT(m_index == JSRopeString::s_maxInternalRopeLength);
JSString* jsString = m_jsString;
- m_jsString = jsStringBuilder(&m_globalData);
+ m_jsString = jsStringBuilder(&m_vm);
m_index = 0;
append(jsString);
}
@@ -154,7 +154,7 @@ void JSRopeString::resolveRope(ExecState* exec) const
void JSRopeString::resolveRopeSlowCase8(LChar* buffer) const
{
LChar* position = buffer + m_length; // We will be working backwards over the rope.
- Vector<JSString*, 32> workQueue; // Putting strings into a Vector is only OK because there are no GC points in this method.
+ Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // Putting strings into a Vector is only OK because there are no GC points in this method.
for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) {
workQueue.append(m_fibers[i].get());
@@ -186,7 +186,7 @@ void JSRopeString::resolveRopeSlowCase8(LChar* buffer) const
void JSRopeString::resolveRopeSlowCase(UChar* buffer) const
{
UChar* position = buffer + m_length; // We will be working backwards over the rope.
- Vector<JSString*, 32> workQueue; // These strings are kept alive by the parent rope, so using a Vector is OK.
+ Vector<JSString*, 32, UnsafeVectorOverflow> workQueue; // These strings are kept alive by the parent rope, so using a Vector is OK.
for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i)
workQueue.append(m_fibers[i].get());
@@ -233,7 +233,7 @@ JSString* JSRopeString::getIndexSlowCase(ExecState* exec, unsigned i)
if (exec->exception())
return jsEmptyString(exec);
ASSERT(!isRope());
- ASSERT(i < m_value.length());
+ RELEASE_ASSERT(i < m_value.length());
return jsSingleCharacterSubstring(exec, m_value, i);
}
@@ -261,8 +261,8 @@ double JSString::toNumber(ExecState* exec) const
inline StringObject* StringObject::create(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
{
- StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->globalData(), globalObject->stringObjectStructure());
- object->finishCreation(exec->globalData(), string);
+ StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->vm(), globalObject->stringObjectStructure());
+ object->finishCreation(exec->vm(), string);
return object;
}
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index 245c48a51..855de974d 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -31,525 +31,523 @@
namespace JSC {
- class JSString;
- class JSRopeString;
- class LLIntOffsetsExtractor;
-
- JSString* jsEmptyString(JSGlobalData*);
- JSString* jsEmptyString(ExecState*);
- JSString* jsString(JSGlobalData*, const String&); // returns empty string if passed null string
- JSString* jsString(ExecState*, const String&); // returns empty string if passed null string
-
- JSString* jsSingleCharacterString(JSGlobalData*, UChar);
- JSString* jsSingleCharacterString(ExecState*, UChar);
- JSString* jsSingleCharacterSubstring(ExecState*, const String&, unsigned offset);
- JSString* jsSubstring(JSGlobalData*, const String&, unsigned offset, unsigned length);
- JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length);
-
- // Non-trivial strings are two or more characters long.
- // These functions are faster than just calling jsString.
- JSString* jsNontrivialString(JSGlobalData*, const String&);
- JSString* jsNontrivialString(ExecState*, const String&);
-
- // Should be used for strings that are owned by an object that will
- // likely outlive the JSValue this makes, such as the parse tree or a
- // DOM object that contains a String
- JSString* jsOwnedString(JSGlobalData*, const String&);
- JSString* jsOwnedString(ExecState*, const String&);
-
- JSRopeString* jsStringBuilder(JSGlobalData*);
-
- class JSString : public JSCell {
- public:
- friend class JIT;
- friend class JSGlobalData;
- friend class SpecializedThunkJIT;
- friend class JSRopeString;
- friend class MarkStack;
- friend class SlotVisitor;
- friend struct ThunkHelpers;
-
- typedef JSCell Base;
-
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
- static void destroy(JSCell*);
-
- private:
- JSString(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
- : JSCell(globalData, globalData.stringStructure.get())
- , m_flags(0)
- , m_value(value)
- {
- }
+class JSString;
+class JSRopeString;
+class LLIntOffsetsExtractor;
+
+JSString* jsEmptyString(VM*);
+JSString* jsEmptyString(ExecState*);
+JSString* jsString(VM*, const String&); // returns empty string if passed null string
+JSString* jsString(ExecState*, const String&); // returns empty string if passed null string
+
+JSString* jsSingleCharacterString(VM*, UChar);
+JSString* jsSingleCharacterString(ExecState*, UChar);
+JSString* jsSingleCharacterSubstring(ExecState*, const String&, unsigned offset);
+JSString* jsSubstring(VM*, const String&, unsigned offset, unsigned length);
+JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length);
+
+// Non-trivial strings are two or more characters long.
+// These functions are faster than just calling jsString.
+JSString* jsNontrivialString(VM*, const String&);
+JSString* jsNontrivialString(ExecState*, const String&);
+
+// Should be used for strings that are owned by an object that will
+// likely outlive the JSValue this makes, such as the parse tree or a
+// DOM object that contains a String
+JSString* jsOwnedString(VM*, const String&);
+JSString* jsOwnedString(ExecState*, const String&);
+
+JSRopeString* jsStringBuilder(VM*);
+
+class JSString : public JSCell {
+public:
+ friend class JIT;
+ friend class VM;
+ friend class SpecializedThunkJIT;
+ friend class JSRopeString;
+ friend class MarkStack;
+ friend class SlotVisitor;
+ friend struct ThunkHelpers;
+
+ typedef JSCell Base;
+
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+ static void destroy(JSCell*);
+
+private:
+ JSString(VM& vm, PassRefPtr<StringImpl> value)
+ : JSCell(vm, vm.stringStructure.get())
+ , m_flags(0)
+ , m_value(value)
+ {
+ }
- JSString(JSGlobalData& globalData)
- : JSCell(globalData, globalData.stringStructure.get())
- , m_flags(0)
- {
- }
+ JSString(VM& vm)
+ : JSCell(vm, vm.stringStructure.get())
+ , m_flags(0)
+ {
+ }
- void finishCreation(JSGlobalData& globalData, size_t length)
- {
- ASSERT(!m_value.isNull());
- Base::finishCreation(globalData);
- m_length = length;
- setIs8Bit(m_value.impl()->is8Bit());
- globalData.m_newStringsSinceLastHashConst++;
- }
+ void finishCreation(VM& vm, size_t length)
+ {
+ ASSERT(!m_value.isNull());
+ Base::finishCreation(vm);
+ m_length = length;
+ setIs8Bit(m_value.impl()->is8Bit());
+ vm.m_newStringsSinceLastHashCons++;
+ }
- void finishCreation(JSGlobalData& globalData, size_t length, size_t cost)
- {
- ASSERT(!m_value.isNull());
- Base::finishCreation(globalData);
- m_length = length;
- setIs8Bit(m_value.impl()->is8Bit());
- Heap::heap(this)->reportExtraMemoryCost(cost);
- globalData.m_newStringsSinceLastHashConst++;
- }
+ void finishCreation(VM& vm, size_t length, size_t cost)
+ {
+ ASSERT(!m_value.isNull());
+ Base::finishCreation(vm);
+ m_length = length;
+ setIs8Bit(m_value.impl()->is8Bit());
+ Heap::heap(this)->reportExtraMemoryCost(cost);
+ vm.m_newStringsSinceLastHashCons++;
+ }
- protected:
- void finishCreation(JSGlobalData& globalData)
- {
- Base::finishCreation(globalData);
- m_length = 0;
- setIs8Bit(true);
- globalData.m_newStringsSinceLastHashConst++;
- }
+protected:
+ void finishCreation(VM& vm)
+ {
+ Base::finishCreation(vm);
+ m_length = 0;
+ setIs8Bit(true);
+ vm.m_newStringsSinceLastHashCons++;
+ }
- public:
- static JSString* create(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
- {
- ASSERT(value);
- size_t length = value->length();
- size_t cost = value->cost();
- JSString* newString = new (NotNull, allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
- newString->finishCreation(globalData, length, cost);
- return newString;
- }
- static JSString* createHasOtherOwner(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
- {
- ASSERT(value);
- size_t length = value->length();
- JSString* newString = new (NotNull, allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
- newString->finishCreation(globalData, length);
- return newString;
- }
+public:
+ static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
+ {
+ ASSERT(value);
+ size_t length = value->length();
+ size_t cost = value->cost();
+ JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
+ newString->finishCreation(vm, length, cost);
+ return newString;
+ }
+ static JSString* createHasOtherOwner(VM& vm, PassRefPtr<StringImpl> value)
+ {
+ ASSERT(value);
+ size_t length = value->length();
+ JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
+ newString->finishCreation(vm, length);
+ return newString;
+ }
- const String& value(ExecState*) const;
- const String& tryGetValue() const;
- unsigned length() { return m_length; }
+ const String& value(ExecState*) const;
+ const String& tryGetValue() const;
+ unsigned length() { return m_length; }
- JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
- JS_EXPORT_PRIVATE bool toBoolean() const;
- bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
- JSObject* toObject(ExecState*, JSGlobalObject*) const;
- double toNumber(ExecState*) const;
+ JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ JS_EXPORT_PRIVATE bool toBoolean() const;
+ bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
+ JSObject* toObject(ExecState*, JSGlobalObject*) const;
+ double toNumber(ExecState*) const;
- bool getStringPropertySlot(ExecState*, PropertyName, PropertySlot&);
- bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- bool getStringPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
+ bool getStringPropertySlot(ExecState*, PropertyName, PropertySlot&);
+ bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+ bool getStringPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
- bool canGetIndex(unsigned i) { return i < m_length; }
- JSString* getIndex(ExecState*, unsigned);
+ bool canGetIndex(unsigned i) { return i < m_length; }
+ JSString* getIndex(ExecState*, unsigned);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
- {
- return Structure::create(globalData, globalObject, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero), &s_info);
- }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
+ {
+ return Structure::create(vm, globalObject, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero), &s_info);
+ }
- static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
- static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
+ static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
+ static size_t offsetOfFlags() { return OBJECT_OFFSETOF(JSString, m_flags); }
+ static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
- static JS_EXPORTDATA const ClassInfo s_info;
+ static JS_EXPORTDATA const ClassInfo s_info;
- static void visitChildren(JSCell*, SlotVisitor&);
+ static void visitChildren(JSCell*, SlotVisitor&);
- protected:
- bool isRope() const { return m_value.isNull(); }
- bool is8Bit() const { return m_flags & Is8Bit; }
- void setIs8Bit(bool flag)
- {
- if (flag)
- m_flags |= Is8Bit;
- else
- m_flags &= ~Is8Bit;
- }
- bool shouldTryHashConst();
- bool isHashConstSingleton() const { return m_flags & IsHashConstSingleton; }
- void clearHashConstSingleton() { m_flags &= ~IsHashConstSingleton; }
- void setHashConstSingleton() { m_flags |= IsHashConstSingleton; }
- bool tryHashConstLock();
- void releaseHashConstLock();
-
- unsigned m_flags;
-
- enum {
- HashConstLock = 1u << 2,
- IsHashConstSingleton = 1u << 1,
- Is8Bit = 1u
- };
+ enum {
+ HashConsLock = 1u << 2,
+ IsHashConsSingleton = 1u << 1,
+ Is8Bit = 1u
+ };
- // A string is represented either by a String or a rope of fibers.
- unsigned m_length;
- mutable String m_value;
+protected:
+ friend class JSValue;
+
+ bool isRope() const { return m_value.isNull(); }
+ bool is8Bit() const { return m_flags & Is8Bit; }
+ void setIs8Bit(bool flag)
+ {
+ if (flag)
+ m_flags |= Is8Bit;
+ else
+ m_flags &= ~Is8Bit;
+ }
+ bool shouldTryHashCons();
+ bool isHashConsSingleton() const { return m_flags & IsHashConsSingleton; }
+ void clearHashConsSingleton() { m_flags &= ~IsHashConsSingleton; }
+ void setHashConsSingleton() { m_flags |= IsHashConsSingleton; }
+ bool tryHashConsLock();
+ void releaseHashConsLock();
+
+ unsigned m_flags;
+
+ // A string is represented either by a String or a rope of fibers.
+ unsigned m_length;
+ mutable String m_value;
- private:
- friend class LLIntOffsetsExtractor;
+private:
+ friend class LLIntOffsetsExtractor;
- static JSObject* toThisObject(JSCell*, ExecState*);
+ static JSObject* toThisObject(JSCell*, ExecState*);
- // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
+ // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
+ static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
+ static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
- String& string() { ASSERT(!isRope()); return m_value; }
+ String& string() { ASSERT(!isRope()); return m_value; }
- friend JSValue jsString(ExecState*, JSString*, JSString*);
- friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
- };
+ friend JSValue jsString(ExecState*, JSString*, JSString*);
+ friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
+};
- class JSRopeString : public JSString {
- friend class JSString;
+class JSRopeString : public JSString {
+ friend class JSString;
- friend JSRopeString* jsStringBuilder(JSGlobalData*);
+ friend JSRopeString* jsStringBuilder(VM*);
- class RopeBuilder {
- public:
- RopeBuilder(JSGlobalData& globalData)
- : m_globalData(globalData)
- , m_jsString(jsStringBuilder(&globalData))
+ class RopeBuilder {
+ public:
+ RopeBuilder(VM& vm)
+ : m_vm(vm)
+ , m_jsString(jsStringBuilder(&vm))
, m_index(0)
- {
- }
-
- void append(JSString* jsString)
- {
- if (m_index == JSRopeString::s_maxInternalRopeLength)
- expand();
- m_jsString->append(m_globalData, m_index++, jsString);
- }
-
- JSRopeString* release()
- {
- JSRopeString* tmp = m_jsString;
- m_jsString = 0;
- return tmp;
- }
-
- unsigned length() { return m_jsString->m_length; }
-
- private:
- void expand();
-
- JSGlobalData& m_globalData;
- JSRopeString* m_jsString;
- size_t m_index;
- };
-
- private:
- JSRopeString(JSGlobalData& globalData)
- : JSString(globalData)
- {
- }
-
- void finishCreation(JSGlobalData& globalData, JSString* s1, JSString* s2)
- {
- Base::finishCreation(globalData);
- m_length = s1->length() + s2->length();
- setIs8Bit(s1->is8Bit() && s2->is8Bit());
- m_fibers[0].set(globalData, this, s1);
- m_fibers[1].set(globalData, this, s2);
- }
-
- void finishCreation(JSGlobalData& globalData, JSString* s1, JSString* s2, JSString* s3)
{
- Base::finishCreation(globalData);
- m_length = s1->length() + s2->length() + s3->length();
- setIs8Bit(s1->is8Bit() && s2->is8Bit() && s3->is8Bit());
- m_fibers[0].set(globalData, this, s1);
- m_fibers[1].set(globalData, this, s2);
- m_fibers[2].set(globalData, this, s3);
}
- void finishCreation(JSGlobalData& globalData)
+ void append(JSString* jsString)
{
- JSString::finishCreation(globalData);
+ if (m_index == JSRopeString::s_maxInternalRopeLength)
+ expand();
+ m_jsString->append(m_vm, m_index++, jsString);
}
- void append(JSGlobalData& globalData, size_t index, JSString* jsString)
- {
- m_fibers[index].set(globalData, this, jsString);
- m_length += jsString->m_length;
- setIs8Bit(is8Bit() && jsString->is8Bit());
- }
-
- static JSRopeString* createNull(JSGlobalData& globalData)
- {
- JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(globalData.heap)) JSRopeString(globalData);
- newString->finishCreation(globalData);
- return newString;
- }
-
- public:
- static JSString* create(JSGlobalData& globalData, JSString* s1, JSString* s2)
- {
- JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(globalData.heap)) JSRopeString(globalData);
- newString->finishCreation(globalData, s1, s2);
- return newString;
- }
- static JSString* create(JSGlobalData& globalData, JSString* s1, JSString* s2, JSString* s3)
+ JSRopeString* release()
{
- JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(globalData.heap)) JSRopeString(globalData);
- newString->finishCreation(globalData, s1, s2, s3);
- return newString;
+ JSRopeString* tmp = m_jsString;
+ m_jsString = 0;
+ return tmp;
}
- void visitFibers(SlotVisitor&);
+ unsigned length() { return m_jsString->m_length; }
private:
- friend JSValue jsString(ExecState*, Register*, unsigned);
- friend JSValue jsStringFromArguments(ExecState*, JSValue);
-
- JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
- void resolveRopeSlowCase8(LChar*) const;
- void resolveRopeSlowCase(UChar*) const;
- void outOfMemory(ExecState*) const;
-
- JSString* getIndexSlowCase(ExecState*, unsigned);
-
- static const unsigned s_maxInternalRopeLength = 3;
-
- mutable FixedArray<WriteBarrier<JSString>, s_maxInternalRopeLength> m_fibers;
+ void expand();
+
+ VM& m_vm;
+ JSRopeString* m_jsString;
+ size_t m_index;
};
-
- JSString* asString(JSValue);
-
- inline JSString* asString(JSValue value)
+
+private:
+ JSRopeString(VM& vm)
+ : JSString(vm)
{
- ASSERT(value.asCell()->isString());
- return jsCast<JSString*>(value.asCell());
}
- inline JSString* jsEmptyString(JSGlobalData* globalData)
+ void finishCreation(VM& vm, JSString* s1, JSString* s2)
{
- return globalData->smallStrings.emptyString(globalData);
+ Base::finishCreation(vm);
+ m_length = s1->length() + s2->length();
+ setIs8Bit(s1->is8Bit() && s2->is8Bit());
+ m_fibers[0].set(vm, this, s1);
+ m_fibers[1].set(vm, this, s2);
}
-
- ALWAYS_INLINE JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c)
+
+ void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3)
{
- if (c <= maxSingleCharacterString)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- return JSString::create(*globalData, String(&c, 1).impl());
+ Base::finishCreation(vm);
+ m_length = s1->length() + s2->length() + s3->length();
+ setIs8Bit(s1->is8Bit() && s2->is8Bit() && s3->is8Bit());
+ m_fibers[0].set(vm, this, s1);
+ m_fibers[1].set(vm, this, s2);
+ m_fibers[2].set(vm, this, s3);
}
- ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String& s, unsigned offset)
+ void finishCreation(VM& vm)
{
- JSGlobalData* globalData = &exec->globalData();
- ASSERT(offset < static_cast<unsigned>(s.length()));
- UChar c = s.characterAt(offset);
- if (c <= maxSingleCharacterString)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- return JSString::create(*globalData, StringImpl::create(s.impl(), offset, 1));
+ JSString::finishCreation(vm);
}
- inline JSString* jsNontrivialString(JSGlobalData* globalData, const String& s)
+ void append(VM& vm, size_t index, JSString* jsString)
{
- ASSERT(s.length() > 1);
- return JSString::create(*globalData, s.impl());
+ m_fibers[index].set(vm, this, jsString);
+ m_length += jsString->m_length;
+ setIs8Bit(is8Bit() && jsString->is8Bit());
}
- inline const String& JSString::value(ExecState* exec) const
+ static JSRopeString* createNull(VM& vm)
{
- if (isRope())
- static_cast<const JSRopeString*>(this)->resolveRope(exec);
- return m_value;
+ JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
+ newString->finishCreation(vm);
+ return newString;
}
- inline const String& JSString::tryGetValue() const
+public:
+ static JSString* create(VM& vm, JSString* s1, JSString* s2)
{
- if (isRope())
- static_cast<const JSRopeString*>(this)->resolveRope(0);
- return m_value;
+ JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
+ newString->finishCreation(vm, s1, s2);
+ return newString;
}
-
- inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
+ static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3)
{
- ASSERT(canGetIndex(i));
- if (isRope())
- return static_cast<JSRopeString*>(this)->getIndexSlowCase(exec, i);
- ASSERT(i < m_value.length());
- return jsSingleCharacterSubstring(exec, m_value, i);
+ JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
+ newString->finishCreation(vm, s1, s2, s3);
+ return newString;
}
- inline JSString* jsString(JSGlobalData* globalData, const String& s)
- {
- int size = s.length();
- if (!size)
- return globalData->smallStrings.emptyString(globalData);
- if (size == 1) {
- UChar c = s.characterAt(0);
- if (c <= maxSingleCharacterString)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return JSString::create(*globalData, s.impl());
- }
+ void visitFibers(SlotVisitor&);
+
+ static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, m_fibers); }
- inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
- {
- ASSERT(offset <= static_cast<unsigned>(s->length()));
- ASSERT(length <= static_cast<unsigned>(s->length()));
- ASSERT(offset + length <= static_cast<unsigned>(s->length()));
- JSGlobalData* globalData = &exec->globalData();
- if (!length)
- return globalData->smallStrings.emptyString(globalData);
- return jsSubstring(globalData, s->value(exec), offset, length);
+ static const unsigned s_maxInternalRopeLength = 3;
+
+private:
+ friend JSValue jsString(ExecState*, Register*, unsigned);
+ friend JSValue jsStringFromArguments(ExecState*, JSValue);
+
+ JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
+ void resolveRopeSlowCase8(LChar*) const;
+ void resolveRopeSlowCase(UChar*) const;
+ void outOfMemory(ExecState*) const;
+
+ JSString* getIndexSlowCase(ExecState*, unsigned);
+
+ mutable FixedArray<WriteBarrier<JSString>, s_maxInternalRopeLength> m_fibers;
+};
+
+JSString* asString(JSValue);
+
+inline JSString* asString(JSValue value)
+{
+ ASSERT(value.asCell()->isString());
+ return jsCast<JSString*>(value.asCell());
+}
+
+inline JSString* jsEmptyString(VM* vm)
+{
+ return vm->smallStrings.emptyString();
+}
+
+ALWAYS_INLINE JSString* jsSingleCharacterString(VM* vm, UChar c)
+{
+ if (c <= maxSingleCharacterString)
+ return vm->smallStrings.singleCharacterString(vm, c);
+ return JSString::create(*vm, String(&c, 1).impl());
+}
+
+ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String& s, unsigned offset)
+{
+ VM* vm = &exec->vm();
+ ASSERT(offset < static_cast<unsigned>(s.length()));
+ UChar c = s.characterAt(offset);
+ if (c <= maxSingleCharacterString)
+ return vm->smallStrings.singleCharacterString(vm, c);
+ return JSString::create(*vm, StringImpl::create(s.impl(), offset, 1));
+}
+
+inline JSString* jsNontrivialString(VM* vm, const String& s)
+{
+ ASSERT(s.length() > 1);
+ return JSString::create(*vm, s.impl());
+}
+
+inline const String& JSString::value(ExecState* exec) const
+{
+ if (isRope())
+ static_cast<const JSRopeString*>(this)->resolveRope(exec);
+ return m_value;
+}
+
+inline const String& JSString::tryGetValue() const
+{
+ if (isRope())
+ static_cast<const JSRopeString*>(this)->resolveRope(0);
+ return m_value;
+}
+
+inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
+{
+ ASSERT(canGetIndex(i));
+ if (isRope())
+ return static_cast<JSRopeString*>(this)->getIndexSlowCase(exec, i);
+ ASSERT(i < m_value.length());
+ return jsSingleCharacterSubstring(exec, m_value, i);
+}
+
+inline JSString* jsString(VM* vm, const String& s)
+{
+ int size = s.length();
+ if (!size)
+ return vm->smallStrings.emptyString();
+ if (size == 1) {
+ UChar c = s.characterAt(0);
+ if (c <= maxSingleCharacterString)
+ return vm->smallStrings.singleCharacterString(vm, c);
}
-
- inline JSString* jsSubstring8(JSGlobalData* globalData, const String& s, unsigned offset, unsigned length)
- {
- ASSERT(offset <= static_cast<unsigned>(s.length()));
- ASSERT(length <= static_cast<unsigned>(s.length()));
- ASSERT(offset + length <= static_cast<unsigned>(s.length()));
- if (!length)
- return globalData->smallStrings.emptyString(globalData);
- if (length == 1) {
- UChar c = s.characterAt(offset);
- if (c <= maxSingleCharacterString)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return JSString::createHasOtherOwner(*globalData, StringImpl::create8(s.impl(), offset, length));
+ return JSString::create(*vm, s.impl());
+}
+
+inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
+{
+ ASSERT(offset <= static_cast<unsigned>(s->length()));
+ ASSERT(length <= static_cast<unsigned>(s->length()));
+ ASSERT(offset + length <= static_cast<unsigned>(s->length()));
+ VM* vm = &exec->vm();
+ if (!length)
+ return vm->smallStrings.emptyString();
+ return jsSubstring(vm, s->value(exec), offset, length);
+}
+
+inline JSString* jsSubstring8(VM* vm, const String& s, unsigned offset, unsigned length)
+{
+ ASSERT(offset <= static_cast<unsigned>(s.length()));
+ ASSERT(length <= static_cast<unsigned>(s.length()));
+ ASSERT(offset + length <= static_cast<unsigned>(s.length()));
+ if (!length)
+ return vm->smallStrings.emptyString();
+ if (length == 1) {
+ UChar c = s.characterAt(offset);
+ if (c <= maxSingleCharacterString)
+ return vm->smallStrings.singleCharacterString(vm, c);
}
-
- inline JSString* jsSubstring(JSGlobalData* globalData, const String& s, unsigned offset, unsigned length)
- {
- ASSERT(offset <= static_cast<unsigned>(s.length()));
- ASSERT(length <= static_cast<unsigned>(s.length()));
- ASSERT(offset + length <= static_cast<unsigned>(s.length()));
- if (!length)
- return globalData->smallStrings.emptyString(globalData);
- if (length == 1) {
- UChar c = s.characterAt(offset);
- if (c <= maxSingleCharacterString)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length));
+ return JSString::createHasOtherOwner(*vm, StringImpl::create8(s.impl(), offset, length));
+}
+
+inline JSString* jsSubstring(VM* vm, const String& s, unsigned offset, unsigned length)
+{
+ ASSERT(offset <= static_cast<unsigned>(s.length()));
+ ASSERT(length <= static_cast<unsigned>(s.length()));
+ ASSERT(offset + length <= static_cast<unsigned>(s.length()));
+ if (!length)
+ return vm->smallStrings.emptyString();
+ if (length == 1) {
+ UChar c = s.characterAt(offset);
+ if (c <= maxSingleCharacterString)
+ return vm->smallStrings.singleCharacterString(vm, c);
}
-
- inline JSString* jsOwnedString(JSGlobalData* globalData, const String& s)
- {
- int size = s.length();
- if (!size)
- return globalData->smallStrings.emptyString(globalData);
- if (size == 1) {
- UChar c = s.characterAt(0);
- if (c <= maxSingleCharacterString)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return JSString::createHasOtherOwner(*globalData, s.impl());
+ return JSString::createHasOtherOwner(*vm, StringImpl::create(s.impl(), offset, length));
+}
+
+inline JSString* jsOwnedString(VM* vm, const String& s)
+{
+ int size = s.length();
+ if (!size)
+ return vm->smallStrings.emptyString();
+ if (size == 1) {
+ UChar c = s.characterAt(0);
+ if (c <= maxSingleCharacterString)
+ return vm->smallStrings.singleCharacterString(vm, c);
}
-
- inline JSRopeString* jsStringBuilder(JSGlobalData* globalData)
- {
- return JSRopeString::createNull(*globalData);
+ return JSString::createHasOtherOwner(*vm, s.impl());
+}
+
+inline JSRopeString* jsStringBuilder(VM* vm)
+{
+ return JSRopeString::createNull(*vm);
+}
+
+inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->vm()); }
+inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->vm(), s); }
+inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->vm(), c); }
+inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->vm(), s, offset, length); }
+inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->vm(), s, offset, length); }
+inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->vm(), s); }
+inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->vm(), s); }
+
+ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+{
+ if (propertyName == exec->propertyNames().length) {
+ slot.setValue(jsNumber(m_length));
+ return true;
}
- inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
- inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->globalData(), s); }
- inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); }
- inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->globalData(), s, offset, length); }
- inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); }
- inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->globalData(), s); }
- inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->globalData(), s); }
-
- ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
- {
- if (propertyName == exec->propertyNames().length) {
- slot.setValue(jsNumber(m_length));
- return true;
- }
-
- unsigned i = propertyName.asIndex();
- if (i < m_length) {
- ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
- slot.setValue(getIndex(exec, i));
- return true;
- }
-
- return false;
+ unsigned i = propertyName.asIndex();
+ if (i < m_length) {
+ ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
+ slot.setValue(getIndex(exec, i));
+ return true;
}
-
- ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
- {
- if (propertyName < m_length) {
- slot.setValue(getIndex(exec, propertyName));
- return true;
- }
- return false;
+ return false;
+}
+
+ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+ if (propertyName < m_length) {
+ slot.setValue(getIndex(exec, propertyName));
+ return true;
}
- inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->classInfo() == &JSString::s_info; }
+ return false;
+}
- inline bool JSCell::toBoolean(ExecState* exec) const
- {
- if (isString())
- return static_cast<const JSString*>(this)->toBoolean();
- return !structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
- }
+inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->classInfo() == &JSString::s_info; }
- // --- JSValue inlines ----------------------------
+// --- JSValue inlines ----------------------------
- inline bool JSValue::toBoolean(ExecState* exec) const
- {
- if (isInt32())
- return asInt32();
- if (isDouble())
- return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
- if (isCell())
- return asCell()->toBoolean(exec);
- return isTrue(); // false, null, and undefined all convert to false.
- }
-
- inline JSString* JSValue::toString(ExecState* exec) const
- {
- if (isString())
- return jsCast<JSString*>(asCell());
- return toStringSlowCase(exec);
- }
-
- inline String JSValue::toWTFString(ExecState* exec) const
- {
- if (isString())
- return static_cast<JSString*>(asCell())->value(exec);
- return toWTFStringSlowCase(exec);
- }
-
- ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
- {
- JSGlobalData& globalData = exec->globalData();
- if (value.isInt32())
- return globalData.numericStrings.add(value.asInt32());
- if (value.isDouble())
- return globalData.numericStrings.add(value.asDouble());
- if (value.isTrue())
- return globalData.propertyNames->trueKeyword.string();
- if (value.isFalse())
- return globalData.propertyNames->falseKeyword.string();
- if (value.isNull())
- return globalData.propertyNames->nullKeyword.string();
- if (value.isUndefined())
- return globalData.propertyNames->undefinedKeyword.string();
- return value.toString(exec)->value(exec);
- }
-
- ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
- {
- if (isString())
- return static_cast<JSString*>(asCell())->value(exec);
-
- return inlineJSValueNotStringtoString(*this, exec);
- }
+inline bool JSValue::toBoolean(ExecState* exec) const
+{
+ if (isInt32())
+ return asInt32();
+ if (isDouble())
+ return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
+ if (isCell())
+ return asCell()->toBoolean(exec);
+ return isTrue(); // false, null, and undefined all convert to false.
+}
+
+inline JSString* JSValue::toString(ExecState* exec) const
+{
+ if (isString())
+ return jsCast<JSString*>(asCell());
+ return toStringSlowCase(exec);
+}
+
+inline String JSValue::toWTFString(ExecState* exec) const
+{
+ if (isString())
+ return static_cast<JSString*>(asCell())->value(exec);
+ return toWTFStringSlowCase(exec);
+}
+
+ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
+{
+ VM& vm = exec->vm();
+ if (value.isInt32())
+ return vm.numericStrings.add(value.asInt32());
+ if (value.isDouble())
+ return vm.numericStrings.add(value.asDouble());
+ if (value.isTrue())
+ return vm.propertyNames->trueKeyword.string();
+ if (value.isFalse())
+ return vm.propertyNames->falseKeyword.string();
+ if (value.isNull())
+ return vm.propertyNames->nullKeyword.string();
+ if (value.isUndefined())
+ return vm.propertyNames->undefinedKeyword.string();
+ return value.toString(exec)->value(exec);
+}
+
+ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
+{
+ if (isString())
+ return static_cast<JSString*>(asCell())->value(exec);
+
+ return inlineJSValueNotStringtoString(*this, exec);
+}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSStringBuilder.h b/Source/JavaScriptCore/runtime/JSStringBuilder.h
index e7778e4fb..5d4960e89 100644
--- a/Source/JavaScriptCore/runtime/JSStringBuilder.h
+++ b/Source/JavaScriptCore/runtime/JSStringBuilder.h
@@ -137,8 +137,8 @@ public:
}
protected:
- Vector<LChar, 64> buffer8;
- Vector<UChar, 64> buffer16;
+ Vector<LChar, 64, UnsafeVectorOverflow> buffer8;
+ Vector<UChar, 64, UnsafeVectorOverflow> buffer16;
bool m_okay;
bool m_is8Bit;
};
diff --git a/Source/JavaScriptCore/runtime/JSStringJoiner.cpp b/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
index cbf9ba48b..7e20d2195 100644
--- a/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
+++ b/Source/JavaScriptCore/runtime/JSStringJoiner.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,9 +29,9 @@
#include "ExceptionHelpers.h"
#include "JSScope.h"
#include "JSString.h"
+#include "Operations.h"
#include <wtf/text/StringImpl.h>
-
namespace JSC {
// The destination is 16bits, at least one string is 16 bits.
@@ -94,7 +94,7 @@ static inline PassRefPtr<StringImpl> joinStrings(const Vector<String>& strings,
return outputStringImpl.release();
}
-JSValue JSStringJoiner::build(ExecState* exec)
+JSValue JSStringJoiner::join(ExecState* exec)
{
if (!m_isValid)
return throwOutOfMemoryError(exec);
@@ -102,25 +102,29 @@ JSValue JSStringJoiner::build(ExecState* exec)
if (!m_strings.size())
return jsEmptyString(exec);
- size_t separatorLength = m_separator.length();
+ Checked<size_t, RecordOverflow> separatorLength = m_separator.length();
// FIXME: add special cases of joinStrings() for (separatorLength == 0) and (separatorLength == 1).
ASSERT(m_strings.size() > 0);
- size_t totalSeparactorsLength = separatorLength * (m_strings.size() - 1);
- size_t outputStringSize = totalSeparactorsLength + m_cumulatedStringsLength;
+ Checked<size_t, RecordOverflow> totalSeparactorsLength = separatorLength * (m_strings.size() - 1);
+ Checked<size_t, RecordOverflow> outputStringSize = totalSeparactorsLength + m_accumulatedStringsLength;
+ size_t finalSize;
+ if (outputStringSize.safeGet(finalSize) == CheckedState::DidOverflow)
+ return throwOutOfMemoryError(exec);
+
if (!outputStringSize)
return jsEmptyString(exec);
RefPtr<StringImpl> outputStringImpl;
if (m_is8Bits)
- outputStringImpl = joinStrings<LChar>(m_strings, m_separator, outputStringSize);
+ outputStringImpl = joinStrings<LChar>(m_strings, m_separator, finalSize);
else
- outputStringImpl = joinStrings<UChar>(m_strings, m_separator, outputStringSize);
+ outputStringImpl = joinStrings<UChar>(m_strings, m_separator, finalSize);
if (!outputStringImpl)
return throwOutOfMemoryError(exec);
- return JSString::create(exec->globalData(), outputStringImpl.release());
+ return JSString::create(exec->vm(), outputStringImpl.release());
}
}
diff --git a/Source/JavaScriptCore/runtime/JSStringJoiner.h b/Source/JavaScriptCore/runtime/JSStringJoiner.h
index 5cb841a80..73950c6d7 100644
--- a/Source/JavaScriptCore/runtime/JSStringJoiner.h
+++ b/Source/JavaScriptCore/runtime/JSStringJoiner.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
#ifndef JSStringJoiner_h
#define JSStringJoiner_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
@@ -40,20 +40,19 @@ public:
JSStringJoiner(const String& separator, size_t stringCount);
void append(const String&);
- JSValue build(ExecState*);
+ JSValue join(ExecState*);
private:
String m_separator;
Vector<String> m_strings;
- unsigned m_cumulatedStringsLength;
+ Checked<unsigned, RecordOverflow> m_accumulatedStringsLength;
bool m_isValid;
bool m_is8Bits;
};
inline JSStringJoiner::JSStringJoiner(const String& separator, size_t stringCount)
: m_separator(separator)
- , m_cumulatedStringsLength(0)
, m_isValid(true)
, m_is8Bits(m_separator.is8Bit())
{
@@ -66,9 +65,9 @@ inline void JSStringJoiner::append(const String& str)
if (!m_isValid)
return;
- m_strings.uncheckedAppend(str);
+ m_strings.append(str);
if (!str.isNull()) {
- m_cumulatedStringsLength += str.length();
+ m_accumulatedStringsLength += str.length();
m_is8Bits = m_is8Bits && str.is8Bit();
}
}
diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
index 7dcde4700..16b20d9db 100644
--- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp
@@ -32,6 +32,7 @@
#include "JSActivation.h"
#include "JSGlobalObject.h"
#include "JSNameScope.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
namespace JSC {
@@ -70,7 +71,7 @@ void JSSymbolTableObject::getOwnNonIndexPropertyNames(JSObject* object, ExecStat
void JSSymbolTableObject::putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned)
{
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
index 913679f80..6db2b88ab 100644
--- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
+++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
@@ -41,7 +41,7 @@ public:
SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
- static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
+ static NO_RETURN_DUE_TO_CRASH void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes);
JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
@@ -49,18 +49,18 @@ public:
protected:
static const unsigned StructureFlags = IsEnvironmentRecord | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
- JSSymbolTableObject(JSGlobalData& globalData, Structure* structure, JSScope* scope, SharedSymbolTable* symbolTable = 0)
- : Base(globalData, structure, scope)
+ JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SharedSymbolTable* symbolTable = 0)
+ : Base(vm, structure, scope)
{
if (symbolTable)
- m_symbolTable.set(globalData, this, symbolTable);
+ m_symbolTable.set(vm, this, symbolTable);
}
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
if (!m_symbolTable)
- m_symbolTable.set(globalData, this, SharedSymbolTable::create(globalData));
+ m_symbolTable.set(vm, this, SharedSymbolTable::create(vm));
}
static void visitChildren(JSCell*, SlotVisitor&);
@@ -118,7 +118,7 @@ inline bool symbolTablePut(
SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, JSValue value,
bool shouldThrow)
{
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
SymbolTable& symbolTable = *object->symbolTable();
@@ -135,13 +135,13 @@ inline bool symbolTablePut(
}
if (UNLIKELY(wasFat))
iter->value.notifyWrite();
- object->registerAt(fastEntry.getIndex()).set(globalData, object, value);
+ object->registerAt(fastEntry.getIndex()).set(vm, object, value);
return true;
}
template<typename SymbolTableObjectType>
inline bool symbolTablePutWithAttributes(
- SymbolTableObjectType* object, JSGlobalData& globalData, PropertyName propertyName,
+ SymbolTableObjectType* object, VM& vm, PropertyName propertyName,
JSValue value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
@@ -153,7 +153,7 @@ inline bool symbolTablePutWithAttributes(
ASSERT(!entry.isNull());
entry.notifyWrite();
entry.setAttributes(attributes);
- object->registerAt(entry.getIndex()).set(globalData, object, value);
+ object->registerAt(entry.getIndex()).set(vm, object, value);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/JSTypeInfo.h b/Source/JavaScriptCore/runtime/JSTypeInfo.h
index 97fc64c1c..109a032bd 100644
--- a/Source/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/Source/JavaScriptCore/runtime/JSTypeInfo.h
@@ -47,6 +47,7 @@ namespace JSC {
static const unsigned OverridesGetPropertyNames = 1 << 8;
static const unsigned ProhibitsPropertyCaching = 1 << 9;
static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
+ static const unsigned StructureHasRareData = 1 << 11;
class TypeInfo {
public:
@@ -70,6 +71,7 @@ namespace JSC {
bool isNumberObject() const { return type() == NumberObjectType; }
bool isName() const { return type() == NameInstanceType; }
+ unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
bool isEnvironmentRecord() const { return isSetOnFlags1(IsEnvironmentRecord); }
@@ -81,6 +83,7 @@ namespace JSC {
bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
+ bool structureHasRareData() const { return isSetOnFlags2(StructureHasRareData); }
static ptrdiff_t flagsOffset()
{
diff --git a/Source/JavaScriptCore/runtime/JSValueInlines.h b/Source/JavaScriptCore/runtime/JSValueInlines.h
deleted file mode 100644
index c5a42f67f..000000000
--- a/Source/JavaScriptCore/runtime/JSValueInlines.h
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSValueInlines_h
-#define JSValueInlines_h
-
-#include "JSValue.h"
-
-namespace JSC {
-
- ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
- {
- if (isInt32())
- return asInt32();
- return JSC::toInt32(toNumber(exec));
- }
-
- inline uint32_t JSValue::toUInt32(ExecState* exec) const
- {
- // See comment on JSC::toUInt32, above.
- return toInt32(exec);
- }
-
- inline bool JSValue::isUInt32() const
- {
- return isInt32() && asInt32() >= 0;
- }
-
- inline uint32_t JSValue::asUInt32() const
- {
- ASSERT(isUInt32());
- return asInt32();
- }
-
- inline double JSValue::asNumber() const
- {
- ASSERT(isNumber());
- return isInt32() ? asInt32() : asDouble();
- }
-
- inline JSValue jsNaN()
- {
- return JSValue(QNaN);
- }
-
- inline JSValue::JSValue(char i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned char i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(short i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned short i)
- {
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned i)
- {
- if (static_cast<int32_t>(i) < 0) {
- *this = JSValue(EncodeAsDouble, static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(long i)
- {
- if (static_cast<int32_t>(i) != i) {
- *this = JSValue(EncodeAsDouble, static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned long i)
- {
- if (static_cast<uint32_t>(i) != i) {
- *this = JSValue(EncodeAsDouble, static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<uint32_t>(i));
- }
-
- inline JSValue::JSValue(long long i)
- {
- if (static_cast<int32_t>(i) != i) {
- *this = JSValue(EncodeAsDouble, static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<int32_t>(i));
- }
-
- inline JSValue::JSValue(unsigned long long i)
- {
- if (static_cast<uint32_t>(i) != i) {
- *this = JSValue(EncodeAsDouble, static_cast<double>(i));
- return;
- }
- *this = JSValue(static_cast<uint32_t>(i));
- }
-
- inline JSValue::JSValue(double d)
- {
- const int32_t asInt32 = static_cast<int32_t>(d);
- if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
- *this = JSValue(EncodeAsDouble, d);
- return;
- }
- *this = JSValue(static_cast<int32_t>(d));
- }
-
- inline EncodedJSValue JSValue::encode(JSValue value)
- {
- return value.u.asInt64;
- }
-
- inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
- {
- JSValue v;
- v.u.asInt64 = encodedJSValue;
- return v;
- }
-
-#if USE(JSVALUE32_64)
- inline JSValue::JSValue()
- {
- u.asBits.tag = EmptyValueTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSNullTag)
- {
- u.asBits.tag = NullTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSUndefinedTag)
- {
- u.asBits.tag = UndefinedTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSTrueTag)
- {
- u.asBits.tag = BooleanTag;
- u.asBits.payload = 1;
- }
-
- inline JSValue::JSValue(JSFalseTag)
- {
- u.asBits.tag = BooleanTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(HashTableDeletedValueTag)
- {
- u.asBits.tag = DeletedValueTag;
- u.asBits.payload = 0;
- }
-
- inline JSValue::JSValue(JSCell* ptr)
- {
- if (ptr)
- u.asBits.tag = CellTag;
- else
- u.asBits.tag = EmptyValueTag;
- u.asBits.payload = reinterpret_cast<int32_t>(ptr);
- }
-
- inline JSValue::JSValue(const JSCell* ptr)
- {
- if (ptr)
- u.asBits.tag = CellTag;
- else
- u.asBits.tag = EmptyValueTag;
- u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
- }
-
- inline JSValue::operator bool() const
- {
- ASSERT(tag() != DeletedValueTag);
- return tag() != EmptyValueTag;
- }
-
- inline bool JSValue::operator==(const JSValue& other) const
- {
- return u.asInt64 == other.u.asInt64;
- }
-
- inline bool JSValue::operator!=(const JSValue& other) const
- {
- return u.asInt64 != other.u.asInt64;
- }
-
- inline bool JSValue::isEmpty() const
- {
- return tag() == EmptyValueTag;
- }
-
- inline bool JSValue::isUndefined() const
- {
- return tag() == UndefinedTag;
- }
-
- inline bool JSValue::isNull() const
- {
- return tag() == NullTag;
- }
-
- inline bool JSValue::isUndefinedOrNull() const
- {
- return isUndefined() || isNull();
- }
-
- inline bool JSValue::isCell() const
- {
- return tag() == CellTag;
- }
-
- inline bool JSValue::isInt32() const
- {
- return tag() == Int32Tag;
- }
-
- inline bool JSValue::isDouble() const
- {
- return tag() < LowestTag;
- }
-
- inline bool JSValue::isTrue() const
- {
- return tag() == BooleanTag && payload();
- }
-
- inline bool JSValue::isFalse() const
- {
- return tag() == BooleanTag && !payload();
- }
-
- inline uint32_t JSValue::tag() const
- {
- return u.asBits.tag;
- }
-
- inline int32_t JSValue::payload() const
- {
- return u.asBits.payload;
- }
-
- inline int32_t JSValue::asInt32() const
- {
- ASSERT(isInt32());
- return u.asBits.payload;
- }
-
- inline double JSValue::asDouble() const
- {
- ASSERT(isDouble());
- return u.asDouble;
- }
-
- ALWAYS_INLINE JSCell* JSValue::asCell() const
- {
- ASSERT(isCell());
- return reinterpret_cast<JSCell*>(u.asBits.payload);
- }
-
- ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
- {
- u.asDouble = d;
- }
-
- inline JSValue::JSValue(int i)
- {
- u.asBits.tag = Int32Tag;
- u.asBits.payload = i;
- }
-
-#if ENABLE(LLINT_C_LOOP)
- inline JSValue::JSValue(int32_t tag, int32_t payload)
- {
- u.asBits.tag = tag;
- u.asBits.payload = payload;
- }
-#endif
-
- inline bool JSValue::isNumber() const
- {
- return isInt32() || isDouble();
- }
-
- inline bool JSValue::isBoolean() const
- {
- return isTrue() || isFalse();
- }
-
- inline bool JSValue::asBoolean() const
- {
- ASSERT(isBoolean());
- return payload();
- }
-
-#else // !USE(JSVALUE32_64) i.e. USE(JSVALUE64)
-
- // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
- inline JSValue::JSValue()
- {
- u.asInt64 = ValueEmpty;
- }
-
- // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
- inline JSValue::JSValue(HashTableDeletedValueTag)
- {
- u.asInt64 = ValueDeleted;
- }
-
- inline JSValue::JSValue(JSCell* ptr)
- {
- u.asInt64 = reinterpret_cast<uintptr_t>(ptr);
- }
-
- inline JSValue::JSValue(const JSCell* ptr)
- {
- u.asInt64 = reinterpret_cast<uintptr_t>(const_cast<JSCell*>(ptr));
- }
-
- inline JSValue::operator bool() const
- {
- return u.asInt64;
- }
-
- inline bool JSValue::operator==(const JSValue& other) const
- {
- return u.asInt64 == other.u.asInt64;
- }
-
- inline bool JSValue::operator!=(const JSValue& other) const
- {
- return u.asInt64 != other.u.asInt64;
- }
-
- inline bool JSValue::isEmpty() const
- {
- return u.asInt64 == ValueEmpty;
- }
-
- inline bool JSValue::isUndefined() const
- {
- return asValue() == JSValue(JSUndefined);
- }
-
- inline bool JSValue::isNull() const
- {
- return asValue() == JSValue(JSNull);
- }
-
- inline bool JSValue::isTrue() const
- {
- return asValue() == JSValue(JSTrue);
- }
-
- inline bool JSValue::isFalse() const
- {
- return asValue() == JSValue(JSFalse);
- }
-
- inline bool JSValue::asBoolean() const
- {
- ASSERT(isBoolean());
- return asValue() == JSValue(JSTrue);
- }
-
- inline int32_t JSValue::asInt32() const
- {
- ASSERT(isInt32());
- return static_cast<int32_t>(u.asInt64);
- }
-
- inline bool JSValue::isDouble() const
- {
- return isNumber() && !isInt32();
- }
-
- inline JSValue::JSValue(JSNullTag)
- {
- u.asInt64 = ValueNull;
- }
-
- inline JSValue::JSValue(JSUndefinedTag)
- {
- u.asInt64 = ValueUndefined;
- }
-
- inline JSValue::JSValue(JSTrueTag)
- {
- u.asInt64 = ValueTrue;
- }
-
- inline JSValue::JSValue(JSFalseTag)
- {
- u.asInt64 = ValueFalse;
- }
-
- inline bool JSValue::isUndefinedOrNull() const
- {
- // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
- return (u.asInt64 & ~TagBitUndefined) == ValueNull;
- }
-
- inline bool JSValue::isBoolean() const
- {
- return (u.asInt64 & ~1) == ValueFalse;
- }
-
- inline bool JSValue::isCell() const
- {
- return !(u.asInt64 & TagMask);
- }
-
- inline bool JSValue::isInt32() const
- {
- return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
- }
-
- inline int64_t reinterpretDoubleToInt64(double value)
- {
- return bitwise_cast<int64_t>(value);
- }
- inline double reinterpretInt64ToDouble(int64_t value)
- {
- return bitwise_cast<double>(value);
- }
-
- ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
- {
- u.asInt64 = reinterpretDoubleToInt64(d) + DoubleEncodeOffset;
- }
-
- inline JSValue::JSValue(int i)
- {
- u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
- }
-
- inline double JSValue::asDouble() const
- {
- ASSERT(isDouble());
- return reinterpretInt64ToDouble(u.asInt64 - DoubleEncodeOffset);
- }
-
- inline bool JSValue::isNumber() const
- {
- return u.asInt64 & TagTypeNumber;
- }
-
- ALWAYS_INLINE JSCell* JSValue::asCell() const
- {
- ASSERT(isCell());
- return u.ptr;
- }
-
-#endif // USE(JSVALUE64)
-
-} // namespace JSC
-
-#endif // JSValueInlines_h
-
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.cpp b/Source/JavaScriptCore/runtime/JSVariableObject.cpp
index 9b03a2c64..fc262f5d8 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.cpp
@@ -29,6 +29,8 @@
#include "config.h"
#include "JSVariableObject.h"
+#include "Operations.h"
+
namespace JSC {
const ClassInfo JSVariableObject::s_info = { "VariableObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSVariableObject) };
diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h
index 3ff7aa841..615aa331f 100644
--- a/Source/JavaScriptCore/runtime/JSVariableObject.h
+++ b/Source/JavaScriptCore/runtime/JSVariableObject.h
@@ -33,7 +33,6 @@
#include "JSSymbolTableObject.h"
#include "Register.h"
#include "SymbolTable.h"
-#include <wtf/UnusedParam.h>
#include <wtf/OwnArrayPtr.h>
namespace JSC {
@@ -59,13 +58,13 @@ namespace JSC {
static const unsigned StructureFlags = Base::StructureFlags;
JSVariableObject(
- JSGlobalData& globalData,
+ VM& vm,
Structure* structure,
Register* registers,
JSScope* scope,
SharedSymbolTable* symbolTable = 0
)
- : Base(globalData, structure, scope, symbolTable)
+ : Base(vm, structure, scope, symbolTable)
, m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
{
}
diff --git a/Source/JavaScriptCore/runtime/JSWithScope.cpp b/Source/JavaScriptCore/runtime/JSWithScope.cpp
index 7d74e63c3..c0c6c1f7b 100644
--- a/Source/JavaScriptCore/runtime/JSWithScope.cpp
+++ b/Source/JavaScriptCore/runtime/JSWithScope.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "JSWithScope.h"
+#include "Operations.h"
+
namespace JSC {
const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWithScope) };
diff --git a/Source/JavaScriptCore/runtime/JSWithScope.h b/Source/JavaScriptCore/runtime/JSWithScope.h
index ba2b793a9..ea879cb54 100644
--- a/Source/JavaScriptCore/runtime/JSWithScope.h
+++ b/Source/JavaScriptCore/runtime/JSWithScope.h
@@ -37,14 +37,14 @@ public:
static JSWithScope* create(ExecState* exec, JSObject* object)
{
JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object);
- withScope->finishCreation(exec->globalData());
+ withScope->finishCreation(exec->vm());
return withScope;
}
static JSWithScope* create(ExecState* exec, JSObject* object, JSScope* next)
{
JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object, next);
- withScope->finishCreation(exec->globalData());
+ withScope->finishCreation(exec->vm());
return withScope;
}
@@ -52,9 +52,9 @@ public:
static void visitChildren(JSCell*, SlotVisitor&);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(WithScopeType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(WithScopeType, StructureFlags), &s_info);
}
static JS_EXPORTDATA const ClassInfo s_info;
@@ -65,21 +65,21 @@ protected:
private:
JSWithScope(ExecState* exec, JSObject* object)
: Base(
- exec->globalData(),
+ exec->vm(),
exec->lexicalGlobalObject()->withScopeStructure(),
exec->scope()
)
- , m_object(exec->globalData(), this, object)
+ , m_object(exec->vm(), this, object)
{
}
JSWithScope(ExecState* exec, JSObject* object, JSScope* next)
: Base(
- exec->globalData(),
+ exec->vm(),
exec->lexicalGlobalObject()->withScopeStructure(),
next
)
- , m_object(exec->globalData(), this, object)
+ , m_object(exec->vm(), this, object)
{
}
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
index ff80c1e20..01961a984 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Maks Orlovich
- * Copyright (C) 2006, 2009 Apple, Inc.
+ * Copyright (C) 2006, 2009, 2012 Apple, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,6 +22,8 @@
#include "config.h"
#include "JSWrapperObject.h"
+#include "Operations.h"
+
namespace JSC {
ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSWrapperObject);
diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h
index 72bc1874c..f1b6d3286 100644
--- a/Source/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h
@@ -32,16 +32,32 @@ namespace JSC {
public:
typedef JSDestructibleObject Base;
+ static size_t allocationSize(size_t inlineCapacity)
+ {
+ ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
+ return sizeof(JSWrapperObject);
+ }
+
JSValue internalValue() const;
- void setInternalValue(JSGlobalData&, JSValue);
+ void setInternalValue(VM&, JSValue);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ }
+
+ static ptrdiff_t internalValueOffset() { return OBJECT_OFFSETOF(JSWrapperObject, m_internalValue); }
+ static ptrdiff_t internalValueCellOffset()
+ {
+#if USE(JSVALUE64)
+ return internalValueOffset();
+#else
+ return internalValueOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload);
+#endif
}
protected:
- explicit JSWrapperObject(JSGlobalData&, Structure*);
+ explicit JSWrapperObject(VM&, Structure*);
static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
static void visitChildren(JSCell*, SlotVisitor&);
@@ -50,8 +66,8 @@ namespace JSC {
WriteBarrier<Unknown> m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, Structure* structure)
- : JSDestructibleObject(globalData, structure)
+ inline JSWrapperObject::JSWrapperObject(VM& vm, Structure* structure)
+ : JSDestructibleObject(vm, structure)
{
}
@@ -60,11 +76,11 @@ namespace JSC {
return m_internalValue.get();
}
- inline void JSWrapperObject::setInternalValue(JSGlobalData& globalData, JSValue value)
+ inline void JSWrapperObject::setInternalValue(VM& vm, JSValue value)
{
ASSERT(value);
ASSERT(!value.isObject());
- m_internalValue.set(globalData, this, value);
+ m_internalValue.set(vm, this, value);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp
index bf27327bf..f594518b6 100644
--- a/Source/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp
@@ -32,6 +32,8 @@
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
#include "StrongInlines.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
@@ -55,22 +57,24 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
do {
Vector<JSONPPathEntry> path;
// Unguarded next to start off the lexer
- Identifier name = Identifier(&m_exec->globalData(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+ Identifier name = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
JSONPPathEntry entry;
- if (name == m_exec->globalData().propertyNames->varKeyword) {
+ if (name == m_exec->vm().propertyNames->varKeyword) {
if (m_lexer.next() != TokIdentifier)
return false;
entry.m_type = JSONPPathEntryTypeDeclare;
- entry.m_pathEntryName = Identifier(&m_exec->globalData(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+ entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
path.append(entry);
} else {
entry.m_type = JSONPPathEntryTypeDot;
- entry.m_pathEntryName = Identifier(&m_exec->globalData(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+ entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
path.append(entry);
}
- if (m_exec->globalData().keywords->isKeyword(entry.m_pathEntryName))
+ if (m_exec->vm().keywords->isKeyword(entry.m_pathEntryName))
return false;
TokenType tokenType = m_lexer.next();
+ if (entry.m_type == JSONPPathEntryTypeDeclare && tokenType != TokAssign)
+ return false;
while (tokenType != TokAssign) {
switch (tokenType) {
case TokLBracket: {
@@ -90,7 +94,7 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
entry.m_type = JSONPPathEntryTypeDot;
if (m_lexer.next() != TokIdentifier)
return false;
- entry.m_pathEntryName = Identifier(&m_exec->globalData(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
+ entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start);
break;
}
case TokLParen: {
@@ -109,7 +113,7 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee
startJSON:
m_lexer.next();
results.append(JSONPData());
- results.last().m_value.set(m_exec->globalData(), parse(StartParseExpression));
+ results.last().m_value.set(m_exec->vm(), parse(StartParseExpression));
if (!results.last().m_value)
return false;
results.last().m_path.swap(path);
@@ -129,19 +133,19 @@ template <typename CharType>
ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const LChar* characters, size_t length)
{
if (!length)
- return m_exec->globalData().propertyNames->emptyIdentifier;
+ return m_exec->vm().propertyNames->emptyIdentifier;
if (characters[0] >= MaximumCachableCharacter)
- return Identifier(&m_exec->globalData(), characters, length);
+ return Identifier(&m_exec->vm(), characters, length);
if (length == 1) {
if (!m_shortIdentifiers[characters[0]].isNull())
return m_shortIdentifiers[characters[0]];
- m_shortIdentifiers[characters[0]] = Identifier(&m_exec->globalData(), characters, length);
+ m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
return m_shortIdentifiers[characters[0]];
}
if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length))
return m_recentIdentifiers[characters[0]];
- m_recentIdentifiers[characters[0]] = Identifier(&m_exec->globalData(), characters, length);
+ m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
return m_recentIdentifiers[characters[0]];
}
@@ -149,19 +153,19 @@ template <typename CharType>
ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const UChar* characters, size_t length)
{
if (!length)
- return m_exec->globalData().propertyNames->emptyIdentifier;
+ return m_exec->vm().propertyNames->emptyIdentifier;
if (characters[0] >= MaximumCachableCharacter)
- return Identifier(&m_exec->globalData(), characters, length);
+ return Identifier(&m_exec->vm(), characters, length);
if (length == 1) {
if (!m_shortIdentifiers[characters[0]].isNull())
return m_shortIdentifiers[characters[0]];
- m_shortIdentifiers[characters[0]] = Identifier(&m_exec->globalData(), characters, length);
+ m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
return m_shortIdentifiers[characters[0]];
}
if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length))
return m_recentIdentifiers[characters[0]];
- m_recentIdentifiers[characters[0]] = Identifier(&m_exec->globalData(), characters, length);
+ m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length);
return m_recentIdentifiers[characters[0]];
}
@@ -542,8 +546,8 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
ParserState state = initialState;
MarkedArgumentBuffer objectStack;
JSValue lastValue;
- Vector<ParserState, 16> stateStack;
- Vector<Identifier, 16> identifierStack;
+ Vector<ParserState, 16, UnsafeVectorOverflow> stateStack;
+ Vector<Identifier, 16, UnsafeVectorOverflow> identifierStack;
while (1) {
switch(state) {
startParseArray:
@@ -649,7 +653,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
if (i != PropertyName::NotAnIndex)
object->putDirectIndex(m_exec, i, lastValue);
else
- object->putDirect(m_exec->globalData(), ident, lastValue);
+ object->putDirect(m_exec->vm(), ident, lastValue);
identifierStack.removeLast();
if (m_lexer.currentToken().type == TokComma)
goto doParseObjectStartExpression;
@@ -814,7 +818,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState)
return JSValue();
}
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
if (stateStack.isEmpty())
return lastValue;
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.h b/Source/JavaScriptCore/runtime/LiteralParser.h
index c0f308ee5..fac97571c 100644
--- a/Source/JavaScriptCore/runtime/LiteralParser.h
+++ b/Source/JavaScriptCore/runtime/LiteralParser.h
@@ -27,8 +27,8 @@
#define LiteralParser_h
#include "Identifier.h"
+#include "JSCJSValue.h"
#include "JSGlobalObjectFunctions.h"
-#include "JSValue.h"
#include <wtf/text/WTFString.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/Lookup.cpp b/Source/JavaScriptCore/runtime/Lookup.cpp
index a6a349974..030aef5a5 100644
--- a/Source/JavaScriptCore/runtime/Lookup.cpp
+++ b/Source/JavaScriptCore/runtime/Lookup.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -22,10 +22,11 @@
#include "Executable.h"
#include "JSFunction.h"
+#include "Operations.h"
namespace JSC {
-void HashTable::createTable(JSGlobalData* globalData) const
+void HashTable::createTable(VM* vm) const
{
ASSERT(!table);
int linkIndex = compactHashSizeMask + 1;
@@ -33,7 +34,7 @@ void HashTable::createTable(JSGlobalData* globalData) const
for (int i = 0; i < compactSize; ++i)
entries[i].setKey(0);
for (int i = 0; values[i].key; ++i) {
- StringImpl* identifier = Identifier::add(globalData, values[i].key).leakRef();
+ StringImpl* identifier = Identifier::add(vm, values[i].key).leakRef();
int hashIndex = identifier->existingHash() & compactHashSizeMask;
HashEntry* entry = &entries[hashIndex];
@@ -68,23 +69,22 @@ bool setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
{
ASSERT(thisObj->globalObject());
ASSERT(entry->attributes() & Function);
- WriteBarrierBase<Unknown>* location = thisObj->getDirectLocation(exec->globalData(), propertyName);
+ PropertyOffset offset = thisObj->getDirectOffset(exec->vm(), propertyName);
- if (!location) {
+ if (!isValidOffset(offset)) {
// If a property is ever deleted from an object with a static table, then we reify
// all static functions at that time - after this we shouldn't be re-adding anything.
if (thisObj->staticFunctionsReified())
return false;
- StringImpl* name = propertyName.publicName();
- ASSERT(name);
-
- JSFunction* function = JSFunction::create(exec, thisObj->globalObject(), entry->functionLength(), name, entry->function(), entry->intrinsic());
- thisObj->putDirect(exec->globalData(), propertyName, function, entry->attributes());
- location = thisObj->getDirectLocation(exec->globalData(), propertyName);
+ thisObj->putDirectNativeFunction(
+ exec, thisObj->globalObject(), propertyName, entry->functionLength(),
+ entry->function(), entry->intrinsic(), entry->attributes());
+ offset = thisObj->getDirectOffset(exec->vm(), propertyName);
+ ASSERT(isValidOffset(offset));
}
- slot.setValue(thisObj, location->get(), thisObj->offsetForLocation(location));
+ slot.setValue(thisObj, thisObj->getDirect(offset), offset);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/Lookup.h b/Source/JavaScriptCore/runtime/Lookup.h
index ccb08128d..c90ceae7c 100644
--- a/Source/JavaScriptCore/runtime/Lookup.h
+++ b/Source/JavaScriptCore/runtime/Lookup.h
@@ -53,7 +53,7 @@ namespace JSC {
m_attributes = attributes;
m_u.store.value1 = v1;
m_u.store.value2 = v2;
- m_u.function.intrinsic = intrinsic;
+ m_intrinsic = intrinsic;
m_next = 0;
}
@@ -65,7 +65,7 @@ namespace JSC {
Intrinsic intrinsic() const
{
ASSERT(m_attributes & Function);
- return m_u.function.intrinsic;
+ return m_intrinsic;
}
NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
@@ -82,6 +82,7 @@ namespace JSC {
private:
StringImpl* m_key;
unsigned char m_attributes; // JSObject attributes
+ Intrinsic m_intrinsic;
union {
struct {
@@ -91,7 +92,6 @@ namespace JSC {
struct {
NativeFunction functionValue;
intptr_t length; // number of arguments for function
- Intrinsic intrinsic;
} function;
struct {
GetFunction get;
@@ -121,24 +121,24 @@ namespace JSC {
return result;
}
- ALWAYS_INLINE void initializeIfNeeded(JSGlobalData* globalData) const
+ ALWAYS_INLINE void initializeIfNeeded(VM* vm) const
{
if (!table)
- createTable(globalData);
+ createTable(vm);
}
ALWAYS_INLINE void initializeIfNeeded(ExecState* exec) const
{
if (!table)
- createTable(&exec->globalData());
+ createTable(&exec->vm());
}
JS_EXPORT_PRIVATE void deleteTable() const;
// Find an entry in the table, and return the entry.
- ALWAYS_INLINE const HashEntry* entry(JSGlobalData* globalData, PropertyName identifier) const
+ ALWAYS_INLINE const HashEntry* entry(VM* vm, PropertyName identifier) const
{
- initializeIfNeeded(globalData);
+ initializeIfNeeded(vm);
return entry(identifier);
}
@@ -194,14 +194,14 @@ namespace JSC {
int m_position;
};
- ConstIterator begin(JSGlobalData& globalData) const
+ ConstIterator begin(VM& vm) const
{
- initializeIfNeeded(&globalData);
+ initializeIfNeeded(&vm);
return ConstIterator(this, 0);
}
- ConstIterator end(JSGlobalData& globalData) const
+ ConstIterator end(VM& vm) const
{
- initializeIfNeeded(&globalData);
+ initializeIfNeeded(&vm);
return ConstIterator(this, compactSize);
}
@@ -229,7 +229,7 @@ namespace JSC {
}
// Convert the hash table keys to identifiers.
- JS_EXPORT_PRIVATE void createTable(JSGlobalData*) const;
+ JS_EXPORT_PRIVATE void createTable(VM*) const;
};
JS_EXPORT_PRIVATE bool setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, PropertyName, PropertySlot&);
@@ -353,6 +353,18 @@ namespace JSC {
return true;
}
+ template <class ThisImp>
+ inline void putEntry(ExecState* exec, const HashEntry* entry, PropertyName propertyName, JSValue value, ThisImp* thisObj, bool shouldThrow = false)
+ {
+ // If this is a function put it as an override property.
+ if (entry->attributes() & Function)
+ thisObj->putDirect(exec->vm(), propertyName, value);
+ else if (!(entry->attributes() & ReadOnly))
+ entry->propertyPutter()(exec, thisObj, value);
+ else if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ }
+
/**
* This one is for "put".
* It looks up a hash entry for the property to be set. If an entry
@@ -366,14 +378,7 @@ namespace JSC {
if (!entry)
return false;
- // If this is a function put it as an override property.
- if (entry->attributes() & Function)
- thisObj->putDirect(exec->globalData(), propertyName, value);
- else if (!(entry->attributes() & ReadOnly))
- entry->propertyPutter()(exec, thisObj, value);
- else if (shouldThrow)
- throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
-
+ putEntry<ThisImp>(exec, entry, propertyName, value, thisObj, shouldThrow);
return true;
}
diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp
index 7634487ad..71c53a3e4 100644
--- a/Source/JavaScriptCore/runtime/MathObject.cpp
+++ b/Source/JavaScriptCore/runtime/MathObject.cpp
@@ -52,6 +52,7 @@ static EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*);
+static EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState*);
}
@@ -81,27 +82,28 @@ const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, ExecState::math
sin mathProtoFuncSin DontEnum|Function 1
sqrt mathProtoFuncSqrt DontEnum|Function 1
tan mathProtoFuncTan DontEnum|Function 1
+ imul mathProtoFuncIMul DontEnum|Function 2
@end
*/
MathObject::MathObject(JSGlobalObject* globalObject, Structure* structure)
- : JSNonFinalObject(globalObject->globalData(), structure)
+ : JSNonFinalObject(globalObject->vm(), structure)
{
}
void MathObject::finishCreation(ExecState* exec, JSGlobalObject* globalObject)
{
- Base::finishCreation(globalObject->globalData());
+ Base::finishCreation(globalObject->vm());
ASSERT(inherits(&s_info));
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "LOG10E"), jsNumber(0.4342944819032518), DontDelete | DontEnum | ReadOnly); // See ECMA-262 15.8.1.5
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), Identifier(exec, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "LOG10E"), jsNumber(0.4342944819032518), DontDelete | DontEnum | ReadOnly); // See ECMA-262 15.8.1.5
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), Identifier(exec, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
}
bool MathObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
@@ -174,11 +176,11 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec)
double result = -std::numeric_limits<double>::infinity();
for (unsigned k = 0; k < argsCount; ++k) {
double val = exec->argument(k).toNumber(exec);
- if (isnan(val)) {
+ if (std::isnan(val)) {
result = QNaN;
break;
}
- if (val > result || (val == 0 && result == 0 && !signbit(val)))
+ if (val > result || (!val && !result && !std::signbit(val)))
result = val;
}
return JSValue::encode(jsNumber(result));
@@ -190,11 +192,11 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncMin(ExecState* exec)
double result = +std::numeric_limits<double>::infinity();
for (unsigned k = 0; k < argsCount; ++k) {
double val = exec->argument(k).toNumber(exec);
- if (isnan(val)) {
+ if (std::isnan(val)) {
result = QNaN;
break;
}
- if (val < result || (val == 0 && result == 0 && signbit(val)))
+ if (val < result || (!val && !result && std::signbit(val)))
result = val;
}
return JSValue::encode(jsNumber(result));
@@ -244,9 +246,9 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec)
double arg = exec->argument(0).toNumber(exec);
double arg2 = exec->argument(1).toNumber(exec);
- if (isnan(arg2))
+ if (std::isnan(arg2))
return JSValue::encode(jsNaN());
- if (isinf(arg2) && fabs(arg) == 1)
+ if (std::isinf(arg2) && fabs(arg) == 1)
return JSValue::encode(jsNaN());
return JSValue::encode(jsNumber(mathPow(arg, arg2)));
}
@@ -265,7 +267,7 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec)
EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec)
{
- return JSValue::encode(exec->globalData().cachedSin(exec->argument(0).toNumber(exec)));
+ return JSValue::encode(exec->vm().cachedSin(exec->argument(0).toNumber(exec)));
}
EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec)
@@ -278,6 +280,15 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec)
return JSValue::encode(jsDoubleNumber(tan(exec->argument(0).toNumber(exec))));
}
+EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState* exec)
+{
+ int32_t left = exec->argument(0).toInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
+ int32_t right = exec->argument(1).toInt32(exec);
+ return JSValue::encode(jsNumber(left * right));
+}
+
#if PLATFORM(IOS) && CPU(ARM_THUMB2)
// The following code is taken from netlib.org:
diff --git a/Source/JavaScriptCore/runtime/MathObject.h b/Source/JavaScriptCore/runtime/MathObject.h
index f4082f087..190614b84 100644
--- a/Source/JavaScriptCore/runtime/MathObject.h
+++ b/Source/JavaScriptCore/runtime/MathObject.h
@@ -43,9 +43,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
index 0f8efc604..5459ff3db 100644
--- a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
+++ b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp
@@ -27,7 +27,7 @@
#include "MemoryStatistics.h"
#include "ExecutableAllocator.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "JSStack.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.h b/Source/JavaScriptCore/runtime/MemoryStatistics.h
index 9a86df296..79cec9c21 100644
--- a/Source/JavaScriptCore/runtime/MemoryStatistics.h
+++ b/Source/JavaScriptCore/runtime/MemoryStatistics.h
@@ -28,7 +28,7 @@
#include "Heap.h"
-class JSGlobalData;
+class VM;
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/NameConstructor.cpp b/Source/JavaScriptCore/runtime/NameConstructor.cpp
index b5facc7cf..e6f85693a 100644
--- a/Source/JavaScriptCore/runtime/NameConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NameConstructor.cpp
@@ -28,6 +28,7 @@
#include "JSGlobalObject.h"
#include "NamePrototype.h"
+#include "Operations.h"
namespace JSC {
@@ -42,15 +43,15 @@ NameConstructor::NameConstructor(JSGlobalObject* globalObject, Structure* struct
void NameConstructor::finishCreation(ExecState* exec, NamePrototype* prototype)
{
- Base::finishCreation(exec->globalData(), prototype->classInfo()->className);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, prototype, DontEnum | DontDelete | ReadOnly);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
+ Base::finishCreation(exec->vm(), prototype->classInfo()->className);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, prototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum);
}
static EncodedJSValue JSC_HOST_CALL constructPrivateName(ExecState* exec)
{
JSValue publicName = exec->argumentCount() ? exec->argument(0) : jsUndefined();
- return JSValue::encode(NameInstance::create(exec->globalData(), exec->lexicalGlobalObject()->privateNameStructure(), publicName.toString(exec)));
+ return JSValue::encode(NameInstance::create(exec->vm(), exec->lexicalGlobalObject()->privateNameStructure(), publicName.toString(exec)));
}
ConstructType NameConstructor::getConstructData(JSCell*, ConstructData& constructData)
diff --git a/Source/JavaScriptCore/runtime/NameConstructor.h b/Source/JavaScriptCore/runtime/NameConstructor.h
index 16c5eef68..b7a52e402 100644
--- a/Source/JavaScriptCore/runtime/NameConstructor.h
+++ b/Source/JavaScriptCore/runtime/NameConstructor.h
@@ -46,9 +46,9 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/NameInstance.cpp b/Source/JavaScriptCore/runtime/NameInstance.cpp
index f257243e8..dbbf0e2f6 100644
--- a/Source/JavaScriptCore/runtime/NameInstance.cpp
+++ b/Source/JavaScriptCore/runtime/NameInstance.cpp
@@ -27,15 +27,16 @@
#include "NameInstance.h"
#include "JSScope.h"
+#include "Operations.h"
namespace JSC {
const ClassInfo NameInstance::s_info = { "Name", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameInstance) };
-NameInstance::NameInstance(JSGlobalData& globalData, Structure* structure, JSString* nameString)
- : Base(globalData, structure)
+NameInstance::NameInstance(VM& vm, Structure* structure, JSString* nameString)
+ : Base(vm, structure)
{
- m_nameString.set(globalData, this, nameString);
+ m_nameString.set(vm, this, nameString);
}
void NameInstance::destroy(JSCell* cell)
diff --git a/Source/JavaScriptCore/runtime/NameInstance.h b/Source/JavaScriptCore/runtime/NameInstance.h
index 129e7c407..e5aa79d97 100644
--- a/Source/JavaScriptCore/runtime/NameInstance.h
+++ b/Source/JavaScriptCore/runtime/NameInstance.h
@@ -37,15 +37,15 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), &s_info);
}
- static NameInstance* create(JSGlobalData& globalData, Structure* structure, JSString* nameString)
+ static NameInstance* create(VM& vm, Structure* structure, JSString* nameString)
{
- NameInstance* name = new (NotNull, allocateCell<NameInstance>(globalData.heap)) NameInstance(globalData, structure, nameString);
- name->finishCreation(globalData);
+ NameInstance* name = new (NotNull, allocateCell<NameInstance>(vm.heap)) NameInstance(vm, structure, nameString);
+ name->finishCreation(vm);
return name;
}
@@ -55,11 +55,11 @@ public:
protected:
static void destroy(JSCell*);
- NameInstance(JSGlobalData&, Structure*, JSString*);
+ NameInstance(VM&, Structure*, JSString*);
- void finishCreation(JSGlobalData& globalData)
+ void finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/NamePrototype.cpp b/Source/JavaScriptCore/runtime/NamePrototype.cpp
index f14e58522..a3b55fe74 100644
--- a/Source/JavaScriptCore/runtime/NamePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NamePrototype.cpp
@@ -27,6 +27,7 @@
#include "NamePrototype.h"
#include "Error.h"
+#include "Operations.h"
namespace JSC {
@@ -47,13 +48,13 @@ const ClassInfo NamePrototype::s_info = { "Name", &Base::s_info, 0, ExecState::p
*/
NamePrototype::NamePrototype(ExecState* exec, Structure* structure)
- : Base(exec->globalData(), structure, jsEmptyString(exec))
+ : Base(exec->vm(), structure, jsEmptyString(exec))
{
}
void NamePrototype::finishCreation(ExecState* exec)
{
- Base::finishCreation(exec->globalData());
+ Base::finishCreation(exec->vm());
ASSERT(inherits(&s_info));
}
diff --git a/Source/JavaScriptCore/runtime/NamePrototype.h b/Source/JavaScriptCore/runtime/NamePrototype.h
index 5d86decfd..a3abf330b 100644
--- a/Source/JavaScriptCore/runtime/NamePrototype.h
+++ b/Source/JavaScriptCore/runtime/NamePrototype.h
@@ -43,9 +43,9 @@ public:
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(NameInstanceType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 1f1730805..929cc8cb2 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -25,6 +25,7 @@
#include "JSFunction.h"
#include "JSString.h"
#include "NativeErrorPrototype.h"
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
index 8db237028..0a6ef6ec1 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
+++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -43,9 +43,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
Structure* errorStructure() { return m_errorStructure.get(); }
@@ -53,14 +53,14 @@ namespace JSC {
protected:
void finishCreation(ExecState* exec, JSGlobalObject* globalObject, Structure* prototypeStructure, const String& name)
{
- Base::finishCreation(exec->globalData(), name);
+ Base::finishCreation(exec->vm(), name);
ASSERT(inherits(&s_info));
NativeErrorPrototype* prototype = NativeErrorPrototype::create(exec, globalObject, prototypeStructure, name, this);
- putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
- putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
- m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), globalObject, prototype));
+ putDirect(exec->vm(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
+ putDirect(exec->vm(), exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
+ m_errorStructure.set(exec->vm(), this, ErrorInstance::createStructure(exec->vm(), globalObject, prototype));
ASSERT(m_errorStructure);
ASSERT(m_errorStructure->isObject());
}
diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
index 296a86a22..c33ac3d92 100644
--- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -24,6 +24,7 @@
#include "JSGlobalObject.h"
#include "JSString.h"
#include "NativeErrorConstructor.h"
+#include "Operations.h"
namespace JSC {
@@ -35,9 +36,9 @@ NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, Structure* structure
void NativeErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject* globalObject, const WTF::String& nameAndMessage, NativeErrorConstructor* constructor)
{
Base::finishCreation(exec, globalObject);
- putDirect(exec->globalData(), exec->propertyNames().name, jsString(exec, nameAndMessage), DontEnum);
- putDirect(exec->globalData(), exec->propertyNames().message, jsEmptyString(exec), DontEnum);
- putDirect(exec->globalData(), exec->propertyNames().constructor, constructor, DontEnum);
+ putDirect(exec->vm(), exec->propertyNames().name, jsString(exec, nameAndMessage), DontEnum);
+ putDirect(exec->vm(), exec->propertyNames().message, jsEmptyString(exec), DontEnum);
+ putDirect(exec->vm(), exec->propertyNames().constructor, constructor, DontEnum);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
index daa643da7..14e149dcf 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -25,6 +25,7 @@
#include "Lookup.h"
#include "NumberObject.h"
#include "NumberPrototype.h"
+#include "Operations.h"
namespace JSC {
@@ -61,14 +62,14 @@ NumberConstructor::NumberConstructor(JSGlobalObject* globalObject, Structure* st
void NumberConstructor::finishCreation(ExecState* exec, NumberPrototype* numberPrototype)
{
- Base::finishCreation(exec->globalData(), numberPrototype->s_info.className);
+ Base::finishCreation(exec->vm(), numberPrototype->s_info.className);
ASSERT(inherits(&s_info));
// Number.Prototype
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, numberPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, numberPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
bool NumberConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -114,9 +115,9 @@ static JSValue numberConstructorMinValue(ExecState*, JSValue, PropertyName)
// ECMA 15.7.1
static EncodedJSValue JSC_HOST_CALL constructWithNumberConstructor(ExecState* exec)
{
- NumberObject* object = NumberObject::create(exec->globalData(), asInternalFunction(exec->callee())->globalObject()->numberObjectStructure());
+ NumberObject* object = NumberObject::create(exec->vm(), asInternalFunction(exec->callee())->globalObject()->numberObjectStructure());
double n = exec->argumentCount() ? exec->argument(0).toNumber(exec) : 0;
- object->setInternalValue(exec->globalData(), jsNumber(n));
+ object->setInternalValue(exec->vm(), jsNumber(n));
return JSValue::encode(object);
}
diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.h b/Source/JavaScriptCore/runtime/NumberConstructor.h
index 75f55f88e..45883ede1 100644
--- a/Source/JavaScriptCore/runtime/NumberConstructor.h
+++ b/Source/JavaScriptCore/runtime/NumberConstructor.h
@@ -46,9 +46,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
- return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp
index b87753d4d..05349ef31 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.cpp
+++ b/Source/JavaScriptCore/runtime/NumberObject.cpp
@@ -24,6 +24,7 @@
#include "JSGlobalObject.h"
#include "NumberPrototype.h"
+#include "Operations.h"
namespace JSC {
@@ -31,21 +32,21 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberObject);
const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(NumberObject) };
-NumberObject::NumberObject(JSGlobalData& globalData, Structure* structure)
- : JSWrapperObject(globalData, structure)
+NumberObject::NumberObject(VM& vm, Structure* structure)
+ : JSWrapperObject(vm, structure)
{
}
-void NumberObject::finishCreation(JSGlobalData& globalData)
+void NumberObject::finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
}
NumberObject* constructNumber(ExecState* exec, JSGlobalObject* globalObject, JSValue number)
{
- NumberObject* object = NumberObject::create(exec->globalData(), globalObject->numberObjectStructure());
- object->setInternalValue(exec->globalData(), number);
+ NumberObject* object = NumberObject::create(exec->vm(), globalObject->numberObjectStructure());
+ object->setInternalValue(exec->vm(), number);
return object;
}
diff --git a/Source/JavaScriptCore/runtime/NumberObject.h b/Source/JavaScriptCore/runtime/NumberObject.h
index ed84207d9..1c7c8982b 100644
--- a/Source/JavaScriptCore/runtime/NumberObject.h
+++ b/Source/JavaScriptCore/runtime/NumberObject.h
@@ -27,24 +27,24 @@ namespace JSC {
class NumberObject : public JSWrapperObject {
protected:
- NumberObject(JSGlobalData&, Structure*);
- void finishCreation(JSGlobalData&);
+ NumberObject(VM&, Structure*);
+ void finishCreation(VM&);
public:
typedef JSWrapperObject Base;
- static NumberObject* create(JSGlobalData& globalData, Structure* structure)
+ static NumberObject* create(VM& vm, Structure* structure)
{
- NumberObject* number = new (NotNull, allocateCell<NumberObject>(globalData.heap)) NumberObject(globalData, structure);
- number->finishCreation(globalData);
+ NumberObject* number = new (NotNull, allocateCell<NumberObject>(vm.heap)) NumberObject(vm, structure);
+ number->finishCreation(vm);
return number;
}
static JS_EXPORTDATA const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), &s_info);
}
};
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
index 23c9dbfdd..54a947303 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -71,14 +71,14 @@ const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0,
ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberPrototype);
NumberPrototype::NumberPrototype(ExecState* exec, Structure* structure)
- : NumberObject(exec->globalData(), structure)
+ : NumberObject(exec->vm(), structure)
{
}
void NumberPrototype::finishCreation(ExecState* exec, JSGlobalObject*)
{
- Base::finishCreation(exec->globalData());
- setInternalValue(exec->globalData(), jsNumber(0));
+ Base::finishCreation(exec->vm());
+ setInternalValue(exec->vm(), jsNumber(0));
ASSERT(inherits(&s_info));
}
@@ -151,7 +151,7 @@ static const char radixDigits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radix)
{
- ASSERT(isfinite(number));
+ ASSERT(std::isfinite(number));
ASSERT(radix >= 2 && radix <= 36);
// Position the decimal point at the center of the string, set
@@ -161,7 +161,7 @@ static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radi
// Extract the sign.
bool isNegative = number < 0;
- if (signbit(number))
+ if (std::signbit(number))
number = -number;
double integerPart = floor(number);
@@ -198,12 +198,12 @@ static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radi
// Calculate the delta from the current number to the next & previous possible IEEE numbers.
double nextNumber = nextafter(number, std::numeric_limits<double>::infinity());
double lastNumber = nextafter(number, -std::numeric_limits<double>::infinity());
- ASSERT(isfinite(nextNumber) && !signbit(nextNumber));
- ASSERT(isfinite(lastNumber) && !signbit(lastNumber));
+ ASSERT(std::isfinite(nextNumber) && !std::signbit(nextNumber));
+ ASSERT(std::isfinite(lastNumber) && !std::signbit(lastNumber));
double deltaNextDouble = nextNumber - number;
double deltaLastDouble = number - lastNumber;
- ASSERT(isfinite(deltaNextDouble) && !signbit(deltaNextDouble));
- ASSERT(isfinite(deltaLastDouble) && !signbit(deltaLastDouble));
+ ASSERT(std::isfinite(deltaNextDouble) && !std::signbit(deltaNextDouble));
+ ASSERT(std::isfinite(deltaLastDouble) && !std::signbit(deltaLastDouble));
// We track the delta from the current value to the next, to track how many digits of the
// fraction we need to write. For example, if the value we are converting is precisely
@@ -380,7 +380,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
return throwVMError(exec, createRangeError(exec, ASCIILiteral("toExponential() argument must be between 0 and 20")));
// Handle NaN and Infinity.
- if (!isfinite(x))
+ if (!std::isfinite(x))
return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
// Round if the argument is not undefined, always format as exponential.
@@ -418,7 +418,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
// The check above will return false for NaN or Infinity, these will be
// handled by numberToString.
- ASSERT(isfinite(x));
+ ASSERT(std::isfinite(x));
NumberToStringBuffer buffer;
return JSValue::encode(jsString(exec, String(numberToFixedWidthString(x, decimalPlaces, buffer))));
@@ -448,7 +448,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
// Handle NaN and Infinity.
- if (!isfinite(x))
+ if (!std::isfinite(x))
return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));
NumberToStringBuffer buffer;
@@ -475,13 +475,13 @@ static inline EncodedJSValue integerValueToString(ExecState* exec, int32_t radix
if (static_cast<unsigned>(value) < static_cast<unsigned>(radix)) {
ASSERT(value <= 36);
ASSERT(value >= 0);
- JSGlobalData* globalData = &exec->globalData();
- return JSValue::encode(globalData->smallStrings.singleCharacterString(globalData, radixDigits[value]));
+ VM* vm = &exec->vm();
+ return JSValue::encode(vm->smallStrings.singleCharacterString(vm, radixDigits[value]));
}
if (radix == 10) {
- JSGlobalData* globalData = &exec->globalData();
- return JSValue::encode(jsString(globalData, globalData->numericStrings.add(value)));
+ VM* vm = &exec->vm();
+ return JSValue::encode(jsString(vm, vm->numericStrings.add(value)));
}
return JSValue::encode(jsString(exec, toStringWithRadix(value, radix)));
@@ -503,11 +503,11 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
return integerValueToString(exec, radix, integerValue);
if (radix == 10) {
- JSGlobalData* globalData = &exec->globalData();
- return JSValue::encode(jsString(globalData, globalData->numericStrings.add(doubleValue)));
+ VM* vm = &exec->vm();
+ return JSValue::encode(jsString(vm, vm->numericStrings.add(doubleValue)));
}
- if (!isfinite(doubleValue))
+ if (!std::isfinite(doubleValue))
return JSValue::encode(jsString(exec, String::numberToStringECMAScript(doubleValue)));
RadixBuffer s;
diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.h b/Source/JavaScriptCore/runtime/NumberPrototype.h
index d7caecf3f..b51251c72 100644
--- a/Source/JavaScriptCore/runtime/NumberPrototype.h
+++ b/Source/JavaScriptCore/runtime/NumberPrototype.h
@@ -38,9 +38,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
index 7e74a914b..d72cbe84e 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -30,6 +30,7 @@
#include "JSGlobalObject.h"
#include "Lookup.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "PropertyDescriptor.h"
#include "PropertyNameArray.h"
@@ -84,11 +85,11 @@ ObjectConstructor::ObjectConstructor(JSGlobalObject* globalObject, Structure* st
void ObjectConstructor::finishCreation(ExecState* exec, ObjectPrototype* objectPrototype)
{
- Base::finishCreation(exec->globalData(), Identifier(exec, "Object").string());
+ Base::finishCreation(exec->vm(), Identifier(exec, "Object").string());
// ECMA 15.2.3.1
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
bool ObjectConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
@@ -101,19 +102,19 @@ bool ObjectConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* ex
return getStaticFunctionDescriptor<JSObject>(exec, ExecState::objectConstructorTable(exec), jsCast<ObjectConstructor*>(object), propertyName, descriptor);
}
-// ECMA 15.2.2
-static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args)
+static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
{
+ JSGlobalObject* globalObject = exec->callee()->globalObject();
+ ArgList args(exec);
JSValue arg = args.at(0);
if (arg.isUndefinedOrNull())
- return constructEmptyObject(exec, globalObject);
+ return constructEmptyObject(exec, globalObject->objectPrototype());
return arg.toObject(exec, globalObject);
}
static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* exec)
{
- ArgList args(exec);
- return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
+ return JSValue::encode(constructObject(exec));
}
ConstructType ObjectConstructor::getConstructData(JSCell*, ConstructData& constructData)
@@ -124,8 +125,7 @@ ConstructType ObjectConstructor::getConstructData(JSCell*, ConstructData& constr
static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
{
- ArgList args(exec);
- return JSValue::encode(constructObject(exec, asInternalFunction(exec->callee())->globalObject(), args));
+ return JSValue::encode(constructObject(exec));
}
CallType ObjectConstructor::getCallData(JSCell*, CallData& callData)
@@ -160,17 +160,17 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState
JSObject* description = constructEmptyObject(exec);
if (!descriptor.isAccessorDescriptor()) {
- description->putDirect(exec->globalData(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
} else {
ASSERT(descriptor.getter());
ASSERT(descriptor.setter());
- description->putDirect(exec->globalData(), exec->propertyNames().get, descriptor.getter(), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().set, descriptor.setter(), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().get, descriptor.getter(), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().set, descriptor.setter(), 0);
}
- description->putDirect(exec->globalData(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
- description->putDirect(exec->globalData(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
+ description->putDirect(exec->vm(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);
return JSValue::encode(description);
}
@@ -349,7 +349,9 @@ EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
if (!exec->argument(0).isObject() && !exec->argument(0).isNull())
return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null.")));
JSValue proto = exec->argument(0);
- JSObject* newObject = proto.isObject() ? constructEmptyObject(exec, asObject(proto)->inheritorID(exec->globalData())) : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
+ JSObject* newObject = proto.isObject()
+ ? constructEmptyObject(exec, asObject(proto))
+ : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
if (exec->argument(1).isUndefined())
return JSValue::encode(newObject);
if (!exec->argument(1).isObject())
@@ -366,7 +368,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
JSObject* object = asObject(obj);
if (isJSFinalObject(object)) {
- object->seal(exec->globalData());
+ object->seal(exec->vm());
return JSValue::encode(obj);
}
@@ -388,7 +390,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec)
}
// 3. Set the [[Extensible]] internal property of O to false.
- object->preventExtensions(exec->globalData());
+ object->preventExtensions(exec->vm());
// 4. Return O.
return JSValue::encode(obj);
@@ -403,7 +405,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
JSObject* object = asObject(obj);
if (isJSFinalObject(object) && !hasIndexedProperties(object->structure()->indexingType())) {
- object->freeze(exec->globalData());
+ object->freeze(exec->vm());
return JSValue::encode(obj);
}
@@ -429,7 +431,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec)
}
// 3. Set the [[Extensible]] internal property of O to false.
- object->preventExtensions(exec->globalData());
+ object->preventExtensions(exec->vm());
// 4. Return O.
return JSValue::encode(obj);
@@ -440,7 +442,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec)
JSValue obj = exec->argument(0);
if (!obj.isObject())
return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.preventExtensions can only be called on Objects.")));
- asObject(obj)->preventExtensions(exec->globalData());
+ asObject(obj)->preventExtensions(exec->vm());
return JSValue::encode(obj);
}
@@ -453,7 +455,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec)
JSObject* object = asObject(obj);
if (isJSFinalObject(object))
- return JSValue::encode(jsBoolean(object->isSealed(exec->globalData())));
+ return JSValue::encode(jsBoolean(object->isSealed(exec->vm())));
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
@@ -483,7 +485,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec)
JSObject* object = asObject(obj);
if (isJSFinalObject(object))
- return JSValue::encode(jsBoolean(object->isFrozen(exec->globalData())));
+ return JSValue::encode(jsBoolean(object->isFrozen(exec->vm())));
// 2. For each named own property name P of O,
PropertyNameArray properties(exec);
diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.h b/Source/JavaScriptCore/runtime/ObjectConstructor.h
index c89134599..72c895fba 100644
--- a/Source/JavaScriptCore/runtime/ObjectConstructor.h
+++ b/Source/JavaScriptCore/runtime/ObjectConstructor.h
@@ -22,6 +22,8 @@
#define ObjectConstructor_h
#include "InternalFunction.h"
+#include "JSGlobalObject.h"
+#include "ObjectPrototype.h"
namespace JSC {
@@ -43,9 +45,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
@@ -58,6 +60,30 @@ namespace JSC {
static CallType getCallData(JSCell*, CallData&);
};
+ inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
+ {
+ return JSFinalObject::create(exec, structure);
+ }
+
+ inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype, unsigned inlineCapacity)
+ {
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
+ Structure* structure = prototypeMap.emptyObjectStructureForPrototype(
+ prototype, inlineCapacity);
+ return constructEmptyObject(exec, structure);
+ }
+
+ inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype)
+ {
+ return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity());
+ }
+
+ inline JSObject* constructEmptyObject(ExecState* exec)
+ {
+ return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype());
+ }
+
} // namespace JSC
#endif // ObjectConstructor_h
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
index e94edfadf..eaed425df 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -25,6 +25,8 @@
#include "JSFunction.h"
#include "JSString.h"
#include "JSStringBuilder.h"
+#include "Operations.h"
+#include "StructureRareDataInlines.h"
namespace JSC {
@@ -38,51 +40,40 @@ static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*);
static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*);
-}
-
-#include "ObjectPrototype.lut.h"
-
-namespace JSC {
-
ASSERT_HAS_TRIVIAL_DESTRUCTOR(ObjectPrototype);
-const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, 0, ExecState::objectPrototypeTable, CREATE_METHOD_TABLE(ObjectPrototype) };
-
-/* Source for ObjectPrototype.lut.h
-@begin objectPrototypeTable
- toString objectProtoFuncToString DontEnum|Function 0
- toLocaleString objectProtoFuncToLocaleString DontEnum|Function 0
- valueOf objectProtoFuncValueOf DontEnum|Function 0
- hasOwnProperty objectProtoFuncHasOwnProperty DontEnum|Function 1
- propertyIsEnumerable objectProtoFuncPropertyIsEnumerable DontEnum|Function 1
- isPrototypeOf objectProtoFuncIsPrototypeOf DontEnum|Function 1
- __defineGetter__ objectProtoFuncDefineGetter DontEnum|Function 2
- __defineSetter__ objectProtoFuncDefineSetter DontEnum|Function 2
- __lookupGetter__ objectProtoFuncLookupGetter DontEnum|Function 1
- __lookupSetter__ objectProtoFuncLookupSetter DontEnum|Function 1
-@end
-*/
+const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ObjectPrototype) };
ObjectPrototype::ObjectPrototype(ExecState* exec, Structure* stucture)
- : JSNonFinalObject(exec->globalData(), stucture)
+ : JSNonFinalObject(exec->vm(), stucture)
{
}
-void ObjectPrototype::finishCreation(JSGlobalData& globalData, JSGlobalObject*)
+void ObjectPrototype::finishCreation(ExecState* exec, JSGlobalObject* globalObject)
{
- Base::finishCreation(globalData);
+ VM& vm = exec->vm();
+
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
- notifyUsedAsPrototype(globalData);
-}
-
-bool ObjectPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
-{
- return getStaticFunctionSlot<JSNonFinalObject>(exec, ExecState::objectPrototypeTable(exec), jsCast<ObjectPrototype*>(cell), propertyName, slot);
+ vm.prototypeMap.addPrototype(this);
+
+ JSC_NATIVE_FUNCTION(vm.propertyNames->toString, objectProtoFuncToString, DontEnum, 0);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->toLocaleString, objectProtoFuncToLocaleString, DontEnum, 0);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->valueOf, objectProtoFuncValueOf, DontEnum, 0);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->hasOwnProperty, objectProtoFuncHasOwnProperty, DontEnum, 1);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable, DontEnum, 1);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->isPrototypeOf, objectProtoFuncIsPrototypeOf, DontEnum, 1);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->__defineGetter__, objectProtoFuncDefineGetter, DontEnum, 2);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->__defineSetter__, objectProtoFuncDefineSetter, DontEnum, 2);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->__lookupGetter__, objectProtoFuncLookupGetter, DontEnum, 1);
+ JSC_NATIVE_FUNCTION(vm.propertyNames->__lookupSetter__, objectProtoFuncLookupSetter, DontEnum, 1);
}
-bool ObjectPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
+ObjectPrototype* ObjectPrototype::create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
{
- return getStaticFunctionDescriptor<JSNonFinalObject>(exec, ExecState::objectPrototypeTable(exec), jsCast<ObjectPrototype*>(object), propertyName, descriptor);
+ ObjectPrototype* prototype = new (NotNull, allocateCell<ObjectPrototype>(*exec->heap())) ObjectPrototype(exec, structure);
+ prototype->finishCreation(exec, globalObject);
+ return prototype;
}
// ------------------------------ Functions --------------------------------
@@ -227,7 +218,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec)
return JSValue::encode(throwOutOfMemoryError(exec));
result = jsNontrivialString(exec, newString.release());
- thisObject->structure()->setObjectToStringValue(exec->globalData(), thisObject, result);
+ thisObject->structure()->setObjectToStringValue(exec->vm(), thisObject, result);
}
return JSValue::encode(result);
}
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.h b/Source/JavaScriptCore/runtime/ObjectPrototype.h
index e3551d6fd..cf0143e29 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.h
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.h
@@ -29,29 +29,20 @@ namespace JSC {
public:
typedef JSNonFinalObject Base;
- static ObjectPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
- {
- ObjectPrototype* prototype = new (NotNull, allocateCell<ObjectPrototype>(*exec->heap())) ObjectPrototype(exec, structure);
- prototype->finishCreation(exec->globalData(), globalObject);
- return prototype;
- }
+ static ObjectPrototype* create(ExecState*, JSGlobalObject*, Structure*);
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSNonFinalObject::StructureFlags;
-
- void finishCreation(JSGlobalData&, JSGlobalObject*);
+ void finishCreation(ExecState*, JSGlobalObject*);
private:
ObjectPrototype(ExecState*, Structure*);
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
};
JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
diff --git a/Source/JavaScriptCore/runtime/Operations.cpp b/Source/JavaScriptCore/runtime/Operations.cpp
index d96bae575..d6cc0ff57 100644
--- a/Source/JavaScriptCore/runtime/Operations.cpp
+++ b/Source/JavaScriptCore/runtime/Operations.cpp
@@ -56,28 +56,32 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
return jsNumber(p1.toNumber(callFrame) + p2.toNumber(callFrame));
}
-JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
+JSValue jsTypeStringForValue(VM& vm, JSGlobalObject* globalObject, JSValue v)
{
- JSGlobalData& globalData = callFrame->globalData();
if (v.isUndefined())
- return globalData.smallStrings.undefinedString(&globalData);
+ return vm.smallStrings.undefinedString();
if (v.isBoolean())
- return globalData.smallStrings.booleanString(&globalData);
+ return vm.smallStrings.booleanString();
if (v.isNumber())
- return globalData.smallStrings.numberString(&globalData);
+ return vm.smallStrings.numberString();
if (v.isString())
- return globalData.smallStrings.stringString(&globalData);
+ return vm.smallStrings.stringString();
if (v.isObject()) {
// Return "undefined" for objects that should be treated
// as null when doing comparisons.
- if (asObject(v)->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))
- return globalData.smallStrings.undefinedString(&globalData);
+ if (asObject(v)->structure()->masqueradesAsUndefined(globalObject))
+ return vm.smallStrings.undefinedString();
CallData callData;
JSObject* object = asObject(v);
if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
- return globalData.smallStrings.functionString(&globalData);
+ return vm.smallStrings.functionString();
}
- return globalData.smallStrings.objectString(&globalData);
+ return vm.smallStrings.objectString();
+}
+
+JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
+{
+ return jsTypeStringForValue(callFrame->vm(), callFrame->lexicalGlobalObject(), v);
}
bool jsIsObjectType(CallFrame* callFrame, JSValue v)
@@ -86,7 +90,7 @@ bool jsIsObjectType(CallFrame* callFrame, JSValue v)
return v.isNull();
JSType type = v.asCell()->structure()->typeInfo().type();
- if (type == NumberType || type == StringType)
+ if (type == StringType)
return false;
if (type >= ObjectType) {
if (asObject(v)->structure()->masqueradesAsUndefined(callFrame->lexicalGlobalObject()))
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index 8e0a0a393..afac13000 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -24,359 +24,263 @@
#include "ExceptionHelpers.h"
#include "Interpreter.h"
+#include "JSCJSValueInlines.h"
+#include "JSFunctionInlines.h"
#include "JSProxy.h"
#include "JSString.h"
-#include "JSValueInlines.h"
+#include "StructureInlines.h"
namespace JSC {
- NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
- JSValue jsTypeStringForValue(CallFrame*, JSValue);
- bool jsIsObjectType(CallFrame*, JSValue);
- bool jsIsFunctionType(JSValue);
-
- ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
- {
- JSGlobalData& globalData = exec->globalData();
-
- unsigned length1 = s1->length();
- if (!length1)
- return s2;
- unsigned length2 = s2->length();
- if (!length2)
- return s1;
- if ((length1 + length2) < length1)
+NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
+JSValue jsTypeStringForValue(CallFrame*, JSValue);
+JSValue jsTypeStringForValue(VM&, JSGlobalObject*, JSValue);
+bool jsIsObjectType(CallFrame*, JSValue);
+bool jsIsFunctionType(JSValue);
+
+ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
+{
+ VM& vm = exec->vm();
+
+ unsigned length1 = s1->length();
+ if (!length1)
+ return s2;
+ unsigned length2 = s2->length();
+ if (!length2)
+ return s1;
+ if ((length1 + length2) < length1)
+ return throwOutOfMemoryError(exec);
+
+ return JSRopeString::create(vm, s1, s2);
+}
+
+ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String& u2, const String& u3)
+{
+ VM* vm = &exec->vm();
+
+ unsigned length1 = u1.length();
+ unsigned length2 = u2.length();
+ unsigned length3 = u3.length();
+ if (!length1)
+ return jsString(exec, jsString(vm, u2), jsString(vm, u3));
+ if (!length2)
+ return jsString(exec, jsString(vm, u1), jsString(vm, u3));
+ if (!length3)
+ return jsString(exec, jsString(vm, u1), jsString(vm, u2));
+
+ if ((length1 + length2) < length1)
+ return throwOutOfMemoryError(exec);
+ if ((length1 + length2 + length3) < length3)
+ return throwOutOfMemoryError(exec);
+
+ return JSRopeString::create(exec->vm(), jsString(vm, u1), jsString(vm, u2), jsString(vm, u3));
+}
+
+ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
+{
+ VM* vm = &exec->vm();
+ JSRopeString::RopeBuilder ropeBuilder(*vm);
+
+ unsigned oldLength = 0;
+
+ for (unsigned i = 0; i < count; ++i) {
+ JSValue v = strings[i].jsValue();
+ ropeBuilder.append(v.toString(exec));
+
+ if (ropeBuilder.length() < oldLength) // True for overflow
return throwOutOfMemoryError(exec);
-
- return JSRopeString::create(globalData, s1, s2);
- }
-
- ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String& u2, const String& u3)
- {
- JSGlobalData* globalData = &exec->globalData();
-
- unsigned length1 = u1.length();
- unsigned length2 = u2.length();
- unsigned length3 = u3.length();
- if (!length1)
- return jsString(exec, jsString(globalData, u2), jsString(globalData, u3));
- if (!length2)
- return jsString(exec, jsString(globalData, u1), jsString(globalData, u3));
- if (!length3)
- return jsString(exec, jsString(globalData, u1), jsString(globalData, u2));
-
- if ((length1 + length2) < length1)
- return throwOutOfMemoryError(exec);
- if ((length1 + length2 + length3) < length3)
- return throwOutOfMemoryError(exec);
-
- return JSRopeString::create(exec->globalData(), jsString(globalData, u1), jsString(globalData, u2), jsString(globalData, u3));
+ oldLength = ropeBuilder.length();
}
- ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
- {
- JSGlobalData* globalData = &exec->globalData();
- JSRopeString::RopeBuilder ropeBuilder(*globalData);
+ return ropeBuilder.release();
+}
- unsigned oldLength = 0;
-
- for (unsigned i = 0; i < count; ++i) {
- JSValue v = strings[i].jsValue();
- ropeBuilder.append(v.toString(exec));
-
- if (ropeBuilder.length() < oldLength) // True for overflow
- return throwOutOfMemoryError(exec);
- oldLength = ropeBuilder.length();
- }
-
- return ropeBuilder.release();
- }
+ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue)
+{
+ VM* vm = &exec->vm();
+ JSRopeString::RopeBuilder ropeBuilder(*vm);
+ ropeBuilder.append(thisValue.toString(exec));
- ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue)
- {
- JSGlobalData* globalData = &exec->globalData();
- JSRopeString::RopeBuilder ropeBuilder(*globalData);
- ropeBuilder.append(thisValue.toString(exec));
+ unsigned oldLength = 0;
- unsigned oldLength = 0;
-
- for (unsigned i = 0; i < exec->argumentCount(); ++i) {
- JSValue v = exec->argument(i);
- ropeBuilder.append(v.toString(exec));
-
- if (ropeBuilder.length() < oldLength) // True for overflow
- return throwOutOfMemoryError(exec);
- oldLength = ropeBuilder.length();
- }
-
- return ropeBuilder.release();
- }
-
- // ECMA 11.9.3
- inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
- {
- if (v1.isInt32() && v2.isInt32())
- return v1 == v2;
-
- return equalSlowCase(exec, v1, v2);
- }
-
- ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
- {
- do {
- if (v1.isNumber() && v2.isNumber())
- return v1.asNumber() == v2.asNumber();
-
- bool s1 = v1.isString();
- bool s2 = v2.isString();
- if (s1 && s2)
- return asString(v1)->value(exec) == asString(v2)->value(exec);
-
- if (v1.isUndefinedOrNull()) {
- if (v2.isUndefinedOrNull())
- return true;
- if (!v2.isCell())
- return false;
- return v2.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
- }
-
- if (v2.isUndefinedOrNull()) {
- if (!v1.isCell())
- return false;
- return v1.asCell()->structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
- }
-
- if (v1.isObject()) {
- if (v2.isObject())
- return v1 == v2;
- JSValue p1 = v1.toPrimitive(exec);
- if (exec->hadException())
- return false;
- v1 = p1;
- if (v1.isInt32() && v2.isInt32())
- return v1 == v2;
- continue;
- }
-
- if (v2.isObject()) {
- JSValue p2 = v2.toPrimitive(exec);
- if (exec->hadException())
- return false;
- v2 = p2;
- if (v1.isInt32() && v2.isInt32())
- return v1 == v2;
- continue;
- }
-
- if (s1 || s2) {
- double d1 = v1.toNumber(exec);
- double d2 = v2.toNumber(exec);
- return d1 == d2;
- }
-
- if (v1.isBoolean()) {
- if (v2.isNumber())
- return static_cast<double>(v1.asBoolean()) == v2.asNumber();
- } else if (v2.isBoolean()) {
- if (v1.isNumber())
- return v1.asNumber() == static_cast<double>(v2.asBoolean());
- }
-
- return v1 == v2;
- } while (true);
- }
+ for (unsigned i = 0; i < exec->argumentCount(); ++i) {
+ JSValue v = exec->argument(i);
+ ropeBuilder.append(v.toString(exec));
- // ECMA 11.9.3
- ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
- {
- ASSERT(v1.isCell() && v2.isCell());
-
- if (v1.asCell()->isString() && v2.asCell()->isString())
- return asString(v1)->value(exec) == asString(v2)->value(exec);
-
- return v1 == v2;
- }
-
- inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2)
- {
- if (v1.isInt32() && v2.isInt32())
- return v1 == v2;
-
- if (v1.isNumber() && v2.isNumber())
- return v1.asNumber() == v2.asNumber();
-
- if (!v1.isCell() || !v2.isCell())
- return v1 == v2;
-
- return strictEqualSlowCaseInline(exec, v1, v2);
+ if (ropeBuilder.length() < oldLength) // True for overflow
+ return throwOutOfMemoryError(exec);
+ oldLength = ropeBuilder.length();
}
- // See ES5 11.8.1/11.8.2/11.8.5 for definition of leftFirst, this value ensures correct
- // evaluation ordering for argument conversions for '<' and '>'. For '<' pass the value
- // true, for leftFirst, for '>' pass the value false (and reverse operand order).
- template<bool leftFirst>
- ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
- {
- if (v1.isInt32() && v2.isInt32())
- return v1.asInt32() < v2.asInt32();
-
- if (v1.isNumber() && v2.isNumber())
- return v1.asNumber() < v2.asNumber();
-
- if (isJSString(v1) && isJSString(v2))
- return codePointCompareLessThan(asString(v1)->value(callFrame), asString(v2)->value(callFrame));
-
- double n1;
- double n2;
- JSValue p1;
- JSValue p2;
- bool wasNotString1;
- bool wasNotString2;
- if (leftFirst) {
- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
- } else {
- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
- }
-
- if (wasNotString1 | wasNotString2)
- return n1 < n2;
- return codePointCompareLessThan(asString(p1)->value(callFrame), asString(p2)->value(callFrame));
+ return ropeBuilder.release();
+}
+
+// See ES5 11.8.1/11.8.2/11.8.5 for definition of leftFirst, this value ensures correct
+// evaluation ordering for argument conversions for '<' and '>'. For '<' pass the value
+// true, for leftFirst, for '>' pass the value false (and reverse operand order).
+template<bool leftFirst>
+ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
+{
+ if (v1.isInt32() && v2.isInt32())
+ return v1.asInt32() < v2.asInt32();
+
+ if (v1.isNumber() && v2.isNumber())
+ return v1.asNumber() < v2.asNumber();
+
+ if (isJSString(v1) && isJSString(v2))
+ return codePointCompareLessThan(asString(v1)->value(callFrame), asString(v2)->value(callFrame));
+
+ double n1;
+ double n2;
+ JSValue p1;
+ JSValue p2;
+ bool wasNotString1;
+ bool wasNotString2;
+ if (leftFirst) {
+ wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+ } else {
+ wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+ wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
}
- // See ES5 11.8.3/11.8.4/11.8.5 for definition of leftFirst, this value ensures correct
- // evaluation ordering for argument conversions for '<=' and '=>'. For '<=' pass the
- // value true, for leftFirst, for '=>' pass the value false (and reverse operand order).
- template<bool leftFirst>
- ALWAYS_INLINE bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
- {
- if (v1.isInt32() && v2.isInt32())
- return v1.asInt32() <= v2.asInt32();
-
- if (v1.isNumber() && v2.isNumber())
- return v1.asNumber() <= v2.asNumber();
-
- if (isJSString(v1) && isJSString(v2))
- return !codePointCompareLessThan(asString(v2)->value(callFrame), asString(v1)->value(callFrame));
-
- double n1;
- double n2;
- JSValue p1;
- JSValue p2;
- bool wasNotString1;
- bool wasNotString2;
- if (leftFirst) {
- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
- } else {
- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
- }
-
- if (wasNotString1 | wasNotString2)
- return n1 <= n2;
- return !codePointCompareLessThan(asString(p2)->value(callFrame), asString(p1)->value(callFrame));
+ if (wasNotString1 | wasNotString2)
+ return n1 < n2;
+ return codePointCompareLessThan(asString(p1)->value(callFrame), asString(p2)->value(callFrame));
+}
+
+// See ES5 11.8.3/11.8.4/11.8.5 for definition of leftFirst, this value ensures correct
+// evaluation ordering for argument conversions for '<=' and '=>'. For '<=' pass the
+// value true, for leftFirst, for '=>' pass the value false (and reverse operand order).
+template<bool leftFirst>
+ALWAYS_INLINE bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
+{
+ if (v1.isInt32() && v2.isInt32())
+ return v1.asInt32() <= v2.asInt32();
+
+ if (v1.isNumber() && v2.isNumber())
+ return v1.asNumber() <= v2.asNumber();
+
+ if (isJSString(v1) && isJSString(v2))
+ return !codePointCompareLessThan(asString(v2)->value(callFrame), asString(v1)->value(callFrame));
+
+ double n1;
+ double n2;
+ JSValue p1;
+ JSValue p2;
+ bool wasNotString1;
+ bool wasNotString2;
+ if (leftFirst) {
+ wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+ } else {
+ wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+ wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
}
- // Fast-path choices here are based on frequency data from SunSpider:
- // <times> Add case: <t1> <t2>
- // ---------------------------
- // 5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
- // 247412 Add case: 5 5
- // 20900 Add case: 5 6
- // 13962 Add case: 5 3
- // 4000 Add case: 3 5
-
- ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
- {
- if (v1.isNumber() && v2.isNumber())
- return jsNumber(v1.asNumber() + v2.asNumber());
+ if (wasNotString1 | wasNotString2)
+ return n1 <= n2;
+ return !codePointCompareLessThan(asString(p2)->value(callFrame), asString(p1)->value(callFrame));
+}
+
+// Fast-path choices here are based on frequency data from SunSpider:
+// <times> Add case: <t1> <t2>
+// ---------------------------
+// 5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
+// 247412 Add case: 5 5
+// 20900 Add case: 5 6
+// 13962 Add case: 5 3
+// 4000 Add case: 3 5
+
+ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
+{
+ if (v1.isNumber() && v2.isNumber())
+ return jsNumber(v1.asNumber() + v2.asNumber());
- if (v1.isString() && !v2.isObject())
- return jsString(callFrame, asString(v1), v2.toString(callFrame));
+ if (v1.isString() && !v2.isObject())
+ return jsString(callFrame, asString(v1), v2.toString(callFrame));
- // All other cases are pretty uncommon
- return jsAddSlowCase(callFrame, v1, v2);
- }
+ // All other cases are pretty uncommon
+ return jsAddSlowCase(callFrame, v1, v2);
+}
#define InvalidPrototypeChain (std::numeric_limits<size_t>::max())
- inline size_t normalizePrototypeChainForChainAccess(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
- {
- JSCell* cell = base.asCell();
- size_t count = 0;
+inline size_t normalizePrototypeChainForChainAccess(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
+{
+ JSCell* cell = base.asCell();
+ size_t count = 0;
- while (slotBase != cell) {
- if (cell->isProxy())
- return InvalidPrototypeChain;
+ while (slotBase != cell) {
+ if (cell->isProxy())
+ return InvalidPrototypeChain;
- if (cell->structure()->typeInfo().hasImpureGetOwnPropertySlot())
- return InvalidPrototypeChain;
+ if (cell->structure()->typeInfo().hasImpureGetOwnPropertySlot())
+ return InvalidPrototypeChain;
- JSValue v = cell->structure()->prototypeForLookup(callFrame);
+ JSValue v = cell->structure()->prototypeForLookup(callFrame);
- // If we didn't find slotBase in base's prototype chain, then base
- // must be a proxy for another object.
+ // If we didn't find slotBase in base's prototype chain, then base
+ // must be a proxy for another object.
- if (v.isNull())
- return InvalidPrototypeChain;
+ if (v.isNull())
+ return InvalidPrototypeChain;
- cell = v.asCell();
+ cell = v.asCell();
- // Since we're accessing a prototype in a loop, it's a good bet that it
- // should not be treated as a dictionary.
- if (cell->structure()->isDictionary()) {
- asObject(cell)->flattenDictionaryObject(callFrame->globalData());
- if (slotBase == cell)
- slotOffset = cell->structure()->get(callFrame->globalData(), propertyName);
- }
-
- ++count;
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (cell->structure()->isDictionary()) {
+ asObject(cell)->flattenDictionaryObject(callFrame->vm());
+ if (slotBase == cell)
+ slotOffset = cell->structure()->get(callFrame->vm(), propertyName);
}
-
- ASSERT(count);
- return count;
+
+ ++count;
}
-
- inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
- {
- size_t count = 0;
- while (1) {
- if (base->isProxy())
- return InvalidPrototypeChain;
+
+ ASSERT(count);
+ return count;
+}
+
+inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
+{
+ size_t count = 0;
+ while (1) {
+ if (base->isProxy())
+ return InvalidPrototypeChain;
- JSValue v = base->structure()->prototypeForLookup(callFrame);
- if (v.isNull())
- return count;
+ JSValue v = base->structure()->prototypeForLookup(callFrame);
+ if (v.isNull())
+ return count;
- base = v.asCell();
+ base = v.asCell();
- // Since we're accessing a prototype in a loop, it's a good bet that it
- // should not be treated as a dictionary.
- if (base->structure()->isDictionary())
- asObject(base)->flattenDictionaryObject(callFrame->globalData());
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (base->structure()->isDictionary())
+ asObject(base)->flattenDictionaryObject(callFrame->vm());
- ++count;
- }
+ ++count;
}
+}
- inline bool isPrototypeChainNormalized(JSGlobalObject* globalObject, Structure* structure)
- {
- for (;;) {
- if (structure->typeInfo().type() == ProxyType)
- return false;
+inline bool isPrototypeChainNormalized(JSGlobalObject* globalObject, Structure* structure)
+{
+ for (;;) {
+ if (structure->typeInfo().type() == ProxyType)
+ return false;
- JSValue v = structure->prototypeForLookup(globalObject);
- if (v.isNull())
- return true;
+ JSValue v = structure->prototypeForLookup(globalObject);
+ if (v.isNull())
+ return true;
- structure = v.asCell()->structure();
+ structure = v.asCell()->structure();
- if (structure->isDictionary())
- return false;
- }
+ if (structure->isDictionary())
+ return false;
}
+}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp
index 386eb4fcf..40711bfa3 100644
--- a/Source/JavaScriptCore/runtime/Options.cpp
+++ b/Source/JavaScriptCore/runtime/Options.cpp
@@ -36,7 +36,6 @@
#include <wtf/PageBlock.h>
#include <wtf/StdLibExtras.h>
#include <wtf/StringExtras.h>
-#include <wtf/UnusedParam.h>
#if OS(DARWIN) && ENABLE(PARALLEL_GC)
#include <sys/sysctl.h>
@@ -72,6 +71,11 @@ static bool parse(const char* string, double& value)
return sscanf(string, "%lf", &value) == 1;
}
+static bool parse(const char* string, OptionRange& value)
+{
+ return value.init(string);
+}
+
template<typename T>
void overrideOptionWithHeuristic(T& variable, const char* name)
{
@@ -105,6 +109,59 @@ static unsigned computeNumberOfGCMarkers(int maxNumberOfGCMarkers)
return cpusToUse;
}
+bool OptionRange::init(const char* rangeString)
+{
+ // rangeString should be in the form of [!]<low>[:<high>]
+ // where low and high are unsigned
+
+ bool invert = false;
+
+ if (m_state > Uninitialized)
+ return true;
+
+ if (!rangeString) {
+ m_state = InitError;
+ return false;
+ }
+
+ m_rangeString = rangeString;
+
+ if (*rangeString == '!') {
+ invert = true;
+ rangeString++;
+ }
+
+ int scanResult = sscanf(rangeString, " %u:%u", &m_lowLimit, &m_highLimit);
+
+ if (!scanResult || scanResult == EOF) {
+ m_state = InitError;
+ return false;
+ }
+
+ if (scanResult == 1)
+ m_highLimit = m_lowLimit;
+
+ if (m_lowLimit > m_highLimit) {
+ m_state = InitError;
+ return false;
+ }
+
+ m_state = invert ? Inverted : Normal;
+
+ return true;
+}
+
+bool OptionRange::isInRange(unsigned count)
+{
+ if (m_state < Normal)
+ return true;
+
+ if ((m_lowLimit <= count) && (count <= m_highLimit))
+ return m_state == Normal ? true : false;
+
+ return m_state == Normal ? false : true;
+}
+
Options::Entry Options::s_options[Options::numberOfOptions];
// Realize the names for each of the options:
@@ -187,6 +244,7 @@ bool Options::setOption(const char* arg)
#define FOR_EACH_OPTION(type_, name_, defaultValue_) \
if (!strncmp(arg, #name_, equalStr - arg)) { \
type_ value; \
+ value = 0; \
bool success = parse(valueStr, value); \
if (success) { \
name_() = value; \
@@ -227,6 +285,9 @@ void Options::dumpOption(OptionID id, FILE* stream, const char* header, const ch
case int32Type:
fprintf(stream, "%d", s_options[id].u.int32Val);
break;
+ case optionRangeType:
+ fprintf(stream, "%s", s_options[id].u.optionRangeVal.rangeString());
+ break;
}
fprintf(stream, "%s", footer);
}
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index bf4a0cf75..559b6084b 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -60,6 +60,33 @@ namespace JSC {
// values after the sanity checks (for your own testing), then you're liable to
// ensure that the new values set are sane and reasonable for your own run.
+class OptionRange {
+private:
+ enum RangeState { Uninitialized, InitError, Normal, Inverted };
+public:
+ OptionRange& operator= (const int& rhs)
+ { // Only needed for initialization
+ if (!rhs) {
+ m_state = Uninitialized;
+ m_rangeString = 0;
+ m_lowLimit = 0;
+ m_highLimit = 0;
+ }
+ return *this;
+ }
+
+ bool init(const char*);
+ bool isInRange(unsigned);
+ const char* rangeString() { return (m_state > InitError) ? m_rangeString : "<null>"; }
+
+private:
+ RangeState m_state;
+ const char* m_rangeString;
+ unsigned m_lowLimit;
+ unsigned m_highLimit;
+};
+
+typedef OptionRange optionRange;
#define JSC_OPTIONS(v) \
v(bool, useJIT, true) \
@@ -74,10 +101,21 @@ namespace JSC {
v(bool, showDisassembly, false) \
v(bool, showDFGDisassembly, false) \
v(bool, showAllDFGNodes, false) \
+ v(optionRange, bytecodeRangeToDFGCompile, 0) \
+ v(bool, dumpBytecodeAtDFGTime, false) \
+ v(bool, dumpGraphAtEachPhase, false) \
+ v(bool, verboseCompilation, false) \
+ v(bool, logCompilationChanges, false) \
+ v(bool, printEachOSRExit, false) \
+ v(bool, validateGraph, false) \
+ v(bool, validateGraphAtEachPhase, false) \
+ \
+ v(bool, enableProfiler, false) \
\
v(unsigned, maximumOptimizationCandidateInstructionCount, 10000) \
\
v(unsigned, maximumFunctionForCallInlineCandidateInstructionCount, 180) \
+ v(unsigned, maximumFunctionForClosureCallInlineCandidateInstructionCount, 100) \
v(unsigned, maximumFunctionForConstructInlineCandidateInstructionCount, 100) \
\
/* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \
@@ -87,21 +125,20 @@ namespace JSC {
v(int32, thresholdForJITSoon, 100) \
\
v(int32, thresholdForOptimizeAfterWarmUp, 1000) \
- v(int32, thresholdForOptimizeAfterLongWarmUp, 5000) \
+ v(int32, thresholdForOptimizeAfterLongWarmUp, 1000) \
v(int32, thresholdForOptimizeSoon, 1000) \
\
v(int32, executionCounterIncrementForLoop, 1) \
v(int32, executionCounterIncrementForReturn, 15) \
\
+ v(int32, evalThresholdMultiplier, 10) \
+ \
v(bool, randomizeExecutionCountsBetweenCheckpoints, false) \
v(int32, maximumExecutionCountsBetweenCheckpoints, 1000) \
\
- v(double, likelyToTakeSlowCaseThreshold, 0.15) \
- v(double, couldTakeSlowCaseThreshold, 0.05) \
v(unsigned, likelyToTakeSlowCaseMinimumCount, 100) \
v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
\
- v(double, osrExitProminenceForFrequentExitSite, 0.3) \
v(unsigned, osrExitCountForReoptimization, 100) \
v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
\
@@ -170,6 +207,7 @@ private:
unsignedType,
doubleType,
int32Type,
+ optionRangeType,
};
// For storing for an option value:
@@ -179,6 +217,7 @@ private:
unsigned unsignedVal;
double doubleVal;
int32 int32Val;
+ OptionRange optionRangeVal;
} u;
};
diff --git a/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp b/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
index 236a8e5ae..14b42fd9a 100644
--- a/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
+++ b/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp
@@ -176,8 +176,8 @@ bool sameValue(ExecState* exec, JSValue a, JSValue b)
return false;
double x = a.asNumber();
double y = b.asNumber();
- if (isnan(x))
- return isnan(y);
+ if (std::isnan(x))
+ return std::isnan(y);
return bitwise_cast<uint64_t>(x) == bitwise_cast<uint64_t>(y);
}
diff --git a/Source/JavaScriptCore/runtime/PropertyDescriptor.h b/Source/JavaScriptCore/runtime/PropertyDescriptor.h
index 2c3878f57..5a5857d1c 100644
--- a/Source/JavaScriptCore/runtime/PropertyDescriptor.h
+++ b/Source/JavaScriptCore/runtime/PropertyDescriptor.h
@@ -26,7 +26,7 @@
#ifndef PropertyDescriptor_h
#define PropertyDescriptor_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
class GetterSetter;
diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
index 9c6ddb20f..9ddb6997c 100644
--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -22,8 +22,10 @@
#define PropertyMapHashTable_h
#include "PropertyOffset.h"
+#include "Structure.h"
#include "WriteBarrier.h"
#include <wtf/HashTable.h>
+#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/StringImpl.h>
@@ -50,9 +52,7 @@ namespace JSC {
inline bool isPowerOf2(unsigned v)
{
- // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
-
- return !(v & (v - 1)) && v;
+ return hasOneBitSet(v);
}
inline unsigned nextPowerOf2(unsigned v)
@@ -77,17 +77,16 @@ struct PropertyMapEntry {
unsigned attributes;
WriteBarrier<JSCell> specificValue;
- PropertyMapEntry(JSGlobalData& globalData, JSCell* owner, StringImpl* key, PropertyOffset offset, unsigned attributes, JSCell* specificValue)
+ PropertyMapEntry(VM& vm, JSCell* owner, StringImpl* key, PropertyOffset offset, unsigned attributes, JSCell* specificValue)
: key(key)
, offset(offset)
, attributes(attributes)
- , specificValue(globalData, owner, specificValue, WriteBarrier<JSCell>::MayBeNull)
+ , specificValue(vm, owner, specificValue, WriteBarrier<JSCell>::MayBeNull)
{
}
};
-class PropertyTable {
- WTF_MAKE_FAST_ALLOCATED;
+class PropertyTable : public JSCell {
// This is the implementation for 'iterator' and 'const_iterator',
// used for iterating over the table in insertion order.
@@ -130,6 +129,19 @@ class PropertyTable {
};
public:
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+ static void destroy(JSCell*);
+
+ static JS_EXPORTDATA const ClassInfo s_info;
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info);
+ }
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+
typedef StringImpl* KeyType;
typedef PropertyMapEntry ValueType;
@@ -143,9 +155,9 @@ public:
typedef std::pair<ValueType*, unsigned> find_iterator;
// Constructor is passed an initial capacity, a PropertyTable to copy, or both.
- explicit PropertyTable(unsigned initialCapacity);
- PropertyTable(JSGlobalData&, JSCell*, const PropertyTable&);
- PropertyTable(JSGlobalData&, JSCell*, unsigned initialCapacity, const PropertyTable&);
+ static PropertyTable* create(VM&, unsigned initialCapacity);
+ static PropertyTable* clone(VM&, JSCell* owner, const PropertyTable&);
+ static PropertyTable* clone(VM&, JSCell* owner, unsigned initialCapacity, const PropertyTable&);
~PropertyTable();
// Ordered iteration methods.
@@ -158,7 +170,8 @@ public:
find_iterator find(const KeyType&);
find_iterator findWithString(const KeyType&);
// Add a value to the table
- std::pair<find_iterator, bool> add(const ValueType& entry);
+ enum EffectOnPropertyOffset { PropertyOffsetMayChange, PropertyOffsetMustNotChange };
+ std::pair<find_iterator, bool> add(const ValueType& entry, PropertyOffset&, EffectOnPropertyOffset);
// Remove a value from the table.
void remove(const find_iterator& iter);
void remove(const KeyType& key);
@@ -181,7 +194,7 @@ public:
PropertyOffset nextOffset(PropertyOffset inlineCapacity);
// Copy this PropertyTable, ensuring the copy has at least the capacity provided.
- PassOwnPtr<PropertyTable> copy(JSGlobalData&, JSCell* owner, unsigned newCapacity);
+ PropertyTable* copy(VM&, JSCell* owner, unsigned newCapacity);
#ifndef NDEBUG
size_t sizeInMemory();
@@ -189,6 +202,10 @@ public:
#endif
private:
+ PropertyTable(VM&, unsigned initialCapacity);
+ PropertyTable(VM&, JSCell*, const PropertyTable&);
+ PropertyTable(VM&, JSCell*, unsigned initialCapacity, const PropertyTable&);
+
PropertyTable(const PropertyTable&);
// Used to insert a value known not to be in the table, and where we know capacity to be available.
void reinsert(const ValueType& entry);
@@ -235,76 +252,10 @@ private:
unsigned m_deletedCount;
OwnPtr< Vector<PropertyOffset> > m_deletedOffsets;
- static const unsigned MinimumTableSize = 16;
+ static const unsigned MinimumTableSize = 8;
static const unsigned EmptyEntryIndex = 0;
};
-inline PropertyTable::PropertyTable(unsigned initialCapacity)
- : m_indexSize(sizeForCapacity(initialCapacity))
- , m_indexMask(m_indexSize - 1)
- , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
- , m_keyCount(0)
- , m_deletedCount(0)
-{
- ASSERT(isPowerOf2(m_indexSize));
-}
-
-inline PropertyTable::PropertyTable(JSGlobalData&, JSCell* owner, const PropertyTable& other)
- : m_indexSize(other.m_indexSize)
- , m_indexMask(other.m_indexMask)
- , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
- , m_keyCount(other.m_keyCount)
- , m_deletedCount(other.m_deletedCount)
-{
- ASSERT(isPowerOf2(m_indexSize));
-
- memcpy(m_index, other.m_index, dataSize());
-
- iterator end = this->end();
- for (iterator iter = begin(); iter != end; ++iter) {
- iter->key->ref();
- Heap::writeBarrier(owner, iter->specificValue.get());
- }
-
- // Copy the m_deletedOffsets vector.
- Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
- if (otherDeletedOffsets)
- m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
-}
-
-inline PropertyTable::PropertyTable(JSGlobalData&, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
- : m_indexSize(sizeForCapacity(initialCapacity))
- , m_indexMask(m_indexSize - 1)
- , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
- , m_keyCount(0)
- , m_deletedCount(0)
-{
- ASSERT(isPowerOf2(m_indexSize));
- ASSERT(initialCapacity >= other.m_keyCount);
-
- const_iterator end = other.end();
- for (const_iterator iter = other.begin(); iter != end; ++iter) {
- ASSERT(canInsert());
- reinsert(*iter);
- iter->key->ref();
- Heap::writeBarrier(owner, iter->specificValue.get());
- }
-
- // Copy the m_deletedOffsets vector.
- Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
- if (otherDeletedOffsets)
- m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
-}
-
-inline PropertyTable::~PropertyTable()
-{
- iterator end = this->end();
- for (iterator iter = begin(); iter != end; ++iter)
- iter->key->deref();
-
- fastFree(m_index);
-}
-
inline PropertyTable::iterator PropertyTable::begin()
{
return iterator(skipDeletedEntries(table()));
@@ -390,12 +341,14 @@ inline PropertyTable::find_iterator PropertyTable::findWithString(const KeyType&
}
}
-inline std::pair<PropertyTable::find_iterator, bool> PropertyTable::add(const ValueType& entry)
+inline std::pair<PropertyTable::find_iterator, bool> PropertyTable::add(const ValueType& entry, PropertyOffset& offset, EffectOnPropertyOffset offsetEffect)
{
// Look for a value with a matching key already in the array.
find_iterator iter = find(entry.key);
- if (iter.first)
+ if (iter.first) {
+ RELEASE_ASSERT(iter.first->offset <= offset);
return std::make_pair(iter, false);
+ }
// Ref the key
entry.key->ref();
@@ -414,6 +367,12 @@ inline std::pair<PropertyTable::find_iterator, bool> PropertyTable::add(const Va
*iter.first = entry;
++m_keyCount;
+
+ if (offsetEffect == PropertyOffsetMayChange)
+ offset = std::max(offset, entry.offset);
+ else
+ RELEASE_ASSERT(offset >= entry.offset);
+
return std::make_pair(iter, true);
}
@@ -491,18 +450,18 @@ inline PropertyOffset PropertyTable::nextOffset(PropertyOffset inlineCapacity)
if (hasDeletedOffset())
return getDeletedOffset();
- return propertyOffsetFor(size(), inlineCapacity);
+ return offsetForPropertyNumber(size(), inlineCapacity);
}
-inline PassOwnPtr<PropertyTable> PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity)
+inline PropertyTable* PropertyTable::copy(VM& vm, JSCell* owner, unsigned newCapacity)
{
ASSERT(newCapacity >= m_keyCount);
// Fast case; if the new table will be the same m_indexSize as this one, we can memcpy it,
// save rehashing all keys.
if (sizeForCapacity(newCapacity) == m_indexSize)
- return adoptPtr(new PropertyTable(globalData, owner, *this));
- return adoptPtr(new PropertyTable(globalData, owner, newCapacity, *this));
+ return PropertyTable::clone(vm, owner, *this);
+ return PropertyTable::clone(vm, owner, newCapacity, *this);
}
#ifndef NDEBUG
@@ -588,7 +547,7 @@ inline size_t PropertyTable::dataSize()
inline unsigned PropertyTable::sizeForCapacity(unsigned capacity)
{
- if (capacity < 8)
+ if (capacity < MinimumTableSize / 2)
return MinimumTableSize;
return nextPowerOf2(capacity + 1) * 2;
}
diff --git a/Source/JavaScriptCore/runtime/PropertyNameArray.h b/Source/JavaScriptCore/runtime/PropertyNameArray.h
index 1cdac0049..96f1d0afa 100644
--- a/Source/JavaScriptCore/runtime/PropertyNameArray.h
+++ b/Source/JavaScriptCore/runtime/PropertyNameArray.h
@@ -52,9 +52,9 @@ namespace JSC {
// FIXME: Rename to PropertyNameArrayBuilder.
class PropertyNameArray {
public:
- PropertyNameArray(JSGlobalData* globalData)
+ PropertyNameArray(VM* vm)
: m_data(PropertyNameArrayData::create())
- , m_globalData(globalData)
+ , m_vm(vm)
, m_numCacheableSlots(0)
, m_baseObject(0)
{
@@ -62,17 +62,17 @@ namespace JSC {
PropertyNameArray(ExecState* exec)
: m_data(PropertyNameArrayData::create())
- , m_globalData(&exec->globalData())
+ , m_vm(&exec->vm())
, m_numCacheableSlots(0)
, m_baseObject(0)
{
}
- JSGlobalData* globalData() { return m_globalData; }
+ VM* vm() { return m_vm; }
void add(const Identifier& identifier) { add(identifier.impl()); }
JS_EXPORT_PRIVATE void add(StringImpl*);
- void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); }
+ void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_vm, identifier)); }
Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
@@ -106,7 +106,7 @@ namespace JSC {
RefPtr<PropertyNameArrayData> m_data;
IdentifierSet m_set;
- JSGlobalData* m_globalData;
+ VM* m_vm;
size_t m_numCacheableSlots;
JSObject* m_baseObject;
};
diff --git a/Source/JavaScriptCore/runtime/PropertyOffset.h b/Source/JavaScriptCore/runtime/PropertyOffset.h
index 1a2bba446..dc0297bf7 100644
--- a/Source/JavaScriptCore/runtime/PropertyOffset.h
+++ b/Source/JavaScriptCore/runtime/PropertyOffset.h
@@ -28,16 +28,9 @@
#include <wtf/Platform.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/UnusedParam.h>
namespace JSC {
-#if USE(JSVALUE32_64)
-#define INLINE_STORAGE_CAPACITY 7
-#else
-#define INLINE_STORAGE_CAPACITY 6
-#endif
-
typedef int PropertyOffset;
static const PropertyOffset invalidOffset = -1;
@@ -45,9 +38,9 @@ static const PropertyOffset firstOutOfLineOffset = 100;
// Declare all of the functions because they tend to do forward calls.
inline void checkOffset(PropertyOffset);
-inline void checkOffset(PropertyOffset, PropertyOffset inlineCapacity);
+inline void checkOffset(PropertyOffset, int inlineCapacity);
inline void validateOffset(PropertyOffset);
-inline void validateOffset(PropertyOffset, PropertyOffset inlineCapacity);
+inline void validateOffset(PropertyOffset, int inlineCapacity);
inline bool isValidOffset(PropertyOffset);
inline bool isInlineOffset(PropertyOffset);
inline bool isOutOfLineOffset(PropertyOffset);
@@ -55,7 +48,7 @@ inline size_t offsetInInlineStorage(PropertyOffset);
inline size_t offsetInOutOfLineStorage(PropertyOffset);
inline size_t offsetInRespectiveStorage(PropertyOffset);
inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset);
-inline size_t numberOfSlotsForLastOffset(PropertyOffset, PropertyOffset inlineCapacity);
+inline size_t numberOfSlotsForLastOffset(PropertyOffset, int inlineCapacity);
inline void checkOffset(PropertyOffset offset)
{
@@ -63,7 +56,7 @@ inline void checkOffset(PropertyOffset offset)
ASSERT(offset >= invalidOffset);
}
-inline void checkOffset(PropertyOffset offset, PropertyOffset inlineCapacity)
+inline void checkOffset(PropertyOffset offset, int inlineCapacity)
{
UNUSED_PARAM(offset);
UNUSED_PARAM(inlineCapacity);
@@ -79,7 +72,7 @@ inline void validateOffset(PropertyOffset offset)
ASSERT(isValidOffset(offset));
}
-inline void validateOffset(PropertyOffset offset, PropertyOffset inlineCapacity)
+inline void validateOffset(PropertyOffset offset, int inlineCapacity)
{
checkOffset(offset, inlineCapacity);
ASSERT(isValidOffset(offset));
@@ -132,7 +125,7 @@ inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset offset)
return offset - firstOutOfLineOffset + 1;
}
-inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, PropertyOffset inlineCapacity)
+inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, int inlineCapacity)
{
checkOffset(offset, inlineCapacity);
if (offset < inlineCapacity)
@@ -140,7 +133,7 @@ inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, PropertyOffset i
return inlineCapacity + numberOfOutOfLineSlotsForLastOffset(offset);
}
-inline PropertyOffset propertyOffsetFor(PropertyOffset propertyNumber, PropertyOffset inlineCapacity)
+inline PropertyOffset offsetForPropertyNumber(int propertyNumber, int inlineCapacity)
{
PropertyOffset offset = propertyNumber;
if (offset >= inlineCapacity) {
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.cpp b/Source/JavaScriptCore/runtime/PropertySlot.cpp
index 8ac874115..291ea487c 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.cpp
+++ b/Source/JavaScriptCore/runtime/PropertySlot.cpp
@@ -23,6 +23,7 @@
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/PropertySlot.h b/Source/JavaScriptCore/runtime/PropertySlot.h
index c673eaa50..6fb80d23d 100644
--- a/Source/JavaScriptCore/runtime/PropertySlot.h
+++ b/Source/JavaScriptCore/runtime/PropertySlot.h
@@ -21,7 +21,7 @@
#ifndef PropertySlot_h
#define PropertySlot_h
-#include "JSValue.h"
+#include "JSCJSValue.h"
#include "PropertyName.h"
#include "PropertyOffset.h"
#include "Register.h"
diff --git a/Source/JavaScriptCore/runtime/PropertyTable.cpp b/Source/JavaScriptCore/runtime/PropertyTable.cpp
new file mode 100644
index 000000000..bb5ecce4a
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/PropertyTable.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 "PropertyMapHashTable.h"
+
+#include "JSCJSValueInlines.h"
+#include "JSCellInlines.h"
+#include "SlotVisitorInlines.h"
+#include "StructureInlines.h"
+
+namespace JSC {
+
+const ClassInfo PropertyTable::s_info = { "PropertyTable", 0, 0, 0, CREATE_METHOD_TABLE(PropertyTable) };
+
+PropertyTable* PropertyTable::create(VM& vm, unsigned initialCapacity)
+{
+ PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, initialCapacity);
+ table->finishCreation(vm);
+ return table;
+}
+
+PropertyTable* PropertyTable::clone(VM& vm, JSCell* owner, const PropertyTable& other)
+{
+ PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, owner, other);
+ table->finishCreation(vm);
+ return table;
+}
+
+PropertyTable* PropertyTable::clone(VM& vm, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
+{
+ PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(vm.heap)) PropertyTable(vm, owner, initialCapacity, other);
+ table->finishCreation(vm);
+ return table;
+}
+
+PropertyTable::PropertyTable(VM& vm, unsigned initialCapacity)
+ : JSCell(vm, vm.propertyTableStructure.get())
+ , m_indexSize(sizeForCapacity(initialCapacity))
+ , m_indexMask(m_indexSize - 1)
+ , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
+ , m_keyCount(0)
+ , m_deletedCount(0)
+{
+ ASSERT(isPowerOf2(m_indexSize));
+}
+
+PropertyTable::PropertyTable(VM& vm, JSCell* owner, const PropertyTable& other)
+ : JSCell(vm, vm.propertyTableStructure.get())
+ , m_indexSize(other.m_indexSize)
+ , m_indexMask(other.m_indexMask)
+ , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
+ , m_keyCount(other.m_keyCount)
+ , m_deletedCount(other.m_deletedCount)
+{
+ ASSERT(isPowerOf2(m_indexSize));
+
+ memcpy(m_index, other.m_index, dataSize());
+
+ iterator end = this->end();
+ for (iterator iter = begin(); iter != end; ++iter) {
+ iter->key->ref();
+ Heap::writeBarrier(owner, iter->specificValue.get());
+ }
+
+ // Copy the m_deletedOffsets vector.
+ Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
+ if (otherDeletedOffsets)
+ m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
+}
+
+PropertyTable::PropertyTable(VM& vm, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
+ : JSCell(vm, vm.propertyTableStructure.get())
+ , m_indexSize(sizeForCapacity(initialCapacity))
+ , m_indexMask(m_indexSize - 1)
+ , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
+ , m_keyCount(0)
+ , m_deletedCount(0)
+{
+ ASSERT(isPowerOf2(m_indexSize));
+ ASSERT(initialCapacity >= other.m_keyCount);
+
+ const_iterator end = other.end();
+ for (const_iterator iter = other.begin(); iter != end; ++iter) {
+ ASSERT(canInsert());
+ reinsert(*iter);
+ iter->key->ref();
+ Heap::writeBarrier(owner, iter->specificValue.get());
+ }
+
+ // Copy the m_deletedOffsets vector.
+ Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
+ if (otherDeletedOffsets)
+ m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
+}
+
+void PropertyTable::destroy(JSCell* cell)
+{
+ static_cast<PropertyTable*>(cell)->PropertyTable::~PropertyTable();
+}
+
+PropertyTable::~PropertyTable()
+{
+ iterator end = this->end();
+ for (iterator iter = begin(); iter != end; ++iter)
+ iter->key->deref();
+
+ fastFree(m_index);
+}
+
+void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ PropertyTable* thisObject = jsCast<PropertyTable*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
+ ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
+
+ JSCell::visitChildren(thisObject, visitor);
+
+ PropertyTable::iterator end = thisObject->end();
+ for (PropertyTable::iterator ptr = thisObject->begin(); ptr != end; ++ptr)
+ visitor.append(&ptr->specificValue);
+}
+
+}
diff --git a/Source/JavaScriptCore/runtime/Protect.h b/Source/JavaScriptCore/runtime/Protect.h
index 843c9e111..78dd319a3 100644
--- a/Source/JavaScriptCore/runtime/Protect.h
+++ b/Source/JavaScriptCore/runtime/Protect.h
@@ -23,7 +23,7 @@
#define Protect_h
#include "Heap.h"
-#include "JSValue.h"
+#include "JSCJSValue.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/PrototypeMap.cpp b/Source/JavaScriptCore/runtime/PrototypeMap.cpp
new file mode 100644
index 000000000..29de45b10
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/PrototypeMap.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PrototypeMap.h"
+
+#include "JSGlobalObject.h"
+#include "Operations.h"
+
+namespace JSC {
+
+void PrototypeMap::addPrototype(JSObject* object)
+{
+ m_prototypes.add(object, object);
+
+ // Note that this method makes the somewhat odd decision to not check if this
+ // object currently has indexed accessors. We could do that check here, and if
+ // indexed accessors were found, we could tell the global object to have a bad
+ // time. But we avoid this, to allow the following to be always fast:
+ //
+ // 1) Create an object.
+ // 2) Give it a setter or read-only property that happens to have a numeric name.
+ // 3) Allocate objects that use this object as a prototype.
+ //
+ // This avoids anyone having a bad time. Even if the instance objects end up
+ // having indexed storage, the creation of indexed storage leads to a prototype
+ // chain walk that detects the presence of indexed setters and then does the
+ // right thing. As a result, having a bad time only happens if you add an
+ // indexed setter (or getter, or read-only field) to an object that is already
+ // used as a prototype.
+}
+
+Structure* PrototypeMap::emptyObjectStructureForPrototype(JSObject* prototype, unsigned inlineCapacity)
+{
+ StructureMap::AddResult addResult = m_structures.add(std::make_pair(prototype, inlineCapacity), nullptr);
+ if (!addResult.isNewEntry) {
+ ASSERT(isPrototype(prototype));
+ return addResult.iterator->value.get();
+ }
+
+ addPrototype(prototype);
+ Structure* structure = JSFinalObject::createStructure(
+ prototype->globalObject()->vm(), prototype->globalObject(), prototype, inlineCapacity);
+ addResult.iterator->value = structure;
+ return structure;
+}
+
+void PrototypeMap::clearEmptyObjectStructureForPrototype(JSObject* object, unsigned inlineCapacity)
+{
+ m_structures.remove(std::make_pair(object, inlineCapacity));
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/PrototypeMap.h b/Source/JavaScriptCore/runtime/PrototypeMap.h
new file mode 100644
index 000000000..9752ca7ea
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/PrototypeMap.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PrototypeMap_h
+#define PrototypeMap_h
+
+#include "WeakGCMap.h"
+#include <wtf/TriState.h>
+
+namespace JSC {
+
+class JSObject;
+class Structure;
+
+// Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
+class PrototypeMap {
+public:
+ JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
+ void clearEmptyObjectStructureForPrototype(JSObject*, unsigned inlineCapacity);
+ void addPrototype(JSObject*);
+ TriState isPrototype(JSObject*) const; // Returns a conservative estimate.
+
+private:
+ WeakGCMap<JSObject*, JSObject> m_prototypes;
+ typedef WeakGCMap<std::pair<JSObject*, unsigned>, Structure> StructureMap;
+ StructureMap m_structures;
+};
+
+inline TriState PrototypeMap::isPrototype(JSObject* object) const
+{
+ if (!m_prototypes.contains(object))
+ return FalseTriState;
+
+ // We know that 'object' was used as a prototype at one time, so be
+ // conservative and say that it might still be so. (It would be expensive
+ // to find out for sure, and we don't know of any cases where being precise
+ // would improve performance.)
+ return MixedTriState;
+}
+
+} // namespace JSC
+
+#endif // PrototypeMap_h
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 3229f5207..d27bc1eb1 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -24,16 +24,16 @@
#include "RegExp.h"
#include "Lexer.h"
+#include "Operations.h"
#include "RegExpCache.h"
-#include "yarr/Yarr.h"
-#include "yarr/YarrJIT.h"
+#include "Yarr.h"
+#include "YarrJIT.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wtf/Assertions.h>
#include <wtf/OwnArrayPtr.h>
-
#define REGEXP_FUNC_TEST_DATA_GEN 0
namespace JSC {
@@ -217,8 +217,8 @@ void RegExpFunctionalTestCollector::outputEscapedString(const String& s, bool es
}
#endif
-RegExp::RegExp(JSGlobalData& globalData, const String& patternString, RegExpFlags flags)
- : JSCell(globalData, globalData.regExpStructure.get())
+RegExp::RegExp(VM& vm, const String& patternString, RegExpFlags flags)
+ : JSCell(vm, vm.regExpStructure.get())
, m_state(NotCompiled)
, m_patternString(patternString)
, m_flags(flags)
@@ -231,9 +231,9 @@ RegExp::RegExp(JSGlobalData& globalData, const String& patternString, RegExpFlag
{
}
-void RegExp::finishCreation(JSGlobalData& globalData)
+void RegExp::finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
if (m_constructionError)
m_state = ParseError;
@@ -250,23 +250,23 @@ void RegExp::destroy(JSCell* cell)
thisObject->RegExp::~RegExp();
}
-RegExp* RegExp::createWithoutCaching(JSGlobalData& globalData, const String& patternString, RegExpFlags flags)
+RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, RegExpFlags flags)
{
- RegExp* regExp = new (NotNull, allocateCell<RegExp>(globalData.heap)) RegExp(globalData, patternString, flags);
- regExp->finishCreation(globalData);
+ RegExp* regExp = new (NotNull, allocateCell<RegExp>(vm.heap)) RegExp(vm, patternString, flags);
+ regExp->finishCreation(vm);
return regExp;
}
-RegExp* RegExp::create(JSGlobalData& globalData, const String& patternString, RegExpFlags flags)
+RegExp* RegExp::create(VM& vm, const String& patternString, RegExpFlags flags)
{
- return globalData.regExpCache()->lookupOrCreate(patternString, flags);
+ return vm.regExpCache()->lookupOrCreate(patternString, flags);
}
-void RegExp::compile(JSGlobalData* globalData, Yarr::YarrCharSize charSize)
+void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize)
{
Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
if (m_constructionError) {
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
m_state = ParseError;
return;
}
@@ -274,13 +274,13 @@ void RegExp::compile(JSGlobalData* globalData, Yarr::YarrCharSize charSize)
if (!hasCode()) {
ASSERT(m_state == NotCompiled);
- globalData->regExpCache()->addToStrongCache(this);
+ vm->regExpCache()->addToStrongCache(this);
m_state = ByteCode;
}
#if ENABLE(YARR_JIT)
- if (!pattern.m_containsBackreferences && globalData->canUseRegExpJIT()) {
- Yarr::jitCompile(pattern, charSize, globalData, m_regExpJITCode);
+ if (!pattern.m_containsBackreferences && vm->canUseRegExpJIT()) {
+ Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
#if ENABLE(YARR_JIT_DEBUG)
if (!m_regExpJITCode.isFallBack())
m_state = JITCode;
@@ -297,10 +297,10 @@ void RegExp::compile(JSGlobalData* globalData, Yarr::YarrCharSize charSize)
UNUSED_PARAM(charSize);
#endif
- m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
+ m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
}
-void RegExp::compileIfNecessary(JSGlobalData& globalData, Yarr::YarrCharSize charSize)
+void RegExp::compileIfNecessary(VM& vm, Yarr::YarrCharSize charSize)
{
if (hasCode()) {
#if ENABLE(YARR_JIT)
@@ -315,17 +315,17 @@ void RegExp::compileIfNecessary(JSGlobalData& globalData, Yarr::YarrCharSize cha
#endif
}
- compile(&globalData, charSize);
+ compile(&vm, charSize);
}
-int RegExp::match(JSGlobalData& globalData, const String& s, unsigned startOffset, Vector<int, 32>& ovector)
+int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int, 32>& ovector)
{
#if ENABLE(REGEXP_TRACING)
m_rtMatchCallCount++;
#endif
ASSERT(m_state != ParseError);
- compileIfNecessary(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
+ compileIfNecessary(vm, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
int offsetVectorSize = (m_numSubpatterns + 1) * 2;
ovector.resize(offsetVectorSize);
@@ -384,11 +384,11 @@ int RegExp::match(JSGlobalData& globalData, const String& s, unsigned startOffse
return result;
}
-void RegExp::compileMatchOnly(JSGlobalData* globalData, Yarr::YarrCharSize charSize)
+void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize)
{
Yarr::YarrPattern pattern(m_patternString, ignoreCase(), multiline(), &m_constructionError);
if (m_constructionError) {
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
m_state = ParseError;
return;
}
@@ -396,13 +396,13 @@ void RegExp::compileMatchOnly(JSGlobalData* globalData, Yarr::YarrCharSize charS
if (!hasCode()) {
ASSERT(m_state == NotCompiled);
- globalData->regExpCache()->addToStrongCache(this);
+ vm->regExpCache()->addToStrongCache(this);
m_state = ByteCode;
}
#if ENABLE(YARR_JIT)
- if (!pattern.m_containsBackreferences && globalData->canUseRegExpJIT()) {
- Yarr::jitCompile(pattern, charSize, globalData, m_regExpJITCode, Yarr::MatchOnly);
+ if (!pattern.m_containsBackreferences && vm->canUseRegExpJIT()) {
+ Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
#if ENABLE(YARR_JIT_DEBUG)
if (!m_regExpJITCode.isFallBack())
m_state = JITCode;
@@ -419,10 +419,10 @@ void RegExp::compileMatchOnly(JSGlobalData* globalData, Yarr::YarrCharSize charS
UNUSED_PARAM(charSize);
#endif
- m_regExpBytecode = Yarr::byteCompile(pattern, &globalData->m_regExpAllocator);
+ m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
}
-void RegExp::compileIfNecessaryMatchOnly(JSGlobalData& globalData, Yarr::YarrCharSize charSize)
+void RegExp::compileIfNecessaryMatchOnly(VM& vm, Yarr::YarrCharSize charSize)
{
if (hasCode()) {
#if ENABLE(YARR_JIT)
@@ -437,17 +437,17 @@ void RegExp::compileIfNecessaryMatchOnly(JSGlobalData& globalData, Yarr::YarrCha
#endif
}
- compileMatchOnly(&globalData, charSize);
+ compileMatchOnly(&vm, charSize);
}
-MatchResult RegExp::match(JSGlobalData& globalData, const String& s, unsigned startOffset)
+MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset)
{
#if ENABLE(REGEXP_TRACING)
m_rtMatchCallCount++;
#endif
ASSERT(m_state != ParseError);
- compileIfNecessaryMatchOnly(globalData, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
+ compileIfNecessaryMatchOnly(vm, s.is8Bit() ? Yarr::Char8 : Yarr::Char16);
#if ENABLE(YARR_JIT)
if (m_state == JITCode) {
diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h
index b2b65d90c..94ea316a8 100644
--- a/Source/JavaScriptCore/runtime/RegExp.h
+++ b/Source/JavaScriptCore/runtime/RegExp.h
@@ -38,7 +38,7 @@
namespace JSC {
struct RegExpRepresentation;
- class JSGlobalData;
+ class VM;
JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
@@ -46,7 +46,7 @@ namespace JSC {
public:
typedef JSCell Base;
- JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const String& pattern, RegExpFlags);
+ JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
static const bool needsDestruction = true;
static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
@@ -60,8 +60,8 @@ namespace JSC {
bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
const char* errorMessage() const { return m_constructionError; }
- JS_EXPORT_PRIVATE int match(JSGlobalData&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
- MatchResult match(JSGlobalData&, const String&, unsigned startOffset);
+ JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
+ MatchResult match(VM&, const String&, unsigned startOffset);
unsigned numSubpatterns() const { return m_numSubpatterns; }
bool hasCode()
@@ -75,9 +75,9 @@ namespace JSC {
void printTraceData();
#endif
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(LeafType, 0), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(LeafType, 0), &s_info);
}
static const ClassInfo s_info;
@@ -85,13 +85,13 @@ namespace JSC {
RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
protected:
- void finishCreation(JSGlobalData&);
+ void finishCreation(VM&);
private:
friend class RegExpCache;
- RegExp(JSGlobalData&, const String&, RegExpFlags);
+ RegExp(VM&, const String&, RegExpFlags);
- static RegExp* createWithoutCaching(JSGlobalData&, const String&, RegExpFlags);
+ static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
enum RegExpState {
ParseError,
@@ -100,11 +100,11 @@ namespace JSC {
NotCompiled
} m_state;
- void compile(JSGlobalData*, Yarr::YarrCharSize);
- void compileIfNecessary(JSGlobalData&, Yarr::YarrCharSize);
+ void compile(VM*, Yarr::YarrCharSize);
+ void compileIfNecessary(VM&, Yarr::YarrCharSize);
- void compileMatchOnly(JSGlobalData*, Yarr::YarrCharSize);
- void compileIfNecessaryMatchOnly(JSGlobalData&, Yarr::YarrCharSize);
+ void compileMatchOnly(VM*, Yarr::YarrCharSize);
+ void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize);
#if ENABLE(YARR_JIT_DEBUG)
void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp
index 8acafba23..1ab3f5f51 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2010 University of Szeged
* Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu)
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,8 +27,9 @@
*/
#include "config.h"
-
#include "RegExpCache.h"
+
+#include "Operations.h"
#include "RegExpObject.h"
#include "StrongInlines.h"
@@ -39,18 +41,18 @@ RegExp* RegExpCache::lookupOrCreate(const String& patternString, RegExpFlags fla
if (RegExp* regExp = m_weakCache.get(key))
return regExp;
- RegExp* regExp = RegExp::createWithoutCaching(*m_globalData, patternString, flags);
+ RegExp* regExp = RegExp::createWithoutCaching(*m_vm, patternString, flags);
#if ENABLE(REGEXP_TRACING)
- m_globalData->addRegExpToTrace(regExp);
+ m_vm->addRegExpToTrace(regExp);
#endif
weakAdd(m_weakCache, key, PassWeak<RegExp>(regExp, this));
return regExp;
}
-RegExpCache::RegExpCache(JSGlobalData* globalData)
+RegExpCache::RegExpCache(VM* vm)
: m_nextEntryInStrongCache(0)
- , m_globalData(globalData)
+ , m_vm(vm)
{
}
@@ -66,7 +68,7 @@ void RegExpCache::addToStrongCache(RegExp* regExp)
String pattern = regExp->pattern();
if (pattern.length() > maxStrongCacheablePatternLength)
return;
- m_strongCache[m_nextEntryInStrongCache].set(*m_globalData, regExp);
+ m_strongCache[m_nextEntryInStrongCache].set(*m_vm, regExp);
m_nextEntryInStrongCache++;
if (m_nextEntryInStrongCache == maxStrongCacheableEntries)
m_nextEntryInStrongCache = 0;
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.h b/Source/JavaScriptCore/runtime/RegExpCache.h
index c6a4a0aa2..4f854d1ba 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.h
+++ b/Source/JavaScriptCore/runtime/RegExpCache.h
@@ -29,6 +29,7 @@
#include "RegExpKey.h"
#include "Strong.h"
#include "Weak.h"
+#include "WeakInlines.h"
#include <wtf/FixedArray.h>
#include <wtf/HashMap.h>
@@ -42,7 +43,7 @@ friend class RegExp;
typedef HashMap<RegExpKey, Weak<RegExp> > RegExpCacheMap;
public:
- RegExpCache(JSGlobalData* globalData);
+ RegExpCache(VM* vm);
void invalidateCode();
private:
@@ -58,7 +59,7 @@ private:
RegExpCacheMap m_weakCache; // Holds all regular expressions currently live.
int m_nextEntryInStrongCache;
WTF::FixedArray<Strong<RegExp>, maxStrongCacheableEntries> m_strongCache; // Holds a select few regular expressions that have compiled and executed
- JSGlobalData* m_globalData;
+ VM* m_vm;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp b/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp
index 47cff15f1..c54b4783d 100644
--- a/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "RegExpCachedResult.h"
+#include "Operations.h"
#include "RegExpMatchesArray.h"
namespace JSC {
@@ -41,8 +42,8 @@ void RegExpCachedResult::visitChildren(SlotVisitor& visitor)
RegExpMatchesArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner)
{
if (m_result) {
- m_reifiedInput.set(exec->globalData(), owner, m_lastInput.get());
- m_reifiedResult.set(exec->globalData(), owner, RegExpMatchesArray::create(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
+ m_reifiedInput.set(exec->vm(), owner, m_lastInput.get());
+ m_reifiedResult.set(exec->vm(), owner, RegExpMatchesArray::create(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
m_result = MatchResult::failed();
}
return m_reifiedResult.get();
@@ -53,7 +54,7 @@ void RegExpCachedResult::setInput(ExecState* exec, JSObject* owner, JSString* in
// Make sure we're reified, otherwise m_reifiedInput will be ignored.
lastResult(exec, owner);
ASSERT(!m_result);
- m_reifiedInput.set(exec->globalData(), owner, input);
+ m_reifiedInput.set(exec->vm(), owner, input);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/RegExpCachedResult.h b/Source/JavaScriptCore/runtime/RegExpCachedResult.h
index 812ff4336..d2763bc77 100644
--- a/Source/JavaScriptCore/runtime/RegExpCachedResult.h
+++ b/Source/JavaScriptCore/runtime/RegExpCachedResult.h
@@ -44,17 +44,17 @@ namespace JSC {
// m_reifiedResult and m_reifiedInput hold the cached results.
class RegExpCachedResult {
public:
- RegExpCachedResult(JSGlobalData& globalData, JSObject* owner, RegExp* emptyRegExp)
+ RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
: m_result(0, 0)
{
- m_lastInput.set(globalData, owner, jsEmptyString(&globalData));
- m_lastRegExp.set(globalData, owner, emptyRegExp);
+ m_lastInput.set(vm, owner, jsEmptyString(&vm));
+ m_lastRegExp.set(vm, owner, emptyRegExp);
}
- ALWAYS_INLINE void record(JSGlobalData& globalData, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
+ ALWAYS_INLINE void record(VM& vm, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
{
- m_lastRegExp.set(globalData, owner, regExp);
- m_lastInput.set(globalData, owner, input);
+ m_lastRegExp.set(vm, owner, regExp);
+ m_lastInput.set(vm, owner, input);
m_result = result;
}
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index cc6ceb1d1..8b12a5a05 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -23,6 +23,7 @@
#include "RegExpConstructor.h"
#include "Error.h"
+#include "Operations.h"
#include "RegExpMatchesArray.h"
#include "RegExpPrototype.h"
@@ -83,21 +84,21 @@ const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_i
RegExpConstructor::RegExpConstructor(JSGlobalObject* globalObject, Structure* structure, RegExpPrototype* regExpPrototype)
: InternalFunction(globalObject, structure)
- , m_cachedResult(globalObject->globalData(), this, regExpPrototype->regExp())
+ , m_cachedResult(globalObject->vm(), this, regExpPrototype->regExp())
, m_multiline(false)
{
}
void RegExpConstructor::finishCreation(ExecState* exec, RegExpPrototype* regExpPrototype)
{
- Base::finishCreation(exec->globalData(), Identifier(exec, "RegExp").string());
+ Base::finishCreation(exec->vm(), Identifier(exec, "RegExp").string());
ASSERT(inherits(&s_info));
// ECMA 15.10.5.1 RegExp.prototype
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
}
void RegExpConstructor::destroy(JSCell* cell)
@@ -282,7 +283,7 @@ JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const A
return throwError(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
}
- RegExp* regExp = RegExp::create(exec->globalData(), pattern, flags);
+ RegExp* regExp = RegExp::create(exec->vm(), pattern, flags);
if (!regExp->isValid())
return throwError(exec, createSyntaxError(exec, regExp->errorMessage()));
return RegExpObject::create(exec, exec->lexicalGlobalObject(), globalObject->regExpStructure(), regExp);
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.h b/Source/JavaScriptCore/runtime/RegExpConstructor.h
index 2cb1c1204..0942070d5 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.h
@@ -43,9 +43,9 @@ namespace JSC {
return constructor;
}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
@@ -55,8 +55,8 @@ namespace JSC {
static const ClassInfo s_info;
- MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
- MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const String&, int startOffset);
+ MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
+ MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
void setMultiline(bool multiline) { m_multiline = multiline; }
bool multiline() const { return m_multiline; }
@@ -101,9 +101,9 @@ namespace JSC {
expression matching through the performMatch function. We use cached results to calculate,
e.g., RegExp.lastMatch and RegExp.leftParen.
*/
- ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
+ ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
{
- int position = regExp->match(globalData, input, startOffset, m_ovector);
+ int position = regExp->match(vm, input, startOffset, m_ovector);
if (ovector)
*ovector = m_ovector.data();
@@ -116,15 +116,15 @@ namespace JSC {
ASSERT(m_ovector[1] >= position);
size_t end = m_ovector[1];
- m_cachedResult.record(globalData, this, regExp, string, MatchResult(position, end));
+ m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
return MatchResult(position, end);
}
- ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const String& input, int startOffset)
+ ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
{
- MatchResult result = regExp->match(globalData, input, startOffset);
+ MatchResult result = regExp->match(vm, input, startOffset);
if (result)
- m_cachedResult.record(globalData, this, regExp, string, result);
+ m_cachedResult.record(vm, this, regExp, string, result);
return result;
}
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
index 19f3b81ad..062650a86 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
@@ -27,33 +27,34 @@
#include "RegExpMatchesArray.h"
#include "ButterflyInlines.h"
+#include "Operations.h"
namespace JSC {
const ClassInfo RegExpMatchesArray::s_info = {"Array", &JSArray::s_info, 0, 0, CREATE_METHOD_TABLE(RegExpMatchesArray)};
-RegExpMatchesArray::RegExpMatchesArray(JSGlobalData& globalData, Butterfly* butterfly, JSGlobalObject* globalObject, JSString* input, RegExp* regExp, MatchResult result)
- : JSArray(globalData, globalObject->regExpMatchesArrayStructure(), butterfly)
+RegExpMatchesArray::RegExpMatchesArray(VM& vm, Butterfly* butterfly, JSGlobalObject* globalObject, JSString* input, RegExp* regExp, MatchResult result)
+ : JSArray(vm, globalObject->regExpMatchesArrayStructure(), butterfly)
, m_result(result)
, m_state(ReifiedNone)
{
- m_input.set(globalData, this, input);
- m_regExp.set(globalData, this, regExp);
+ m_input.set(vm, this, input);
+ m_regExp.set(vm, this, regExp);
}
RegExpMatchesArray* RegExpMatchesArray::create(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
{
ASSERT(result);
- JSGlobalData& globalData = exec->globalData();
- Butterfly* butterfly = createArrayButterfly(globalData, regExp->numSubpatterns() + 1);
- RegExpMatchesArray* array = new (NotNull, allocateCell<RegExpMatchesArray>(globalData.heap)) RegExpMatchesArray(globalData, butterfly, exec->lexicalGlobalObject(), input, regExp, result);
- array->finishCreation(globalData);
+ VM& vm = exec->vm();
+ Butterfly* butterfly = createArrayButterfly(vm, regExp->numSubpatterns() + 1);
+ RegExpMatchesArray* array = new (NotNull, allocateCell<RegExpMatchesArray>(vm.heap)) RegExpMatchesArray(vm, butterfly, exec->lexicalGlobalObject(), input, regExp, result);
+ array->finishCreation(vm);
return array;
}
-void RegExpMatchesArray::finishCreation(JSGlobalData& globalData)
+void RegExpMatchesArray::finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
}
void RegExpMatchesArray::visitChildren(JSCell* cell, SlotVisitor& visitor)
@@ -77,7 +78,7 @@ void RegExpMatchesArray::reifyAllProperties(ExecState* exec)
if (unsigned numSubpatterns = m_regExp->numSubpatterns()) {
Vector<int, 32> subpatternResults;
- int position = m_regExp->match(exec->globalData(), m_input->value(exec), m_result.start, subpatternResults);
+ int position = m_regExp->match(exec->vm(), m_input->value(exec), m_result.start, subpatternResults);
ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == m_result.start);
ASSERT(m_result.start == static_cast<size_t>(subpatternResults[0]));
ASSERT(m_result.end == static_cast<size_t>(subpatternResults[1]));
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
index a5b860b9d..c7c942052 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -28,7 +28,7 @@ namespace JSC {
class RegExpMatchesArray : public JSArray {
private:
- RegExpMatchesArray(JSGlobalData&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
+ RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };
@@ -42,15 +42,15 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithArrayStorage);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithSlowPutArrayStorage);
}
static void visitChildren(JSCell*, SlotVisitor&);
protected:
- void finishCreation(JSGlobalData&);
+ void finishCreation(VM&);
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp
index 00dd1ed74..8b2d03c02 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp
@@ -30,6 +30,7 @@
#include "JSString.h"
#include "Lexer.h"
#include "Lookup.h"
+#include "Operations.h"
#include "RegExpConstructor.h"
#include "RegExpMatchesArray.h"
#include "RegExpPrototype.h"
@@ -63,8 +64,8 @@ const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, 0, ExecState::
*/
RegExpObject::RegExpObject(JSGlobalObject* globalObject, Structure* structure, RegExp* regExp)
- : JSNonFinalObject(globalObject->globalData(), structure)
- , m_regExp(globalObject->globalData(), this, regExp)
+ : JSNonFinalObject(globalObject->vm(), structure)
+ , m_regExp(globalObject->vm(), this, regExp)
, m_lastIndexIsWritable(true)
{
m_lastIndex.setWithoutWriteBarrier(jsNumber(0));
@@ -72,7 +73,7 @@ RegExpObject::RegExpObject(JSGlobalObject* globalObject, Structure* structure, R
void RegExpObject::finishCreation(JSGlobalObject* globalObject)
{
- Base::finishCreation(globalObject->globalData());
+ Base::finishCreation(globalObject->vm());
ASSERT(inherits(&s_info));
}
@@ -314,9 +315,9 @@ MatchResult RegExpObject::match(ExecState* exec, JSString* string)
RegExp* regExp = this->regExp();
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
String input = string->value(exec);
- JSGlobalData& globalData = exec->globalData();
+ VM& vm = exec->vm();
if (!regExp->global())
- return regExpConstructor->performMatch(globalData, regExp, string, input, 0);
+ return regExpConstructor->performMatch(vm, regExp, string, input, 0);
JSValue jsLastIndex = getLastIndex();
unsigned lastIndex;
@@ -335,7 +336,7 @@ MatchResult RegExpObject::match(ExecState* exec, JSString* string)
lastIndex = static_cast<unsigned>(doubleLastIndex);
}
- MatchResult result = regExpConstructor->performMatch(globalData, regExp, string, input, lastIndex);
+ MatchResult result = regExpConstructor->performMatch(vm, regExp, string, input, lastIndex);
setLastIndex(exec, result.end);
return result;
}
diff --git a/Source/JavaScriptCore/runtime/RegExpObject.h b/Source/JavaScriptCore/runtime/RegExpObject.h
index f43d6bc79..7ed3dea91 100644
--- a/Source/JavaScriptCore/runtime/RegExpObject.h
+++ b/Source/JavaScriptCore/runtime/RegExpObject.h
@@ -37,14 +37,14 @@ namespace JSC {
return object;
}
- static RegExpObject* create(JSGlobalData& globalData, JSGlobalObject* globalObject, Structure* structure, RegExp* regExp)
+ static RegExpObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, RegExp* regExp)
{
- RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(globalData.heap)) RegExpObject(globalObject, structure, regExp);
+ RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(globalObject, structure, regExp);
object->finishCreation(globalObject);
return object;
}
- void setRegExp(JSGlobalData& globalData, RegExp* r) { m_regExp.set(globalData, this, r); }
+ void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
RegExp* regExp() const { return m_regExp.get(); }
void setLastIndex(ExecState* exec, size_t lastIndex)
@@ -58,7 +58,7 @@ namespace JSC {
void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
{
if (LIKELY(m_lastIndexIsWritable))
- m_lastIndex.set(exec->globalData(), this, lastIndex);
+ m_lastIndex.set(exec->vm(), this, lastIndex);
else if (shouldThrow)
throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
@@ -76,9 +76,9 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index e4bf2cf9a..daebcbc1d 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -24,12 +24,13 @@
#include "ArrayPrototype.h"
#include "Error.h"
#include "JSArray.h"
+#include "JSCJSValue.h"
#include "JSFunction.h"
#include "JSObject.h"
#include "JSString.h"
#include "JSStringBuilder.h"
-#include "JSValue.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "RegExpObject.h"
#include "RegExp.h"
#include "RegExpCache.h"
@@ -119,13 +120,13 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
if (flags == InvalidFlags)
return throwVMError(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
}
- regExp = RegExp::create(exec->globalData(), pattern, flags);
+ regExp = RegExp::create(exec->vm(), pattern, flags);
}
if (!regExp->isValid())
return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));
- asRegExpObject(thisValue)->setRegExp(exec->globalData(), regExp);
+ asRegExpObject(thisValue)->setRegExp(exec->vm(), regExp);
asRegExpObject(thisValue)->setLastIndex(exec, 0);
return JSValue::encode(jsUndefined());
}
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.h b/Source/JavaScriptCore/runtime/RegExpPrototype.h
index 78c6ae1d4..703306be7 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.h
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.h
@@ -39,9 +39,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.cpp b/Source/JavaScriptCore/runtime/SmallStrings.cpp
index 56a359279..5f35cca5e 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/Source/JavaScriptCore/runtime/SmallStrings.cpp
@@ -29,6 +29,7 @@
#include "HeapRootVisitor.h"
#include "JSGlobalObject.h"
#include "JSString.h"
+#include "Operations.h"
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/text/StringImpl.h>
@@ -80,6 +81,22 @@ SmallStrings::SmallStrings()
m_singleCharacterStrings[i] = 0;
}
+void SmallStrings::initializeCommonStrings(VM& vm)
+{
+ createEmptyString(&vm);
+#define JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE(name) initialize(&vm, m_##name, #name);
+ JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE)
+#undef JSC_COMMON_STRINGS_ATTRIBUTE_INITIALIZE
+}
+
+void SmallStrings::visitStrongReferences(SlotVisitor& visitor)
+{
+ visitor.appendUnbarrieredPointer(&m_emptyString);
+#define JSC_COMMON_STRINGS_ATTRIBUTE_VISIT(name) visitor.appendUnbarrieredPointer(&m_##name);
+ JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_VISIT)
+#undef JSC_COMMON_STRINGS_ATTRIBUTE_VISIT
+}
+
SmallStrings::~SmallStrings()
{
}
@@ -89,23 +106,20 @@ void SmallStrings::finalizeSmallStrings()
finalize(m_emptyString);
for (unsigned i = 0; i < singleCharacterStringCount; ++i)
finalize(m_singleCharacterStrings[i]);
-#define JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE(name) finalize(m_##name);
- JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE)
-#undef JSC_COMMON_STRINGS_ATTRIBUTE_FINALIZE
}
-void SmallStrings::createEmptyString(JSGlobalData* globalData)
+void SmallStrings::createEmptyString(VM* vm)
{
ASSERT(!m_emptyString);
- m_emptyString = JSString::createHasOtherOwner(*globalData, StringImpl::empty());
+ m_emptyString = JSString::createHasOtherOwner(*vm, StringImpl::empty());
}
-void SmallStrings::createSingleCharacterString(JSGlobalData* globalData, unsigned char character)
+void SmallStrings::createSingleCharacterString(VM* vm, unsigned char character)
{
if (!m_storage)
m_storage = adoptPtr(new SmallStringsStorage);
ASSERT(!m_singleCharacterStrings[character]);
- m_singleCharacterStrings[character] = JSString::createHasOtherOwner(*globalData, PassRefPtr<StringImpl>(m_storage->rep(character)));
+ m_singleCharacterStrings[character] = JSString::createHasOtherOwner(*vm, PassRefPtr<StringImpl>(m_storage->rep(character)));
}
StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character)
@@ -115,9 +129,9 @@ StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character)
return m_storage->rep(character);
}
-void SmallStrings::initialize(JSGlobalData* globalData, JSString*& string, const char* value) const
+void SmallStrings::initialize(VM* vm, JSString*& string, const char* value) const
{
- string = JSString::create(*globalData, StringImpl::create(value));
+ string = JSString::create(*vm, StringImpl::create(value));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/SmallStrings.h b/Source/JavaScriptCore/runtime/SmallStrings.h
index 5bc9d2252..f00043021 100644
--- a/Source/JavaScriptCore/runtime/SmallStrings.h
+++ b/Source/JavaScriptCore/runtime/SmallStrings.h
@@ -26,6 +26,8 @@
#ifndef SmallStrings_h
#define SmallStrings_h
+#include "WriteBarrier.h"
+
#include <wtf/FixedArray.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -48,7 +50,7 @@ class StringImpl;
namespace JSC {
class HeapRootVisitor;
- class JSGlobalData;
+ class VM;
class JSString;
class SmallStringsStorage;
class SlotVisitor;
@@ -61,17 +63,15 @@ namespace JSC {
SmallStrings();
~SmallStrings();
- JSString* emptyString(JSGlobalData* globalData)
+ JSString* emptyString()
{
- if (!m_emptyString)
- createEmptyString(globalData);
return m_emptyString;
}
- JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
+ JSString* singleCharacterString(VM* vm, unsigned char character)
{
if (!m_singleCharacterStrings[character])
- createSingleCharacterString(globalData, character);
+ createSingleCharacterString(vm, character);
return m_singleCharacterStrings[character];
}
@@ -81,11 +81,12 @@ namespace JSC {
JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
+ void initializeCommonStrings(VM&);
+ void visitStrongReferences(SlotVisitor&);
+
#define JSC_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
- JSString* name##String(JSGlobalData* globalData) const \
+ JSString* name##String() const \
{ \
- if (!m_##name) \
- initialize(globalData, m_##name, #name); \
return m_##name; \
}
JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ACCESSOR_DEFINITION)
@@ -94,13 +95,13 @@ namespace JSC {
private:
static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
- JS_EXPORT_PRIVATE void createEmptyString(JSGlobalData*);
- JS_EXPORT_PRIVATE void createSingleCharacterString(JSGlobalData*, unsigned char);
+ JS_EXPORT_PRIVATE void createEmptyString(VM*);
+ JS_EXPORT_PRIVATE void createSingleCharacterString(VM*, unsigned char);
- void initialize(JSGlobalData* globalData, JSString*& string, const char* value) const;
+ void initialize(VM* vm, JSString*& string, const char* value) const;
JSString* m_emptyString;
-#define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) mutable JSString* m_##name;
+#define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) JSString* m_##name;
JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
#undef JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION
JSString* m_singleCharacterStrings[singleCharacterStringCount];
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
index 7f21e2c9f..1997c5b70 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
@@ -29,6 +29,7 @@
#include "ClassInfo.h"
#include "GetterSetter.h"
#include "JSObject.h"
+#include "Operations.h"
#include "PropertySlot.h"
#include "Reject.h"
#include "SlotVisitor.h"
@@ -38,8 +39,8 @@ namespace JSC {
const ClassInfo SparseArrayValueMap::s_info = { "SparseArrayValueMap", 0, 0, 0, CREATE_METHOD_TABLE(SparseArrayValueMap) };
-SparseArrayValueMap::SparseArrayValueMap(JSGlobalData& globalData)
- : Base(globalData, globalData.sparseArrayValueMapStructure.get())
+SparseArrayValueMap::SparseArrayValueMap(VM& vm)
+ : Base(vm, vm.sparseArrayValueMapStructure.get())
, m_flags(Normal)
, m_reportedCapacity(0)
{
@@ -49,15 +50,15 @@ SparseArrayValueMap::~SparseArrayValueMap()
{
}
-void SparseArrayValueMap::finishCreation(JSGlobalData& globalData)
+void SparseArrayValueMap::finishCreation(VM& vm)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
}
-SparseArrayValueMap* SparseArrayValueMap::create(JSGlobalData& globalData)
+SparseArrayValueMap* SparseArrayValueMap::create(VM& vm)
{
- SparseArrayValueMap* result = new (NotNull, allocateCell<SparseArrayValueMap>(globalData.heap)) SparseArrayValueMap(globalData);
- result->finishCreation(globalData);
+ SparseArrayValueMap* result = new (NotNull, allocateCell<SparseArrayValueMap>(vm.heap)) SparseArrayValueMap(vm);
+ result->finishCreation(vm);
return result;
}
@@ -66,9 +67,9 @@ void SparseArrayValueMap::destroy(JSCell* cell)
static_cast<SparseArrayValueMap*>(cell)->SparseArrayValueMap::~SparseArrayValueMap();
}
-Structure* SparseArrayValueMap::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+Structure* SparseArrayValueMap::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info);
}
SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigned i)
@@ -117,7 +118,7 @@ bool SparseArrayValueMap::putDirect(ExecState* exec, JSObject* array, unsigned i
}
entry.attributes = attributes;
- entry.set(exec->globalData(), this, value);
+ entry.set(exec->vm(), this, value);
return true;
}
@@ -171,7 +172,7 @@ void SparseArrayEntry::put(ExecState* exec, JSValue thisValue, SparseArrayValueM
return;
}
- set(exec->globalData(), map, value);
+ set(exec->vm(), map, value);
return;
}
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
index 366a7b8ba..31b279fa7 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
@@ -65,10 +65,10 @@ private:
LengthIsReadOnly = 2,
};
- SparseArrayValueMap(JSGlobalData&);
+ SparseArrayValueMap(VM&);
~SparseArrayValueMap();
- void finishCreation(JSGlobalData&);
+ void finishCreation(VM&);
static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
@@ -79,13 +79,13 @@ public:
typedef Map::const_iterator const_iterator;
typedef Map::AddResult AddResult;
- static SparseArrayValueMap* create(JSGlobalData&);
+ static SparseArrayValueMap* create(VM&);
static const bool needsDestruction = true;
static const bool hasImmortalStructure = true;
static void destroy(JSCell*);
- static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue prototype);
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
static void visitChildren(JSCell*, SlotVisitor&);
diff --git a/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp b/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
index b1f28c8aa..eaef9397b 100644
--- a/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
+++ b/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
@@ -27,6 +27,7 @@
#include "StrictEvalActivation.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
namespace JSC {
@@ -36,7 +37,7 @@ const ClassInfo StrictEvalActivation::s_info = { "Object", &Base::s_info, 0, 0,
StrictEvalActivation::StrictEvalActivation(ExecState* exec)
: Base(
- exec->globalData(),
+ exec->vm(),
exec->lexicalGlobalObject()->strictEvalActivationStructure(),
exec->scope()
)
diff --git a/Source/JavaScriptCore/runtime/StrictEvalActivation.h b/Source/JavaScriptCore/runtime/StrictEvalActivation.h
index 9f64feb15..df490d5e7 100644
--- a/Source/JavaScriptCore/runtime/StrictEvalActivation.h
+++ b/Source/JavaScriptCore/runtime/StrictEvalActivation.h
@@ -37,16 +37,16 @@ public:
static StrictEvalActivation* create(ExecState* exec)
{
StrictEvalActivation* activation = new (NotNull, allocateCell<StrictEvalActivation>(*exec->heap())) StrictEvalActivation(exec);
- activation->finishCreation(exec->globalData());
+ activation->finishCreation(exec->vm());
return activation;
}
static bool deleteProperty(JSCell*, ExecState*, PropertyName);
static JSObject* toThisObject(JSCell*, ExecState*);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp
index 7f36a84be..df507ce07 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp
@@ -25,6 +25,7 @@
#include "JITCode.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
#include "StringPrototype.h"
namespace JSC {
@@ -54,9 +55,9 @@ StringConstructor::StringConstructor(JSGlobalObject* globalObject, Structure* st
void StringConstructor::finishCreation(ExecState* exec, StringPrototype* stringPrototype)
{
- Base::finishCreation(exec->globalData(), stringPrototype->classInfo()->className);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
+ Base::finishCreation(exec->vm(), stringPrototype->classInfo()->className);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
}
bool StringConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
@@ -88,6 +89,11 @@ static EncodedJSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec)
return JSValue::encode(stringFromCharCodeSlowCase(exec));
}
+JSCell* JSC_HOST_CALL stringFromCharCode(ExecState* exec, int32_t arg)
+{
+ return jsSingleCharacterString(exec, arg);
+}
+
static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec)
{
JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
diff --git a/Source/JavaScriptCore/runtime/StringConstructor.h b/Source/JavaScriptCore/runtime/StringConstructor.h
index 11f70d499..40e574c02 100644
--- a/Source/JavaScriptCore/runtime/StringConstructor.h
+++ b/Source/JavaScriptCore/runtime/StringConstructor.h
@@ -40,9 +40,9 @@ namespace JSC {
static const ClassInfo s_info;
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
@@ -57,6 +57,8 @@ namespace JSC {
static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
};
+
+ JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp
index ab7d6cb23..bdbe27fe6 100644
--- a/Source/JavaScriptCore/runtime/StringObject.cpp
+++ b/Source/JavaScriptCore/runtime/StringObject.cpp
@@ -23,6 +23,7 @@
#include "Error.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
namespace JSC {
@@ -31,16 +32,16 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject);
const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) };
-StringObject::StringObject(JSGlobalData& globalData, Structure* structure)
- : JSWrapperObject(globalData, structure)
+StringObject::StringObject(VM& vm, Structure* structure)
+ : JSWrapperObject(vm, structure)
{
}
-void StringObject::finishCreation(JSGlobalData& globalData, JSString* string)
+void StringObject::finishCreation(VM& vm, JSString* string)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
ASSERT(inherits(&s_info));
- setInternalValue(globalData, string);
+ setInternalValue(vm, string);
}
bool StringObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -165,7 +166,7 @@ void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Proper
StringObject* constructString(ExecState* exec, JSGlobalObject* globalObject, JSValue string)
{
StringObject* object = StringObject::create(exec, globalObject->stringObjectStructure());
- object->setInternalValue(exec->globalData(), string);
+ object->setInternalValue(exec->vm(), string);
return object;
}
diff --git a/Source/JavaScriptCore/runtime/StringObject.h b/Source/JavaScriptCore/runtime/StringObject.h
index 4369eace1..6a92541c1 100644
--- a/Source/JavaScriptCore/runtime/StringObject.h
+++ b/Source/JavaScriptCore/runtime/StringObject.h
@@ -33,14 +33,14 @@ namespace JSC {
static StringObject* create(ExecState* exec, Structure* structure)
{
JSString* string = jsEmptyString(exec);
- StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->globalData(), structure);
- object->finishCreation(exec->globalData(), string);
+ StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->vm(), structure);
+ object->finishCreation(exec->vm(), string);
return object;
}
static StringObject* create(ExecState* exec, Structure* structure, JSString* string)
{
- StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->globalData(), structure);
- object->finishCreation(exec->globalData(), string);
+ StringObject* object = new (NotNull, allocateCell<StringObject>(*exec->heap())) StringObject(exec->vm(), structure);
+ object->finishCreation(exec->vm(), string);
return object;
}
static StringObject* create(ExecState*, JSGlobalObject*, JSString*);
@@ -61,15 +61,15 @@ namespace JSC {
JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
protected:
- JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, JSString*);
+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*);
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
- JS_EXPORT_PRIVATE StringObject(JSGlobalData&, Structure*);
+ JS_EXPORT_PRIVATE StringObject(VM&, Structure*);
};
StringObject* asStringObject(JSValue);
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index 25f989776..c422fd17b 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2009 Torch Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -82,80 +82,67 @@ static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*);
static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*);
static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*);
-}
-
-#include "StringPrototype.lut.h"
-
-namespace JSC {
-
-const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0, ExecState::stringTable, CREATE_METHOD_TABLE(StringPrototype) };
-
-/* Source for StringPrototype.lut.h
-@begin stringTable 26
- toString stringProtoFuncToString DontEnum|Function 0
- valueOf stringProtoFuncToString DontEnum|Function 0
- charAt stringProtoFuncCharAt DontEnum|Function 1
- charCodeAt stringProtoFuncCharCodeAt DontEnum|Function 1
- concat stringProtoFuncConcat DontEnum|Function 1
- indexOf stringProtoFuncIndexOf DontEnum|Function 1
- lastIndexOf stringProtoFuncLastIndexOf DontEnum|Function 1
- match stringProtoFuncMatch DontEnum|Function 1
- replace stringProtoFuncReplace DontEnum|Function 2
- search stringProtoFuncSearch DontEnum|Function 1
- slice stringProtoFuncSlice DontEnum|Function 2
- split stringProtoFuncSplit DontEnum|Function 2
- substr stringProtoFuncSubstr DontEnum|Function 2
- substring stringProtoFuncSubstring DontEnum|Function 2
- toLowerCase stringProtoFuncToLowerCase DontEnum|Function 0
- toUpperCase stringProtoFuncToUpperCase DontEnum|Function 0
- localeCompare stringProtoFuncLocaleCompare DontEnum|Function 1
-
- # toLocaleLowerCase and toLocaleUpperCase are currently identical to toLowerCase and toUpperCase
- toLocaleLowerCase stringProtoFuncToLowerCase DontEnum|Function 0
- toLocaleUpperCase stringProtoFuncToUpperCase DontEnum|Function 0
-
- big stringProtoFuncBig DontEnum|Function 0
- small stringProtoFuncSmall DontEnum|Function 0
- blink stringProtoFuncBlink DontEnum|Function 0
- bold stringProtoFuncBold DontEnum|Function 0
- fixed stringProtoFuncFixed DontEnum|Function 0
- italics stringProtoFuncItalics DontEnum|Function 0
- strike stringProtoFuncStrike DontEnum|Function 0
- sub stringProtoFuncSub DontEnum|Function 0
- sup stringProtoFuncSup DontEnum|Function 0
- fontcolor stringProtoFuncFontcolor DontEnum|Function 1
- fontsize stringProtoFuncFontsize DontEnum|Function 1
- anchor stringProtoFuncAnchor DontEnum|Function 1
- link stringProtoFuncLink DontEnum|Function 1
- trim stringProtoFuncTrim DontEnum|Function 0
- trimLeft stringProtoFuncTrimLeft DontEnum|Function 0
- trimRight stringProtoFuncTrimRight DontEnum|Function 0
-@end
-*/
+const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringPrototype) };
// ECMA 15.5.4
StringPrototype::StringPrototype(ExecState* exec, Structure* structure)
- : StringObject(exec->globalData(), structure)
+ : StringObject(exec->vm(), structure)
{
}
-void StringPrototype::finishCreation(ExecState* exec, JSGlobalObject*, JSString* nameAndMessage)
+void StringPrototype::finishCreation(ExecState* exec, JSGlobalObject* globalObject, JSString* nameAndMessage)
{
- Base::finishCreation(exec->globalData(), nameAndMessage);
+ VM& vm = exec->vm();
+
+ Base::finishCreation(vm, nameAndMessage);
ASSERT(inherits(&s_info));
- // The constructor will be added later, after StringConstructor has been built
- putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
-}
+ JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->toString, stringProtoFuncToString, DontEnum, 0, StringPrototypeValueOfIntrinsic);
+ JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->valueOf, stringProtoFuncToString, DontEnum, 0, StringPrototypeValueOfIntrinsic);
+ JSC_NATIVE_INTRINSIC_FUNCTION("charAt", stringProtoFuncCharAt, DontEnum, 1, CharAtIntrinsic);
+ JSC_NATIVE_INTRINSIC_FUNCTION("charCodeAt", stringProtoFuncCharCodeAt, DontEnum, 1, CharCodeAtIntrinsic);
+ JSC_NATIVE_FUNCTION("concat", stringProtoFuncConcat, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("indexOf", stringProtoFuncIndexOf, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("lastIndexOf", stringProtoFuncLastIndexOf, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("match", stringProtoFuncMatch, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("replace", stringProtoFuncReplace, DontEnum, 2);
+ JSC_NATIVE_FUNCTION("search", stringProtoFuncSearch, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("slice", stringProtoFuncSlice, DontEnum, 2);
+ JSC_NATIVE_FUNCTION("split", stringProtoFuncSplit, DontEnum, 2);
+ JSC_NATIVE_FUNCTION("substr", stringProtoFuncSubstr, DontEnum, 2);
+ JSC_NATIVE_FUNCTION("substring", stringProtoFuncSubstring, DontEnum, 2);
+ JSC_NATIVE_FUNCTION("toLowerCase", stringProtoFuncToLowerCase, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("toUpperCase", stringProtoFuncToUpperCase, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("localeCompare", stringProtoFuncLocaleCompare, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("toLocaleLowerCase", stringProtoFuncToLowerCase, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("toLocaleUpperCase", stringProtoFuncToUpperCase, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("big", stringProtoFuncBig, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("small", stringProtoFuncSmall, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("blink", stringProtoFuncBlink, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("bold", stringProtoFuncBold, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("fixed", stringProtoFuncFixed, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("italics", stringProtoFuncItalics, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("strike", stringProtoFuncStrike, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("sub", stringProtoFuncSub, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("sup", stringProtoFuncSup, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("fontcolor", stringProtoFuncFontcolor, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("fontsize", stringProtoFuncFontsize, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("anchor", stringProtoFuncAnchor, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("link", stringProtoFuncLink, DontEnum, 1);
+ JSC_NATIVE_FUNCTION("trim", stringProtoFuncTrim, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("trimLeft", stringProtoFuncTrimLeft, DontEnum, 0);
+ JSC_NATIVE_FUNCTION("trimRight", stringProtoFuncTrimRight, DontEnum, 0);
-bool StringPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
-{
- return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), jsCast<StringPrototype*>(cell), propertyName, slot);
+ // The constructor will be added later, after StringConstructor has been built
+ putDirectWithoutTransition(exec->vm(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
}
-bool StringPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
+StringPrototype* StringPrototype::create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
{
- return getStaticFunctionDescriptor<StringObject>(exec, ExecState::stringTable(exec), jsCast<StringPrototype*>(object), propertyName, descriptor);
+ JSString* empty = jsEmptyString(exec);
+ StringPrototype* prototype = new (NotNull, allocateCell<StringPrototype>(*exec->heap())) StringPrototype(exec, structure);
+ prototype->finishCreation(exec, globalObject, empty);
+ return prototype;
}
// ------------------------------ Functions --------------------------
@@ -418,12 +405,12 @@ static NEVER_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSSt
unsigned startPosition = 0;
Vector<StringRange, 16> sourceRanges;
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
unsigned sourceLen = source.length();
while (true) {
- MatchResult result = regExpConstructor->performMatch(*globalData, regExp, string, source, startPosition);
+ MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition);
if (!result)
break;
@@ -493,11 +480,11 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
CachedCall cachedCall(exec, func, argCount);
if (exec->hadException())
return JSValue::encode(jsNull());
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
if (source.is8Bit()) {
while (true) {
int* ovector;
- MatchResult result = regExpConstructor->performMatch(*globalData, regExp, string, source, startPosition, &ovector);
+ MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition, &ovector);
if (!result)
break;
@@ -511,7 +498,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
if (matchStart < 0)
cachedCall.setArgument(i, jsUndefined());
else
- cachedCall.setArgument(i, jsSubstring8(globalData, source, matchStart, matchLen));
+ cachedCall.setArgument(i, jsSubstring8(vm, source, matchStart, matchLen));
}
cachedCall.setArgument(i++, jsNumber(result.start));
@@ -536,7 +523,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
} else {
while (true) {
int* ovector;
- MatchResult result = regExpConstructor->performMatch(*globalData, regExp, string, source, startPosition, &ovector);
+ MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition, &ovector);
if (!result)
break;
@@ -550,7 +537,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
if (matchStart < 0)
cachedCall.setArgument(i, jsUndefined());
else
- cachedCall.setArgument(i, jsSubstring(globalData, source, matchStart, matchLen));
+ cachedCall.setArgument(i, jsSubstring(vm, source, matchStart, matchLen));
}
cachedCall.setArgument(i++, jsNumber(result.start));
@@ -574,10 +561,10 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS
}
}
} else {
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
do {
int* ovector;
- MatchResult result = regExpConstructor->performMatch(*globalData, regExp, string, source, startPosition, &ovector);
+ MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition, &ovector);
if (!result)
break;
@@ -810,7 +797,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec)
else if (!(dpos <= len)) // true for NaN
dpos = len;
- size_t result = s.reverseFind(u2, static_cast<unsigned>(dpos));
+ size_t result;
+ unsigned startPosition = static_cast<unsigned>(dpos);
+ if (!startPosition)
+ result = s.startsWith(u2) ? 0 : notFound;
+ else
+ result = s.reverseFind(u2, startPosition);
if (result == notFound)
return JSValue::encode(jsNumber(-1));
return JSValue::encode(jsNumber(result));
@@ -823,7 +815,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
return throwVMTypeError(exec);
JSString* string = thisValue.toString(exec);
String s = string->value(exec);
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
JSValue a0 = exec->argument(0);
@@ -845,12 +837,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
* replaced with the result of the expression new RegExp(regexp).
* Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
*/
- regExp = RegExp::create(exec->globalData(), a0.isUndefined() ? String("") : a0.toString(exec)->value(exec), NoFlags);
+ regExp = RegExp::create(exec->vm(), a0.isUndefined() ? String("") : a0.toString(exec)->value(exec), NoFlags);
if (!regExp->isValid())
return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
- MatchResult result = regExpConstructor->performMatch(*globalData, regExp, string, s, 0);
+ MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, 0);
// case without 'g' flag is handled like RegExp.prototype.exec
if (!global)
return JSValue::encode(result ? RegExpMatchesArray::create(exec, string, regExp, result) : jsNull());
@@ -863,7 +855,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec)
list.append(jsSubstring(exec, s, result.start, length));
if (!length)
++end;
- result = regExpConstructor->performMatch(*globalData, regExp, string, s, end);
+ result = regExpConstructor->performMatch(*vm, regExp, string, s, end);
}
if (list.isEmpty()) {
// if there are no matches at all, it's important to return
@@ -882,7 +874,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
return throwVMTypeError(exec);
JSString* string = thisValue.toString(exec);
String s = string->value(exec);
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
JSValue a0 = exec->argument(0);
@@ -896,12 +888,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec)
* replaced with the result of the expression new RegExp(regexp).
* Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string.
*/
- reg = RegExp::create(exec->globalData(), a0.isUndefined() ? String("") : a0.toString(exec)->value(exec), NoFlags);
+ reg = RegExp::create(exec->vm(), a0.isUndefined() ? String("") : a0.toString(exec)->value(exec), NoFlags);
if (!reg->isValid())
return throwVMError(exec, createSyntaxError(exec, reg->errorMessage()));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
- MatchResult result = regExpConstructor->performMatch(*globalData, reg, string, s, 0);
+ MatchResult result = regExpConstructor->performMatch(*vm, reg, string, s, 0);
return JSValue::encode(result ? jsNumber(result.start) : jsNumber(-1));
}
@@ -991,7 +983,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
// otherwise let R = ToString(separator).
JSValue separatorValue = exec->argument(0);
if (separatorValue.inherits(&RegExpObject::s_info)) {
- JSGlobalData* globalData = &exec->globalData();
+ VM* vm = &exec->vm();
RegExp* reg = asRegExpObject(separatorValue)->regExp();
// 9. If lim == 0, return A.
@@ -1014,7 +1006,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
// c. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
// Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
// d. Return A.
- if (!reg->match(*globalData, input, 0))
+ if (!reg->match(*vm, input, 0))
result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
return JSValue::encode(result);
}
@@ -1025,7 +1017,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
while (matchPosition < input.length()) {
// a. Call SplitMatch(S, q, R) and let z be its MatchResult result.
Vector<int, 32> ovector;
- int mpos = reg->match(*globalData, input, matchPosition, ovector);
+ int mpos = reg->match(*vm, input, matchPosition, ovector);
// b. If z is failure, then let q = q + 1.
if (mpos < 0)
break;
@@ -1290,9 +1282,6 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec)
EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec)
{
- if (exec->argumentCount() < 1)
- return JSValue::encode(jsNumber(0));
-
JSValue thisValue = exec->hostThisValue();
if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible
return throwVMTypeError(exec);
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.h b/Source/JavaScriptCore/runtime/StringPrototype.h
index b846c7bb3..a7aca4c3e 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.h
+++ b/Source/JavaScriptCore/runtime/StringPrototype.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2013 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
@@ -34,27 +34,18 @@ namespace JSC {
public:
typedef StringObject Base;
- static StringPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
- {
- JSString* empty = jsEmptyString(exec);
- StringPrototype* prototype = new (NotNull, allocateCell<StringPrototype>(*exec->heap())) StringPrototype(exec, structure);
- prototype->finishCreation(exec, globalObject, empty);
- return prototype;
- }
-
- static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&);
- static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&);
+ static StringPrototype* create(ExecState*, JSGlobalObject*, Structure*);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
static const ClassInfo s_info;
protected:
void finishCreation(ExecState*, JSGlobalObject*, JSString*);
- static const unsigned StructureFlags = OverridesGetOwnPropertySlot | StringObject::StructureFlags;
+ static const unsigned StructureFlags = StringObject::StructureFlags;
};
diff --git a/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp b/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp
index 22b7367bc..8835a5c1c 100644
--- a/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp
+++ b/Source/JavaScriptCore/runtime/StringRecursionChecker.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 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
@@ -22,6 +22,7 @@
#include "Error.h"
#include "ExceptionHelpers.h"
+#include "Operations.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/StringRecursionChecker.h b/Source/JavaScriptCore/runtime/StringRecursionChecker.h
index a1b4a51fe..6f236f1f1 100644
--- a/Source/JavaScriptCore/runtime/StringRecursionChecker.h
+++ b/Source/JavaScriptCore/runtime/StringRecursionChecker.h
@@ -21,6 +21,7 @@
#define StringRecursionChecker_h
#include "Interpreter.h"
+#include "VMStackBounds.h"
#include <wtf/StackStats.h>
#include <wtf/WTFThreadData.h>
@@ -49,10 +50,11 @@ private:
inline JSValue StringRecursionChecker::performCheck()
{
- const StackBounds& nativeStack = wtfThreadData().stack();
+ VM& vm = m_exec->vm();
+ const VMStackBounds nativeStack(vm, wtfThreadData().stack());
if (!nativeStack.isSafeToRecurse())
return throwStackOverflowError();
- bool alreadyVisited = !m_exec->globalData().stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
+ bool alreadyVisited = !vm.stringRecursionCheckVisitedObjects.add(m_thisObject).isNewEntry;
if (alreadyVisited)
return emptyString(); // Return empty string to avoid infinite recursion.
return JSValue(); // Indicate success.
@@ -74,8 +76,8 @@ inline StringRecursionChecker::~StringRecursionChecker()
{
if (m_earlyReturnValue)
return;
- ASSERT(m_exec->globalData().stringRecursionCheckVisitedObjects.contains(m_thisObject));
- m_exec->globalData().stringRecursionCheckVisitedObjects.remove(m_thisObject);
+ ASSERT(m_exec->vm().stringRecursionCheckVisitedObjects.contains(m_thisObject));
+ m_exec->vm().stringRecursionCheckVisitedObjects.remove(m_thisObject);
}
}
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index 9ffe3b060..f551eaecc 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,11 +26,13 @@
#include "config.h"
#include "Structure.h"
+#include "CodeBlock.h"
#include "JSObject.h"
#include "JSPropertyNameIterator.h"
#include "Lookup.h"
#include "PropertyNameArray.h"
#include "StructureChain.h"
+#include "StructureRareDataInlines.h"
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/RefPtr.h>
#include <wtf/Threading.h>
@@ -79,21 +81,21 @@ inline Structure* StructureTransitionTable::get(StringImpl* rep, unsigned attrib
return map()->get(make_pair(rep, attributes));
}
-inline void StructureTransitionTable::add(JSGlobalData& globalData, Structure* structure)
+inline void StructureTransitionTable::add(VM& vm, Structure* structure)
{
if (isUsingSingleSlot()) {
Structure* existingTransition = singleTransition();
// This handles the first transition being added.
if (!existingTransition) {
- setSingleTransition(globalData, structure);
+ setSingleTransition(vm, structure);
return;
}
// This handles the second transition being added
// (or the first transition being despecified!)
setMap(new TransitionMap());
- add(globalData, existingTransition);
+ add(vm, existingTransition);
}
// Add the structure to the map.
@@ -101,7 +103,7 @@ inline void StructureTransitionTable::add(JSGlobalData& globalData, Structure* s
// Newer versions of the STL have an std::make_pair function that takes rvalue references.
// When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
// See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details
- map()->set(globalData, make_pair(structure->m_nameInPrevious, +structure->m_attributesInPrevious), structure);
+ map()->set(make_pair(structure->m_nameInPrevious, +structure->m_attributesInPrevious), structure);
}
void Structure::dumpStatistics()
@@ -120,7 +122,7 @@ void Structure::dumpStatistics()
switch (structure->m_transitionTable.size()) {
case 0:
++numberLeaf;
- if (!structure->m_previous)
+ if (!structure->previousID())
++numberSingletons;
break;
@@ -129,9 +131,9 @@ void Structure::dumpStatistics()
break;
}
- if (structure->m_propertyTable) {
+ if (structure->propertyTable()) {
++numberWithPropertyMaps;
- totalPropertyMapsSize += structure->m_propertyTable->sizeInMemory();
+ totalPropertyMapsSize += structure->propertyTable()->sizeInMemory();
}
}
@@ -149,17 +151,16 @@ void Structure::dumpStatistics()
#endif
}
-Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, PropertyOffset inlineCapacity)
- : JSCell(globalData, globalData.structureStructure.get())
- , m_typeInfo(typeInfo)
- , m_indexingType(indexingType)
- , m_globalObject(globalData, this, globalObject, WriteBarrier<JSGlobalObject>::MayBeNull)
- , m_prototype(globalData, this, prototype)
+Structure::Structure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity)
+ : JSCell(vm, vm.structureStructure.get())
+ , m_globalObject(vm, this, globalObject, WriteBarrier<JSGlobalObject>::MayBeNull)
+ , m_prototype(vm, this, prototype)
, m_classInfo(classInfo)
, m_transitionWatchpointSet(InitializedWatching)
- , m_outOfLineCapacity(0)
- , m_inlineCapacity(inlineCapacity)
, m_offset(invalidOffset)
+ , m_typeInfo(typeInfo)
+ , m_indexingType(indexingType)
+ , m_inlineCapacity(inlineCapacity)
, m_dictionaryKind(NoneDictionaryKind)
, m_isPinnedPropertyTable(false)
, m_hasGetterSetterProperties(false)
@@ -171,20 +172,22 @@ Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSV
, m_didTransition(false)
, m_staticFunctionReified(false)
{
+ ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
+ ASSERT(static_cast<PropertyOffset>(inlineCapacity) < firstOutOfLineOffset);
+ ASSERT(!typeInfo.structureHasRareData());
}
const ClassInfo Structure::s_info = { "Structure", 0, 0, 0, CREATE_METHOD_TABLE(Structure) };
-Structure::Structure(JSGlobalData& globalData)
+Structure::Structure(VM& vm)
: JSCell(CreatingEarlyCell)
- , m_typeInfo(CompoundType, OverridesVisitChildren)
- , m_indexingType(0)
- , m_prototype(globalData, this, jsNull())
+ , m_prototype(vm, this, jsNull())
, m_classInfo(&s_info)
, m_transitionWatchpointSet(InitializedWatching)
- , m_outOfLineCapacity(0)
- , m_inlineCapacity(0)
, m_offset(invalidOffset)
+ , m_typeInfo(CompoundType, OverridesVisitChildren)
+ , m_indexingType(0)
+ , m_inlineCapacity(0)
, m_dictionaryKind(NoneDictionaryKind)
, m_isPinnedPropertyTable(false)
, m_hasGetterSetterProperties(false)
@@ -198,16 +201,15 @@ Structure::Structure(JSGlobalData& globalData)
{
}
-Structure::Structure(JSGlobalData& globalData, const Structure* previous)
- : JSCell(globalData, globalData.structureStructure.get())
- , m_typeInfo(previous->typeInfo())
- , m_indexingType(previous->indexingTypeIncludingHistory())
- , m_prototype(globalData, this, previous->storedPrototype())
+Structure::Structure(VM& vm, const Structure* previous)
+ : JSCell(vm, vm.structureStructure.get())
+ , m_prototype(vm, this, previous->storedPrototype())
, m_classInfo(previous->m_classInfo)
, m_transitionWatchpointSet(InitializedWatching)
- , m_outOfLineCapacity(previous->m_outOfLineCapacity)
- , m_inlineCapacity(previous->m_inlineCapacity)
, m_offset(invalidOffset)
+ , m_typeInfo(previous->typeInfo().type(), previous->typeInfo().flags() & ~StructureHasRareData)
+ , m_indexingType(previous->indexingTypeIncludingHistory())
+ , m_inlineCapacity(previous->m_inlineCapacity)
, m_dictionaryKind(previous->m_dictionaryKind)
, m_isPinnedPropertyTable(false)
, m_hasGetterSetterProperties(previous->m_hasGetterSetterProperties)
@@ -219,9 +221,14 @@ Structure::Structure(JSGlobalData& globalData, const Structure* previous)
, m_didTransition(true)
, m_staticFunctionReified(previous->m_staticFunctionReified)
{
+ if (previous->typeInfo().structureHasRareData() && previous->rareData()->needsCloning())
+ cloneRareDataFrom(vm, previous);
+ else if (previous->previousID())
+ m_previousOrRareData.set(vm, this, previous->previousID());
+
previous->notifyTransitionFromThisStructure();
if (previous->m_globalObject)
- m_globalObject.set(globalData, this, previous->m_globalObject.get());
+ m_globalObject.set(vm, this, previous->m_globalObject.get());
}
void Structure::destroy(JSCell* cell)
@@ -229,10 +236,10 @@ void Structure::destroy(JSCell* cell)
static_cast<Structure*>(cell)->Structure::~Structure();
}
-void Structure::materializePropertyMap(JSGlobalData& globalData)
+void Structure::materializePropertyMap(VM& vm)
{
ASSERT(structure()->classInfo() == &s_info);
- ASSERT(!m_propertyTable);
+ ASSERT(!propertyTable());
Vector<Structure*, 8> structures;
structures.append(this);
@@ -242,26 +249,28 @@ void Structure::materializePropertyMap(JSGlobalData& globalData)
// Search for the last Structure with a property table.
while ((structure = structure->previousID())) {
if (structure->m_isPinnedPropertyTable) {
- ASSERT(structure->m_propertyTable);
- ASSERT(!structure->m_previous);
+ ASSERT(structure->propertyTable());
+ ASSERT(!structure->previousID());
- m_propertyTable = structure->m_propertyTable->copy(globalData, 0, numberOfSlotsForLastOffset(m_offset, m_typeInfo.type()));
+ propertyTable().set(vm, this, structure->propertyTable()->copy(vm, 0, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)));
break;
}
structures.append(structure);
}
- if (!m_propertyTable)
- createPropertyMap(numberOfSlotsForLastOffset(m_offset, m_typeInfo.type()));
+ if (!propertyTable())
+ createPropertyMap(vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
- for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
+ for (ptrdiff_t i = structures.size() - 1; i >= 0; --i) {
structure = structures[i];
if (!structure->m_nameInPrevious)
continue;
- PropertyMapEntry entry(globalData, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get());
- m_propertyTable->add(entry);
+ PropertyMapEntry entry(vm, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get());
+ propertyTable()->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
}
+
+ checkOffsetConsistency();
}
inline size_t nextOutOfLineStorageCapacity(size_t currentCapacity)
@@ -271,26 +280,21 @@ inline size_t nextOutOfLineStorageCapacity(size_t currentCapacity)
return currentCapacity * outOfLineGrowthFactor;
}
-void Structure::growOutOfLineCapacity()
-{
- m_outOfLineCapacity = nextOutOfLineStorageCapacity(m_outOfLineCapacity);
-}
-
size_t Structure::suggestedNewOutOfLineStorageCapacity()
{
- return nextOutOfLineStorageCapacity(m_outOfLineCapacity);
+ return nextOutOfLineStorageCapacity(outOfLineCapacity());
}
-void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyName propertyName)
+void Structure::despecifyDictionaryFunction(VM& vm, PropertyName propertyName)
{
StringImpl* rep = propertyName.uid();
- materializePropertyMapIfNecessary(globalData);
+ materializePropertyMapIfNecessary(vm);
ASSERT(isDictionary());
- ASSERT(m_propertyTable);
+ ASSERT(propertyTable());
- PropertyMapEntry* entry = m_propertyTable->find(rep).first;
+ PropertyMapEntry* entry = propertyTable()->find(rep).first;
ASSERT(entry);
entry->specificValue.clear();
}
@@ -304,7 +308,7 @@ Structure* Structure::addPropertyTransitionToExistingStructure(Structure* struct
JSCell* specificValueInPrevious = existingTransition->m_specificValueInPrevious.get();
if (specificValueInPrevious && specificValueInPrevious != specificValue)
return 0;
- validateOffset(existingTransition->m_offset, structure->m_typeInfo.type());
+ validateOffset(existingTransition->m_offset, existingTransition->inlineCapacity());
offset = existingTransition->m_offset;
return existingTransition;
}
@@ -340,7 +344,7 @@ NonPropertyTransition Structure::suggestedArrayStorageTransition() const
return AllocateArrayStorage;
}
-Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
+Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes, JSCell* specificValue, PropertyOffset& offset)
{
// If we have a specific function, we may have got to this point if there is
// already a transition with the correct property name and attributes, but
@@ -360,185 +364,190 @@ Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure*
specificValue = 0;
if (structure->transitionCount() > s_maxTransitionLength) {
- Structure* transition = toCacheableDictionaryTransition(globalData, structure);
+ Structure* transition = toCacheableDictionaryTransition(vm, structure);
ASSERT(structure != transition);
- offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue);
- if (transition->outOfLineSize() > transition->outOfLineCapacity())
- transition->growOutOfLineCapacity();
+ offset = transition->putSpecificValue(vm, propertyName, attributes, specificValue);
return transition;
}
- Structure* transition = create(globalData, structure);
+ Structure* transition = create(vm, structure);
- transition->m_cachedPrototypeChain.setMayBeNull(globalData, transition, structure->m_cachedPrototypeChain.get());
- transition->m_previous.set(globalData, transition, structure);
+ transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
+ transition->setPreviousID(vm, transition, structure);
transition->m_nameInPrevious = propertyName.uid();
transition->m_attributesInPrevious = attributes;
- transition->m_specificValueInPrevious.setMayBeNull(globalData, transition, specificValue);
-
- if (structure->m_propertyTable) {
- if (structure->m_isPinnedPropertyTable)
- transition->m_propertyTable = structure->m_propertyTable->copy(globalData, transition, structure->m_propertyTable->size() + 1);
- else
- transition->m_propertyTable = structure->m_propertyTable.release();
- } else {
- if (structure->m_previous)
- transition->materializePropertyMap(globalData);
- else
- transition->createPropertyMap();
- }
+ transition->m_specificValueInPrevious.setMayBeNull(vm, transition, specificValue);
+ transition->propertyTable().set(vm, transition, structure->takePropertyTableOrCloneIfPinned(vm, transition));
+ transition->m_offset = structure->m_offset;
- offset = transition->putSpecificValue(globalData, propertyName, attributes, specificValue);
- if (transition->outOfLineSize() > transition->outOfLineCapacity())
- transition->growOutOfLineCapacity();
+ offset = transition->putSpecificValue(vm, propertyName, attributes, specificValue);
- transition->m_offset = offset;
- structure->m_transitionTable.add(globalData, transition);
+ checkOffset(transition->m_offset, transition->inlineCapacity());
+ structure->m_transitionTable.add(vm, transition);
+ transition->checkOffsetConsistency();
+ structure->checkOffsetConsistency();
return transition;
}
-Structure* Structure::removePropertyTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, PropertyOffset& offset)
+Structure* Structure::removePropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, PropertyOffset& offset)
{
ASSERT(!structure->isUncacheableDictionary());
- Structure* transition = toUncacheableDictionaryTransition(globalData, structure);
+ Structure* transition = toUncacheableDictionaryTransition(vm, structure);
offset = transition->remove(propertyName);
+ transition->checkOffsetConsistency();
return transition;
}
-Structure* Structure::changePrototypeTransition(JSGlobalData& globalData, Structure* structure, JSValue prototype)
+Structure* Structure::changePrototypeTransition(VM& vm, Structure* structure, JSValue prototype)
{
- Structure* transition = create(globalData, structure);
+ Structure* transition = create(vm, structure);
- transition->m_prototype.set(globalData, transition, prototype);
+ transition->m_prototype.set(vm, transition, prototype);
- // Don't set m_offset, as one can not transition to this.
-
- structure->materializePropertyMapIfNecessary(globalData);
- transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
+ structure->materializePropertyMapIfNecessary(vm);
+ transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
+ transition->m_offset = structure->m_offset;
transition->pin();
+ transition->checkOffsetConsistency();
return transition;
}
-Structure* Structure::despecifyFunctionTransition(JSGlobalData& globalData, Structure* structure, PropertyName replaceFunction)
+Structure* Structure::despecifyFunctionTransition(VM& vm, Structure* structure, PropertyName replaceFunction)
{
ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
- Structure* transition = create(globalData, structure);
+ Structure* transition = create(vm, structure);
++transition->m_specificFunctionThrashCount;
- // Don't set m_offset, as one can not transition to this.
-
- structure->materializePropertyMapIfNecessary(globalData);
- transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
+ structure->materializePropertyMapIfNecessary(vm);
+ transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
+ transition->m_offset = structure->m_offset;
transition->pin();
if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
- transition->despecifyAllFunctions(globalData);
+ transition->despecifyAllFunctions(vm);
else {
- bool removed = transition->despecifyFunction(globalData, replaceFunction);
+ bool removed = transition->despecifyFunction(vm, replaceFunction);
ASSERT_UNUSED(removed, removed);
}
+ transition->checkOffsetConsistency();
return transition;
}
-Structure* Structure::attributeChangeTransition(JSGlobalData& globalData, Structure* structure, PropertyName propertyName, unsigned attributes)
+Structure* Structure::attributeChangeTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes)
{
if (!structure->isUncacheableDictionary()) {
- Structure* transition = create(globalData, structure);
-
- // Don't set m_offset, as one can not transition to this.
+ Structure* transition = create(vm, structure);
- structure->materializePropertyMapIfNecessary(globalData);
- transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
+ structure->materializePropertyMapIfNecessary(vm);
+ transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
+ transition->m_offset = structure->m_offset;
transition->pin();
structure = transition;
}
- ASSERT(structure->m_propertyTable);
- PropertyMapEntry* entry = structure->m_propertyTable->find(propertyName.uid()).first;
+ ASSERT(structure->propertyTable());
+ PropertyMapEntry* entry = structure->propertyTable()->find(propertyName.uid()).first;
ASSERT(entry);
entry->attributes = attributes;
+ structure->checkOffsetConsistency();
return structure;
}
-Structure* Structure::toDictionaryTransition(JSGlobalData& globalData, Structure* structure, DictionaryKind kind)
+Structure* Structure::toDictionaryTransition(VM& vm, Structure* structure, DictionaryKind kind)
{
ASSERT(!structure->isUncacheableDictionary());
- Structure* transition = create(globalData, structure);
+ Structure* transition = create(vm, structure);
- structure->materializePropertyMapIfNecessary(globalData);
- transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
+ structure->materializePropertyMapIfNecessary(vm);
+ transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
+ transition->m_offset = structure->m_offset;
transition->m_dictionaryKind = kind;
transition->pin();
+ transition->checkOffsetConsistency();
return transition;
}
-Structure* Structure::toCacheableDictionaryTransition(JSGlobalData& globalData, Structure* structure)
+Structure* Structure::toCacheableDictionaryTransition(VM& vm, Structure* structure)
{
- return toDictionaryTransition(globalData, structure, CachedDictionaryKind);
+ return toDictionaryTransition(vm, structure, CachedDictionaryKind);
}
-Structure* Structure::toUncacheableDictionaryTransition(JSGlobalData& globalData, Structure* structure)
+Structure* Structure::toUncacheableDictionaryTransition(VM& vm, Structure* structure)
{
- return toDictionaryTransition(globalData, structure, UncachedDictionaryKind);
+ return toDictionaryTransition(vm, structure, UncachedDictionaryKind);
}
// In future we may want to cache this transition.
-Structure* Structure::sealTransition(JSGlobalData& globalData, Structure* structure)
+Structure* Structure::sealTransition(VM& vm, Structure* structure)
{
- Structure* transition = preventExtensionsTransition(globalData, structure);
+ Structure* transition = preventExtensionsTransition(vm, structure);
- if (transition->m_propertyTable) {
- PropertyTable::iterator end = transition->m_propertyTable->end();
- for (PropertyTable::iterator iter = transition->m_propertyTable->begin(); iter != end; ++iter)
+ if (transition->propertyTable()) {
+ PropertyTable::iterator end = transition->propertyTable()->end();
+ for (PropertyTable::iterator iter = transition->propertyTable()->begin(); iter != end; ++iter)
iter->attributes |= DontDelete;
}
+ transition->checkOffsetConsistency();
return transition;
}
// In future we may want to cache this transition.
-Structure* Structure::freezeTransition(JSGlobalData& globalData, Structure* structure)
+Structure* Structure::freezeTransition(VM& vm, Structure* structure)
{
- Structure* transition = preventExtensionsTransition(globalData, structure);
+ Structure* transition = preventExtensionsTransition(vm, structure);
- if (transition->m_propertyTable) {
- PropertyTable::iterator iter = transition->m_propertyTable->begin();
- PropertyTable::iterator end = transition->m_propertyTable->end();
+ if (transition->propertyTable()) {
+ PropertyTable::iterator iter = transition->propertyTable()->begin();
+ PropertyTable::iterator end = transition->propertyTable()->end();
if (iter != end)
transition->m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
for (; iter != end; ++iter)
iter->attributes |= iter->attributes & Accessor ? DontDelete : (DontDelete | ReadOnly);
}
+ transition->checkOffsetConsistency();
return transition;
}
// In future we may want to cache this transition.
-Structure* Structure::preventExtensionsTransition(JSGlobalData& globalData, Structure* structure)
+Structure* Structure::preventExtensionsTransition(VM& vm, Structure* structure)
{
- Structure* transition = create(globalData, structure);
+ Structure* transition = create(vm, structure);
// Don't set m_offset, as one can not transition to this.
- structure->materializePropertyMapIfNecessary(globalData);
- transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
+ structure->materializePropertyMapIfNecessary(vm);
+ transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition));
+ transition->m_offset = structure->m_offset;
transition->m_preventExtensions = true;
transition->pin();
+ transition->checkOffsetConsistency();
return transition;
}
-Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure* structure, NonPropertyTransition transitionKind)
+PropertyTable* Structure::takePropertyTableOrCloneIfPinned(VM& vm, Structure* owner)
+{
+ materializePropertyMapIfNecessaryForPinning(vm);
+ if (m_isPinnedPropertyTable)
+ return propertyTable()->copy(vm, owner, propertyTable()->size() + 1);
+ PropertyTable* takenPropertyTable = propertyTable().get();
+ propertyTable().clear();
+ return takenPropertyTable;
+}
+
+Structure* Structure::nonPropertyTransition(VM& vm, Structure* structure, NonPropertyTransition transitionKind)
{
unsigned attributes = toAttributes(transitionKind);
IndexingType indexingType = newIndexingType(structure->indexingTypeIncludingHistory(), transitionKind);
@@ -559,40 +568,31 @@ Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure*
return existingTransition;
}
- Structure* transition = create(globalData, structure);
- transition->m_previous.set(globalData, transition, structure);
+ Structure* transition = create(vm, structure);
+ transition->setPreviousID(vm, transition, structure);
transition->m_attributesInPrevious = attributes;
transition->m_indexingType = indexingType;
+ transition->propertyTable().set(vm, transition, structure->takePropertyTableOrCloneIfPinned(vm, transition));
transition->m_offset = structure->m_offset;
+ checkOffset(transition->m_offset, transition->inlineCapacity());
- if (structure->m_propertyTable) {
- if (structure->m_isPinnedPropertyTable)
- transition->m_propertyTable = structure->m_propertyTable->copy(globalData, transition, structure->m_propertyTable->size() + 1);
- else
- transition->m_propertyTable = structure->m_propertyTable.release();
- } else {
- if (structure->m_previous)
- transition->materializePropertyMap(globalData);
- else
- transition->createPropertyMap();
- }
-
- structure->m_transitionTable.add(globalData, transition);
+ structure->m_transitionTable.add(vm, transition);
+ transition->checkOffsetConsistency();
return transition;
}
// In future we may want to cache this property.
-bool Structure::isSealed(JSGlobalData& globalData)
+bool Structure::isSealed(VM& vm)
{
if (isExtensible())
return false;
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
return true;
- PropertyTable::iterator end = m_propertyTable->end();
- for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
+ PropertyTable::iterator end = propertyTable()->end();
+ for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
if ((iter->attributes & DontDelete) != DontDelete)
return false;
}
@@ -600,17 +600,17 @@ bool Structure::isSealed(JSGlobalData& globalData)
}
// In future we may want to cache this property.
-bool Structure::isFrozen(JSGlobalData& globalData)
+bool Structure::isFrozen(VM& vm)
{
if (isExtensible())
return false;
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
return true;
- PropertyTable::iterator end = m_propertyTable->end();
- for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
+ PropertyTable::iterator end = propertyTable()->end();
+ for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
if (!(iter->attributes & DontDelete))
return false;
if (!(iter->attributes & (ReadOnly | Accessor)))
@@ -619,59 +619,59 @@ bool Structure::isFrozen(JSGlobalData& globalData)
return true;
}
-Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObject* object)
+Structure* Structure::flattenDictionaryStructure(VM& vm, JSObject* object)
{
+ checkOffsetConsistency();
ASSERT(isDictionary());
if (isUncacheableDictionary()) {
- ASSERT(m_propertyTable);
+ ASSERT(propertyTable());
- size_t propertyCount = m_propertyTable->size();
+ size_t propertyCount = propertyTable()->size();
// Holds our values compacted by insertion order.
Vector<JSValue> values(propertyCount);
// Copies out our values from their hashed locations, compacting property table offsets as we go.
unsigned i = 0;
- PropertyTable::iterator end = m_propertyTable->end();
- for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter, ++i) {
- values[i] = object->getDirectOffset(iter->offset);
- iter->offset = propertyOffsetFor(i, m_inlineCapacity);
+ PropertyTable::iterator end = propertyTable()->end();
+ m_offset = invalidOffset;
+ for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter, ++i) {
+ values[i] = object->getDirect(iter->offset);
+ m_offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity);
}
// Copies in our values to their compacted locations.
for (unsigned i = 0; i < propertyCount; i++)
- object->putDirectOffset(globalData, propertyOffsetFor(i, m_inlineCapacity), values[i]);
+ object->putDirect(vm, offsetForPropertyNumber(i, m_inlineCapacity), values[i]);
- m_propertyTable->clearDeletedOffsets();
+ propertyTable()->clearDeletedOffsets();
+ checkOffsetConsistency();
}
m_dictionaryKind = NoneDictionaryKind;
return this;
}
-PropertyOffset Structure::addPropertyWithoutTransition(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
+PropertyOffset Structure::addPropertyWithoutTransition(VM& vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
{
- ASSERT(!m_enumerationCache);
+ ASSERT(!enumerationCache());
if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
specificValue = 0;
- materializePropertyMapIfNecessaryForPinning(globalData);
+ materializePropertyMapIfNecessaryForPinning(vm);
pin();
- PropertyOffset offset = putSpecificValue(globalData, propertyName, attributes, specificValue);
- if (outOfLineSize() > outOfLineCapacity())
- growOutOfLineCapacity();
- return offset;
+ return putSpecificValue(vm, propertyName, attributes, specificValue);
}
-PropertyOffset Structure::removePropertyWithoutTransition(JSGlobalData& globalData, PropertyName propertyName)
+PropertyOffset Structure::removePropertyWithoutTransition(VM& vm, PropertyName propertyName)
{
ASSERT(isUncacheableDictionary());
- ASSERT(!m_enumerationCache);
+ ASSERT(!enumerationCache());
- materializePropertyMapIfNecessaryForPinning(globalData);
+ materializePropertyMapIfNecessaryForPinning(vm);
pin();
return remove(propertyName);
@@ -679,12 +679,28 @@ PropertyOffset Structure::removePropertyWithoutTransition(JSGlobalData& globalDa
void Structure::pin()
{
- ASSERT(m_propertyTable);
+ ASSERT(propertyTable());
m_isPinnedPropertyTable = true;
- m_previous.clear();
+ clearPreviousID();
m_nameInPrevious.clear();
}
+void Structure::allocateRareData(VM& vm)
+{
+ ASSERT(!typeInfo().structureHasRareData());
+ StructureRareData* rareData = StructureRareData::create(vm, previous());
+ m_typeInfo = TypeInfo(typeInfo().type(), typeInfo().flags() | StructureHasRareData);
+ m_previousOrRareData.set(vm, this, rareData);
+}
+
+void Structure::cloneRareDataFrom(VM& vm, const Structure* other)
+{
+ ASSERT(other->typeInfo().structureHasRareData());
+ StructureRareData* newRareData = StructureRareData::clone(vm, other->rareData());
+ m_typeInfo = TypeInfo(typeInfo().type(), typeInfo().flags() | StructureHasRareData);
+ m_previousOrRareData.set(vm, this, newRareData);
+}
+
#if DUMP_PROPERTYMAP_STATS
struct PropertyMapStatisticsExitLogger {
@@ -708,29 +724,34 @@ PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger()
inline void Structure::checkConsistency()
{
+ checkOffsetConsistency();
}
#endif
-PassOwnPtr<PropertyTable> Structure::copyPropertyTable(JSGlobalData& globalData, Structure* owner)
+PropertyTable* Structure::copyPropertyTable(VM& vm, Structure* owner)
{
- return adoptPtr(m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : 0);
+ if (!propertyTable())
+ return 0;
+ return PropertyTable::clone(vm, owner, *propertyTable().get());
}
-PassOwnPtr<PropertyTable> Structure::copyPropertyTableForPinning(JSGlobalData& globalData, Structure* owner)
+PropertyTable* Structure::copyPropertyTableForPinning(VM& vm, Structure* owner)
{
- return adoptPtr(m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : new PropertyTable(numberOfSlotsForLastOffset(m_offset, m_typeInfo.type())));
+ if (propertyTable())
+ return PropertyTable::clone(vm, owner, *propertyTable().get());
+ return PropertyTable::create(vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
}
-PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue)
+PropertyOffset Structure::get(VM& vm, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue)
{
ASSERT(structure()->classInfo() == &s_info);
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
return invalidOffset;
- PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
+ PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first;
if (!entry)
return invalidOffset;
@@ -739,13 +760,13 @@ PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyNam
return entry->offset;
}
-bool Structure::despecifyFunction(JSGlobalData& globalData, PropertyName propertyName)
+bool Structure::despecifyFunction(VM& vm, PropertyName propertyName)
{
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
return false;
- PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
+ PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first;
if (!entry)
return false;
@@ -754,20 +775,20 @@ bool Structure::despecifyFunction(JSGlobalData& globalData, PropertyName propert
return true;
}
-void Structure::despecifyAllFunctions(JSGlobalData& globalData)
+void Structure::despecifyAllFunctions(VM& vm)
{
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
return;
- PropertyTable::iterator end = m_propertyTable->end();
- for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter)
+ PropertyTable::iterator end = propertyTable()->end();
+ for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter)
iter->specificValue.clear();
}
-PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
+PropertyOffset Structure::putSpecificValue(VM& vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue)
{
- ASSERT(!JSC::isValidOffset(get(globalData, propertyName)));
+ ASSERT(!JSC::isValidOffset(get(vm, propertyName)));
checkConsistency();
if (attributes & DontEnum)
@@ -775,13 +796,13 @@ PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyNam
StringImpl* rep = propertyName.uid();
- if (!m_propertyTable)
- createPropertyMap();
-
- PropertyOffset newOffset = m_propertyTable->nextOffset(m_inlineCapacity);
+ if (!propertyTable())
+ createPropertyMap(vm);
- m_propertyTable->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue));
+ PropertyOffset newOffset = propertyTable()->nextOffset(m_inlineCapacity);
+ propertyTable()->add(PropertyMapEntry(vm, this, rep, newOffset, attributes, specificValue), m_offset, PropertyTable::PropertyOffsetMayChange);
+
checkConsistency();
return newOffset;
}
@@ -792,41 +813,40 @@ PropertyOffset Structure::remove(PropertyName propertyName)
StringImpl* rep = propertyName.uid();
- if (!m_propertyTable)
+ if (!propertyTable())
return invalidOffset;
- PropertyTable::find_iterator position = m_propertyTable->find(rep);
+ PropertyTable::find_iterator position = propertyTable()->find(rep);
if (!position.first)
return invalidOffset;
PropertyOffset offset = position.first->offset;
- m_propertyTable->remove(position);
- m_propertyTable->addDeletedOffset(offset);
+ propertyTable()->remove(position);
+ propertyTable()->addDeletedOffset(offset);
checkConsistency();
return offset;
}
-void Structure::createPropertyMap(unsigned capacity)
+void Structure::createPropertyMap(VM& vm, unsigned capacity)
{
- ASSERT(!m_propertyTable);
+ ASSERT(!propertyTable());
checkConsistency();
- m_propertyTable = adoptPtr(new PropertyTable(capacity));
- checkConsistency();
+ propertyTable().set(vm, this, PropertyTable::create(vm, capacity));
}
-void Structure::getPropertyNamesFromStructure(JSGlobalData& globalData, PropertyNameArray& propertyNames, EnumerationMode mode)
+void Structure::getPropertyNamesFromStructure(VM& vm, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
return;
bool knownUnique = !propertyNames.size();
- PropertyTable::iterator end = m_propertyTable->end();
- for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
+ PropertyTable::iterator end = propertyTable()->end();
+ for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
ASSERT(m_hasNonEnumerableProperties || !(iter->attributes & DontEnum));
if (iter->key->isIdentifier() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) {
if (knownUnique)
@@ -837,6 +857,11 @@ void Structure::getPropertyNamesFromStructure(JSGlobalData& globalData, Property
}
}
+JSValue Structure::prototypeForLookup(CodeBlock* codeBlock) const
+{
+ return prototypeForLookup(codeBlock->globalObject());
+}
+
void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
Structure* thisObject = jsCast<Structure*>(cell);
@@ -851,18 +876,17 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
visitor.append(&thisObject->m_prototype);
visitor.append(&thisObject->m_cachedPrototypeChain);
}
- visitor.append(&thisObject->m_previous);
+ visitor.append(&thisObject->m_previousOrRareData);
visitor.append(&thisObject->m_specificValueInPrevious);
- visitor.append(&thisObject->m_enumerationCache);
- if (thisObject->m_propertyTable) {
- PropertyTable::iterator end = thisObject->m_propertyTable->end();
- for (PropertyTable::iterator ptr = thisObject->m_propertyTable->begin(); ptr != end; ++ptr)
- visitor.append(&ptr->specificValue);
- }
- visitor.append(&thisObject->m_objectToStringValue);
+
+ if (thisObject->m_isPinnedPropertyTable) {
+ ASSERT(thisObject->m_propertyTableUnsafe);
+ visitor.append(&thisObject->m_propertyTableUnsafe);
+ } else if (thisObject->m_propertyTableUnsafe)
+ thisObject->m_propertyTableUnsafe.clear();
}
-bool Structure::prototypeChainMayInterceptStoreTo(JSGlobalData& globalData, PropertyName propertyName)
+bool Structure::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyName)
{
unsigned i = propertyName.asIndex();
if (i != PropertyName::NotAnIndex)
@@ -877,7 +901,7 @@ bool Structure::prototypeChainMayInterceptStoreTo(JSGlobalData& globalData, Prop
unsigned attributes;
JSCell* specificValue;
- PropertyOffset offset = current->get(globalData, propertyName, attributes, specificValue);
+ PropertyOffset offset = current->get(vm, propertyName, attributes, specificValue);
if (!JSC::isValidOffset(offset))
continue;
@@ -892,6 +916,7 @@ bool Structure::prototypeChainMayInterceptStoreTo(JSGlobalData& globalData, Prop
void PropertyTable::checkConsistency()
{
+ checkOffsetConsistency();
ASSERT(m_indexSize >= PropertyTable::MinimumTableSize);
ASSERT(m_indexMask);
ASSERT(m_indexSize == m_indexMask + 1);
@@ -949,17 +974,17 @@ void PropertyTable::checkConsistency()
void Structure::checkConsistency()
{
- if (!m_propertyTable)
+ if (!propertyTable())
return;
if (!m_hasNonEnumerableProperties) {
- PropertyTable::iterator end = m_propertyTable->end();
- for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
+ PropertyTable::iterator end = propertyTable()->end();
+ for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
ASSERT(!(iter->attributes & DontEnum));
}
}
- m_propertyTable->checkConsistency();
+ propertyTable()->checkConsistency();
}
#endif // DO_PROPERTYMAP_CONSTENCY_CHECK
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 6e4402c52..45379efd6 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,18 +28,17 @@
#include "ClassInfo.h"
#include "IndexingType.h"
+#include "JSCJSValue.h"
#include "JSCell.h"
#include "JSType.h"
-#include "JSValue.h"
-#include "PropertyMapHashTable.h"
#include "PropertyName.h"
#include "PropertyNameArray.h"
+#include "PropertyOffset.h"
#include "Protect.h"
+#include "StructureRareData.h"
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
#include "Watchpoint.h"
-#include "Weak.h"
-#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/text/StringImpl.h>
@@ -47,562 +46,436 @@
namespace JSC {
- class LLIntOffsetsExtractor;
- class PropertyNameArray;
- class PropertyNameArrayData;
- class StructureChain;
- class SlotVisitor;
- class JSString;
-
- // The out-of-line property storage capacity to use when first allocating out-of-line
- // storage. Note that all objects start out without having any out-of-line storage;
- // this comes into play only on the first property store that exhausts inline storage.
- static const unsigned initialOutOfLineCapacity = 4;
-
- // The factor by which to grow out-of-line storage when it is exhausted, after the
- // initial allocation.
- static const unsigned outOfLineGrowthFactor = 2;
-
- class Structure : public JSCell {
- public:
- friend class StructureTransitionTable;
-
- typedef JSCell Base;
-
- static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, PropertyOffset inlineCapacity = 0);
-
- protected:
- void finishCreation(JSGlobalData& globalData)
- {
- Base::finishCreation(globalData);
- ASSERT(m_prototype);
- ASSERT(m_prototype.isObject() || m_prototype.isNull());
- }
-
- void finishCreation(JSGlobalData& globalData, CreatingEarlyCellTag)
- {
- Base::finishCreation(globalData, this, CreatingEarlyCell);
- ASSERT(m_prototype);
- ASSERT(m_prototype.isNull());
- ASSERT(!globalData.structureStructure);
- }
-
- public:
- static void dumpStatistics();
-
- JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
- JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
- static Structure* removePropertyTransition(JSGlobalData&, Structure*, PropertyName, PropertyOffset&);
- JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
- JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, PropertyName);
- static Structure* attributeChangeTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes);
- static Structure* toCacheableDictionaryTransition(JSGlobalData&, Structure*);
- static Structure* toUncacheableDictionaryTransition(JSGlobalData&, Structure*);
- static Structure* sealTransition(JSGlobalData&, Structure*);
- static Structure* freezeTransition(JSGlobalData&, Structure*);
- static Structure* preventExtensionsTransition(JSGlobalData&, Structure*);
- static Structure* nonPropertyTransition(JSGlobalData&, Structure*, NonPropertyTransition);
-
- bool isSealed(JSGlobalData&);
- bool isFrozen(JSGlobalData&);
- bool isExtensible() const { return !m_preventExtensions; }
- bool didTransition() const { return m_didTransition; }
- bool putWillGrowOutOfLineStorage()
- {
- ASSERT(outOfLineCapacity() >= outOfLineSize());
-
- if (!m_propertyTable) {
- unsigned currentSize = numberOfOutOfLineSlotsForLastOffset(m_offset);
- ASSERT(outOfLineCapacity() >= currentSize);
- return currentSize == outOfLineCapacity();
- }
-
- ASSERT(totalStorageCapacity() >= m_propertyTable->propertyStorageSize());
- if (m_propertyTable->hasDeletedOffset())
- return false;
-
- ASSERT(totalStorageCapacity() >= m_propertyTable->size());
- return m_propertyTable->size() == totalStorageCapacity();
- }
- JS_EXPORT_PRIVATE size_t suggestedNewOutOfLineStorageCapacity();
+class LLIntOffsetsExtractor;
+class PropertyNameArray;
+class PropertyNameArrayData;
+class PropertyTable;
+class StructureChain;
+class SlotVisitor;
+class JSString;
- Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
+// The out-of-line property storage capacity to use when first allocating out-of-line
+// storage. Note that all objects start out without having any out-of-line storage;
+// this comes into play only on the first property store that exhausts inline storage.
+static const unsigned initialOutOfLineCapacity = 4;
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
- static void destroy(JSCell*);
+// The factor by which to grow out-of-line storage when it is exhausted, after the
+// initial allocation.
+static const unsigned outOfLineGrowthFactor = 2;
- // These should be used with caution.
- JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
- PropertyOffset removePropertyWithoutTransition(JSGlobalData&, PropertyName);
- void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); }
-
- bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
- bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
+class Structure : public JSCell {
+public:
+ friend class StructureTransitionTable;
- bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
+ typedef JSCell Base;
- // Type accessors.
- const TypeInfo& typeInfo() const { ASSERT(structure()->classInfo() == &s_info); return m_typeInfo; }
- bool isObject() const { return typeInfo().isObject(); }
+ static Structure* create(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0);
- IndexingType indexingType() const { return m_indexingType & AllArrayTypes; }
- IndexingType indexingTypeIncludingHistory() const { return m_indexingType; }
-
- bool mayInterceptIndexedAccesses() const
- {
- return !!(indexingTypeIncludingHistory() & MayHaveIndexedAccessors);
- }
-
- bool anyObjectInChainMayInterceptIndexedAccesses() const;
-
- bool needsSlowPutIndexing() const;
- NonPropertyTransition suggestedArrayStorageTransition() const;
-
- JSGlobalObject* globalObject() const { return m_globalObject.get(); }
- void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); }
-
- JSValue storedPrototype() const { return m_prototype.get(); }
- JSValue prototypeForLookup(ExecState*) const;
- JSValue prototypeForLookup(JSGlobalObject*) const;
- JSValue prototypeForLookup(CodeBlock*) const;
- StructureChain* prototypeChain(JSGlobalData&, JSGlobalObject*) const;
- StructureChain* prototypeChain(ExecState*) const;
- static void visitChildren(JSCell*, SlotVisitor&);
-
- // Will just the prototype chain intercept this property access?
- bool prototypeChainMayInterceptStoreTo(JSGlobalData&, PropertyName);
-
- bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
-
- Structure* previousID() const
- {
- ASSERT(structure()->classInfo() == &s_info);
- return m_previous.get();
- }
- bool transitivelyTransitionedFrom(Structure* structureToFind);
-
- void growOutOfLineCapacity();
- unsigned outOfLineCapacity() const
- {
- ASSERT(structure()->classInfo() == &s_info);
- return m_outOfLineCapacity;
- }
- unsigned outOfLineSize() const
- {
- ASSERT(structure()->classInfo() == &s_info);
- if (m_propertyTable) {
- unsigned totalSize = m_propertyTable->propertyStorageSize();
- unsigned inlineCapacity = this->inlineCapacity();
- if (totalSize < inlineCapacity)
- return 0;
- return totalSize - inlineCapacity;
- }
- return numberOfOutOfLineSlotsForLastOffset(m_offset);
- }
- bool hasInlineStorage() const
- {
- return !!m_inlineCapacity;
- }
- unsigned inlineCapacity() const
- {
- return m_inlineCapacity;
- }
- unsigned inlineSize() const
- {
- unsigned result;
- if (m_propertyTable)
- result = m_propertyTable->propertyStorageSize();
- else
- result = m_offset + 1;
- return std::min<unsigned>(result, m_inlineCapacity);
- }
- unsigned totalStorageSize() const
- {
- if (m_propertyTable)
- return m_propertyTable->propertyStorageSize();
- return numberOfSlotsForLastOffset(m_offset, m_typeInfo.type());
- }
- unsigned totalStorageCapacity() const
- {
- ASSERT(structure()->classInfo() == &s_info);
- return m_outOfLineCapacity + inlineCapacity();
- }
-
- PropertyOffset firstValidOffset() const
- {
- if (hasInlineStorage())
- return 0;
- return firstOutOfLineOffset;
- }
- PropertyOffset lastValidOffset() const
- {
- if (m_propertyTable)
- return propertyOffsetFor(m_propertyTable->propertyStorageSize() - 1, m_inlineCapacity);
- return m_offset;
- }
- bool isValidOffset(PropertyOffset offset) const
- {
- return offset >= firstValidOffset()
- && offset <= lastValidOffset();
- }
-
- bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
-
- PropertyOffset get(JSGlobalData&, PropertyName);
- PropertyOffset get(JSGlobalData&, const WTF::String& name);
- JS_EXPORT_PRIVATE PropertyOffset get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue);
-
- bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
- bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
- void setHasGetterSetterProperties(bool is__proto__)
- {
- m_hasGetterSetterProperties = true;
- if (!is__proto__)
- m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
- }
- void setContainsReadOnlyProperties()
- {
- m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
- }
+protected:
+ void finishCreation(VM& vm)
+ {
+ Base::finishCreation(vm);
+ ASSERT(m_prototype);
+ ASSERT(m_prototype.isObject() || m_prototype.isNull());
+ }
- bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
-
- bool isEmpty() const
- {
- if (m_propertyTable)
- return m_propertyTable->isEmpty();
- return !JSC::isValidOffset(m_offset);
- }
-
- JS_EXPORT_PRIVATE void despecifyDictionaryFunction(JSGlobalData&, PropertyName);
- void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
-
- void setEnumerationCache(JSGlobalData&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
- JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
- void getPropertyNamesFromStructure(JSGlobalData&, PropertyNameArray&, EnumerationMode);
-
- JSString* objectToStringValue() { return m_objectToStringValue.get(); }
-
- void setObjectToStringValue(JSGlobalData& globalData, const JSCell* owner, JSString* value)
- {
- m_objectToStringValue.set(globalData, owner, value);
- }
-
- bool staticFunctionsReified()
- {
- return m_staticFunctionReified;
- }
-
- void setStaticFunctionsReified()
- {
- m_staticFunctionReified = true;
- }
-
- const ClassInfo* classInfo() const { return m_classInfo; }
-
- static ptrdiff_t prototypeOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_prototype);
- }
-
- static ptrdiff_t globalObjectOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_globalObject);
- }
-
- static ptrdiff_t typeInfoFlagsOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
- }
-
- static ptrdiff_t typeInfoTypeOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
- }
-
- static ptrdiff_t classInfoOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_classInfo);
- }
+ void finishCreation(VM& vm, CreatingEarlyCellTag)
+ {
+ Base::finishCreation(vm, this, CreatingEarlyCell);
+ ASSERT(m_prototype);
+ ASSERT(m_prototype.isNull());
+ ASSERT(!vm.structureStructure);
+ }
+
+public:
+ static void dumpStatistics();
+
+ JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+ JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+ static Structure* removePropertyTransition(VM&, Structure*, PropertyName, PropertyOffset&);
+ JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype);
+ JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(VM&, Structure*, PropertyName);
+ static Structure* attributeChangeTransition(VM&, Structure*, PropertyName, unsigned attributes);
+ static Structure* toCacheableDictionaryTransition(VM&, Structure*);
+ static Structure* toUncacheableDictionaryTransition(VM&, Structure*);
+ static Structure* sealTransition(VM&, Structure*);
+ static Structure* freezeTransition(VM&, Structure*);
+ static Structure* preventExtensionsTransition(VM&, Structure*);
+ static Structure* nonPropertyTransition(VM&, Structure*, NonPropertyTransition);
+
+ bool isSealed(VM&);
+ bool isFrozen(VM&);
+ bool isExtensible() const { return !m_preventExtensions; }
+ bool didTransition() const { return m_didTransition; }
+ bool putWillGrowOutOfLineStorage();
+ JS_EXPORT_PRIVATE size_t suggestedNewOutOfLineStorageCapacity();
+
+ Structure* flattenDictionaryStructure(VM&, JSObject*);
+
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+ static void destroy(JSCell*);
+
+ // These should be used with caution.
+ JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
+ PropertyOffset removePropertyWithoutTransition(VM&, PropertyName);
+ void setPrototypeWithoutTransition(VM& vm, JSValue prototype) { m_prototype.set(vm, this, prototype); }
- static ptrdiff_t indexingTypeOffset()
- {
- return OBJECT_OFFSETOF(Structure, m_indexingType);
- }
+ bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
+ bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
+
+ bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
+
+ // Type accessors.
+ const TypeInfo& typeInfo() const { ASSERT(structure()->classInfo() == &s_info); return m_typeInfo; }
+ bool isObject() const { return typeInfo().isObject(); }
- static Structure* createStructure(JSGlobalData&);
+ IndexingType indexingType() const { return m_indexingType & AllArrayTypes; }
+ IndexingType indexingTypeIncludingHistory() const { return m_indexingType; }
- bool transitionWatchpointSetHasBeenInvalidated() const
- {
- return m_transitionWatchpointSet.hasBeenInvalidated();
- }
+ bool mayInterceptIndexedAccesses() const
+ {
+ return !!(indexingTypeIncludingHistory() & MayHaveIndexedAccessors);
+ }
- bool transitionWatchpointSetIsStillValid() const
- {
- return m_transitionWatchpointSet.isStillValid();
- }
+ bool anyObjectInChainMayInterceptIndexedAccesses() const;
- void addTransitionWatchpoint(Watchpoint* watchpoint) const
- {
- ASSERT(transitionWatchpointSetIsStillValid());
- m_transitionWatchpointSet.add(watchpoint);
- }
+ bool needsSlowPutIndexing() const;
+ NonPropertyTransition suggestedArrayStorageTransition() const;
- void notifyTransitionFromThisStructure() const
- {
- m_transitionWatchpointSet.notifyWrite();
- }
+ JSGlobalObject* globalObject() const { return m_globalObject.get(); }
+ void setGlobalObject(VM& vm, JSGlobalObject* globalObject) { m_globalObject.set(vm, this, globalObject); }
- static JS_EXPORTDATA const ClassInfo s_info;
-
- private:
- friend class LLIntOffsetsExtractor;
-
- JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, PropertyOffset inlineCapacity);
- Structure(JSGlobalData&);
- Structure(JSGlobalData&, const Structure*);
-
- static Structure* create(JSGlobalData&, const Structure*);
+ JSValue storedPrototype() const { return m_prototype.get(); }
+ JSValue prototypeForLookup(ExecState*) const;
+ JSValue prototypeForLookup(JSGlobalObject*) const;
+ JSValue prototypeForLookup(CodeBlock*) const;
+ StructureChain* prototypeChain(VM&, JSGlobalObject*) const;
+ StructureChain* prototypeChain(ExecState*) const;
+ static void visitChildren(JSCell*, SlotVisitor&);
- typedef enum {
- NoneDictionaryKind = 0,
- CachedDictionaryKind = 1,
- UncachedDictionaryKind = 2
- } DictionaryKind;
- static Structure* toDictionaryTransition(JSGlobalData&, Structure*, DictionaryKind);
-
- PropertyOffset putSpecificValue(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
- PropertyOffset remove(PropertyName);
-
- void createPropertyMap(unsigned keyCount = 0);
- void checkConsistency();
-
- bool despecifyFunction(JSGlobalData&, PropertyName);
- void despecifyAllFunctions(JSGlobalData&);
-
- PassOwnPtr<PropertyTable> copyPropertyTable(JSGlobalData&, Structure* owner);
- PassOwnPtr<PropertyTable> copyPropertyTableForPinning(JSGlobalData&, Structure* owner);
- JS_EXPORT_PRIVATE void materializePropertyMap(JSGlobalData&);
- void materializePropertyMapIfNecessary(JSGlobalData& globalData)
- {
- ASSERT(structure()->classInfo() == &s_info);
- if (!m_propertyTable && m_previous)
- materializePropertyMap(globalData);
- }
- void materializePropertyMapIfNecessaryForPinning(JSGlobalData& globalData)
- {
- ASSERT(structure()->classInfo() == &s_info);
- if (!m_propertyTable)
- materializePropertyMap(globalData);
- }
-
- int transitionCount() const
- {
- // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
- return numberOfSlotsForLastOffset(m_offset, m_typeInfo.type());
- }
-
- bool isValid(JSGlobalObject*, StructureChain* cachedPrototypeChain) const;
- bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
+ // Will just the prototype chain intercept this property access?
+ bool prototypeChainMayInterceptStoreTo(VM&, PropertyName);
- void pin();
-
- static const int s_maxTransitionLength = 64;
-
- static const unsigned maxSpecificFunctionThrashCount = 3;
-
- TypeInfo m_typeInfo;
- IndexingType m_indexingType;
+ bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
- WriteBarrier<JSGlobalObject> m_globalObject;
- WriteBarrier<Unknown> m_prototype;
- mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
-
- WriteBarrier<Structure> m_previous;
- RefPtr<StringImpl> m_nameInPrevious;
- WriteBarrier<JSCell> m_specificValueInPrevious;
-
- const ClassInfo* m_classInfo;
+ Structure* previousID() const
+ {
+ ASSERT(structure()->classInfo() == &s_info);
+ if (typeInfo().structureHasRareData())
+ return rareData()->previousID();
+ return previous();
+ }
+ bool transitivelyTransitionedFrom(Structure* structureToFind);
- StructureTransitionTable m_transitionTable;
+ unsigned outOfLineCapacity() const
+ {
+ ASSERT(checkOffsetConsistency());
+
+ unsigned outOfLineSize = this->outOfLineSize();
- WriteBarrier<JSPropertyNameIterator> m_enumerationCache;
+ if (!outOfLineSize)
+ return 0;
- OwnPtr<PropertyTable> m_propertyTable;
+ if (outOfLineSize <= initialOutOfLineCapacity)
+ return initialOutOfLineCapacity;
- WriteBarrier<JSString> m_objectToStringValue;
-
- mutable InlineWatchpointSet m_transitionWatchpointSet;
-
- uint32_t m_outOfLineCapacity;
- uint8_t m_inlineCapacity;
- COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
-
- // m_offset does not account for anonymous slots
- PropertyOffset m_offset;
-
- unsigned m_dictionaryKind : 2;
- bool m_isPinnedPropertyTable : 1;
- bool m_hasGetterSetterProperties : 1;
- bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
- bool m_hasNonEnumerableProperties : 1;
- unsigned m_attributesInPrevious : 22;
- unsigned m_specificFunctionThrashCount : 2;
- unsigned m_preventExtensions : 1;
- unsigned m_didTransition : 1;
- unsigned m_staticFunctionReified;
- };
-
- inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, PropertyOffset inlineCapacity)
- {
- ASSERT(globalData.structureStructure);
- ASSERT(classInfo);
- Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
- structure->finishCreation(globalData);
- return structure;
+ ASSERT(outOfLineSize > initialOutOfLineCapacity);
+ COMPILE_ASSERT(outOfLineGrowthFactor == 2, outOfLineGrowthFactor_is_two);
+ return WTF::roundUpToPowerOfTwo(outOfLineSize);
}
-
- inline Structure* Structure::createStructure(JSGlobalData& globalData)
+ unsigned outOfLineSize() const
{
- ASSERT(!globalData.structureStructure);
- Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData);
- structure->finishCreation(globalData, CreatingEarlyCell);
- return structure;
+ ASSERT(checkOffsetConsistency());
+ ASSERT(structure()->classInfo() == &s_info);
+
+ return numberOfOutOfLineSlotsForLastOffset(m_offset);
}
-
- inline Structure* Structure::create(JSGlobalData& globalData, const Structure* structure)
+ bool hasInlineStorage() const
{
- ASSERT(globalData.structureStructure);
- Structure* newStructure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, structure);
- newStructure->finishCreation(globalData);
- return newStructure;
+ return !!m_inlineCapacity;
}
-
- inline PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName)
+ unsigned inlineCapacity() const
+ {
+ return m_inlineCapacity;
+ }
+ unsigned inlineSize() const
+ {
+ return std::min<unsigned>(m_offset + 1, m_inlineCapacity);
+ }
+ unsigned totalStorageSize() const
+ {
+ return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
+ }
+ unsigned totalStorageCapacity() const
{
ASSERT(structure()->classInfo() == &s_info);
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
- return invalidOffset;
-
- PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
- return entry ? entry->offset : invalidOffset;
+ return outOfLineCapacity() + inlineCapacity();
}
- inline PropertyOffset Structure::get(JSGlobalData& globalData, const WTF::String& name)
+ PropertyOffset firstValidOffset() const
{
- ASSERT(structure()->classInfo() == &s_info);
- materializePropertyMapIfNecessary(globalData);
- if (!m_propertyTable)
- return invalidOffset;
+ if (hasInlineStorage())
+ return 0;
+ return firstOutOfLineOffset;
+ }
+ PropertyOffset lastValidOffset() const
+ {
+ return m_offset;
+ }
+ bool isValidOffset(PropertyOffset offset) const
+ {
+ return offset >= firstValidOffset()
+ && offset <= lastValidOffset();
+ }
+
+ bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
- PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first;
- return entry ? entry->offset : invalidOffset;
+ PropertyOffset get(VM&, PropertyName);
+ PropertyOffset get(VM&, const WTF::String& name);
+ JS_EXPORT_PRIVATE PropertyOffset get(VM&, PropertyName, unsigned& attributes, JSCell*& specificValue);
+
+ bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
+ bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
+ void setHasGetterSetterProperties(bool is__proto__)
+ {
+ m_hasGetterSetterProperties = true;
+ if (!is__proto__)
+ m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
}
-
- inline bool Structure::masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject)
+ void setContainsReadOnlyProperties()
+ {
+ m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+ }
+
+ bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
+
+ bool isEmpty() const
{
- return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;
+ ASSERT(checkOffsetConsistency());
+ return !JSC::isValidOffset(m_offset);
}
- inline JSValue JSValue::structureOrUndefined() const
+ JS_EXPORT_PRIVATE void despecifyDictionaryFunction(VM&, PropertyName);
+ void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
+
+ void setEnumerationCache(VM&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
+ JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
+ void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode);
+
+ JSString* objectToStringValue()
{
- if (isCell())
- return JSValue(asCell()->structure());
- return jsUndefined();
+ if (!typeInfo().structureHasRareData())
+ return 0;
+ return rareData()->objectToStringValue();
}
- inline bool JSCell::isObject() const
+ void setObjectToStringValue(VM& vm, const JSCell* owner, JSString* value)
{
- return m_structure->isObject();
+ if (!typeInfo().structureHasRareData())
+ allocateRareData(vm);
+ rareData()->setObjectToStringValue(vm, owner, value);
}
- inline bool JSCell::isString() const
+ bool staticFunctionsReified()
{
- return m_structure->typeInfo().type() == StringType;
+ return m_staticFunctionReified;
}
- inline bool JSCell::isGetterSetter() const
+ void setStaticFunctionsReified()
{
- return m_structure->typeInfo().type() == GetterSetterType;
+ m_staticFunctionReified = true;
}
- inline bool JSCell::isProxy() const
+ const ClassInfo* classInfo() const { return m_classInfo; }
+
+ static ptrdiff_t prototypeOffset()
{
- return structure()->typeInfo().type() == ProxyType;
+ return OBJECT_OFFSETOF(Structure, m_prototype);
}
- inline bool JSCell::isAPIValueWrapper() const
+ static ptrdiff_t globalObjectOffset()
{
- return m_structure->typeInfo().type() == APIValueWrapperType;
+ return OBJECT_OFFSETOF(Structure, m_globalObject);
}
- inline void JSCell::setStructure(JSGlobalData& globalData, Structure* structure)
+ static ptrdiff_t typeInfoFlagsOffset()
{
- ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
- ASSERT(structure->classInfo() == m_structure->classInfo());
- ASSERT(!m_structure
- || m_structure->transitionWatchpointSetHasBeenInvalidated()
- || m_structure.get() == structure);
- m_structure.set(globalData, this, structure);
+ return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
}
- ALWAYS_INLINE void SlotVisitor::internalAppend(JSCell* cell)
+ static ptrdiff_t typeInfoTypeOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
+ }
+
+ static ptrdiff_t classInfoOffset()
+ {
+ return OBJECT_OFFSETOF(Structure, m_classInfo);
+ }
+
+ static ptrdiff_t indexingTypeOffset()
{
- ASSERT(!m_isCheckingForDefaultMarkViolation);
- if (!cell)
- return;
-#if ENABLE(GC_VALIDATION)
- validate(cell);
-#endif
- if (Heap::testAndSetMarked(cell) || !cell->structure())
- return;
+ return OBJECT_OFFSETOF(Structure, m_indexingType);
+ }
- m_visitCount++;
+ static Structure* createStructure(VM&);
+
+ bool transitionWatchpointSetHasBeenInvalidated() const
+ {
+ return m_transitionWatchpointSet.hasBeenInvalidated();
+ }
+
+ bool transitionWatchpointSetIsStillValid() const
+ {
+ return m_transitionWatchpointSet.isStillValid();
+ }
+
+ void addTransitionWatchpoint(Watchpoint* watchpoint) const
+ {
+ ASSERT(transitionWatchpointSetIsStillValid());
+ m_transitionWatchpointSet.add(watchpoint);
+ }
+
+ void notifyTransitionFromThisStructure() const
+ {
+ m_transitionWatchpointSet.notifyWrite();
+ }
- MARK_LOG_CHILD(*this, cell);
+ static JS_EXPORTDATA const ClassInfo s_info;
+
+private:
+ friend class LLIntOffsetsExtractor;
- // Should never attempt to mark something that is zapped.
- ASSERT(!cell->isZapped());
+ JS_EXPORT_PRIVATE Structure(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
+ Structure(VM&);
+ Structure(VM&, const Structure*);
+
+ static Structure* create(VM&, const Structure*);
- m_stack.append(cell);
+ typedef enum {
+ NoneDictionaryKind = 0,
+ CachedDictionaryKind = 1,
+ UncachedDictionaryKind = 2
+ } DictionaryKind;
+ static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind);
+
+ PropertyOffset putSpecificValue(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
+ PropertyOffset remove(PropertyName);
+
+ void createPropertyMap(VM&, unsigned keyCount = 0);
+ void checkConsistency();
+
+ bool despecifyFunction(VM&, PropertyName);
+ void despecifyAllFunctions(VM&);
+
+ WriteBarrier<PropertyTable>& propertyTable();
+ PropertyTable* takePropertyTableOrCloneIfPinned(VM&, Structure* owner);
+ PropertyTable* copyPropertyTable(VM&, Structure* owner);
+ PropertyTable* copyPropertyTableForPinning(VM&, Structure* owner);
+ JS_EXPORT_PRIVATE void materializePropertyMap(VM&);
+ void materializePropertyMapIfNecessary(VM& vm)
+ {
+ ASSERT(structure()->classInfo() == &s_info);
+ ASSERT(checkOffsetConsistency());
+ if (!propertyTable() && previousID())
+ materializePropertyMap(vm);
+ }
+ void materializePropertyMapIfNecessaryForPinning(VM& vm)
+ {
+ ASSERT(structure()->classInfo() == &s_info);
+ checkOffsetConsistency();
+ if (!propertyTable())
+ materializePropertyMap(vm);
}
- inline StructureTransitionTable::Hash::Key StructureTransitionTable::keyForWeakGCMapFinalizer(void*, Structure* structure)
+ void setPreviousID(VM& vm, Structure* transition, Structure* structure)
{
- // Newer versions of the STL have an std::make_pair function that takes rvalue references.
- // When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue.
- // See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details.
- return Hash::Key(structure->m_nameInPrevious.get(), +structure->m_attributesInPrevious);
+ if (typeInfo().structureHasRareData())
+ rareData()->setPreviousID(vm, transition, structure);
+ else
+ m_previousOrRareData.set(vm, transition, structure);
}
- inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
+ void clearPreviousID()
{
- for (Structure* current = this; current; current = current->previousID()) {
- if (current == structureToFind)
- return true;
- }
- return false;
+ if (typeInfo().structureHasRareData())
+ rareData()->clearPreviousID();
+ else
+ m_previousOrRareData.clear();
}
- inline JSCell::JSCell(JSGlobalData& globalData, Structure* structure)
- : m_structure(globalData, this, structure)
+ int transitionCount() const
{
+ // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
+ return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
}
- inline void JSCell::finishCreation(JSGlobalData& globalData, Structure* structure, CreatingEarlyCellTag)
+ bool isValid(JSGlobalObject*, StructureChain* cachedPrototypeChain) const;
+ bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
+
+ void pin();
+
+ Structure* previous() const
{
-#if ENABLE(GC_VALIDATION)
- ASSERT(globalData.isInitializingObject());
- globalData.setInitializingObjectClass(0);
- if (structure)
-#endif
- m_structure.setEarlyValue(globalData, this, structure);
- // Very first set of allocations won't have a real structure.
- ASSERT(m_structure || !globalData.structureStructure);
+ ASSERT(!typeInfo().structureHasRareData());
+ return static_cast<Structure*>(m_previousOrRareData.get());
}
+ StructureRareData* rareData() const
+ {
+ ASSERT(typeInfo().structureHasRareData());
+ return static_cast<StructureRareData*>(m_previousOrRareData.get());
+ }
+
+ bool checkOffsetConsistency() const;
+
+ void allocateRareData(VM&);
+ void cloneRareDataFrom(VM&, const Structure*);
+
+ static const int s_maxTransitionLength = 64;
+
+ static const unsigned maxSpecificFunctionThrashCount = 3;
+
+ WriteBarrier<JSGlobalObject> m_globalObject;
+ WriteBarrier<Unknown> m_prototype;
+ mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
+
+ WriteBarrier<JSCell> m_previousOrRareData;
+
+ RefPtr<StringImpl> m_nameInPrevious;
+ WriteBarrier<JSCell> m_specificValueInPrevious;
+
+ const ClassInfo* m_classInfo;
+
+ StructureTransitionTable m_transitionTable;
+
+ // Should be accessed through propertyTable(). During GC, it may be set to 0 by another thread.
+ WriteBarrier<PropertyTable> m_propertyTableUnsafe;
+
+ mutable InlineWatchpointSet m_transitionWatchpointSet;
+
+ COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
+
+ // m_offset does not account for anonymous slots
+ PropertyOffset m_offset;
+
+ TypeInfo m_typeInfo;
+ IndexingType m_indexingType;
+
+ uint8_t m_inlineCapacity;
+ unsigned m_dictionaryKind : 2;
+ bool m_isPinnedPropertyTable : 1;
+ bool m_hasGetterSetterProperties : 1;
+ bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
+ bool m_hasNonEnumerableProperties : 1;
+ unsigned m_attributesInPrevious : 14;
+ unsigned m_specificFunctionThrashCount : 2;
+ unsigned m_preventExtensions : 1;
+ unsigned m_didTransition : 1;
+ unsigned m_staticFunctionReified;
+};
+
} // namespace JSC
#endif // Structure_h
diff --git a/Source/JavaScriptCore/runtime/StructureChain.cpp b/Source/JavaScriptCore/runtime/StructureChain.cpp
index a1c97340e..85abcd34f 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.cpp
+++ b/Source/JavaScriptCore/runtime/StructureChain.cpp
@@ -27,6 +27,7 @@
#include "StructureChain.h"
#include "JSObject.h"
+#include "Operations.h"
#include "Structure.h"
#include <wtf/RefPtr.h>
@@ -34,8 +35,8 @@ namespace JSC {
ClassInfo StructureChain::s_info = { "StructureChain", 0, 0, 0, CREATE_METHOD_TABLE(StructureChain) };
-StructureChain::StructureChain(JSGlobalData& globalData, Structure* structure)
- : JSCell(globalData, structure)
+StructureChain::StructureChain(VM& vm, Structure* structure)
+ : JSCell(vm, structure)
{
}
diff --git a/Source/JavaScriptCore/runtime/StructureChain.h b/Source/JavaScriptCore/runtime/StructureChain.h
index 878f606b4..e652fecc2 100644
--- a/Source/JavaScriptCore/runtime/StructureChain.h
+++ b/Source/JavaScriptCore/runtime/StructureChain.h
@@ -46,16 +46,16 @@ namespace JSC {
public:
typedef JSCell Base;
- static StructureChain* create(JSGlobalData& globalData, Structure* head)
+ static StructureChain* create(VM& vm, Structure* head)
{
- StructureChain* chain = new (NotNull, allocateCell<StructureChain>(globalData.heap)) StructureChain(globalData, globalData.structureChainStructure.get());
- chain->finishCreation(globalData, head);
+ StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm.heap)) StructureChain(vm, vm.structureChainStructure.get());
+ chain->finishCreation(vm, head);
return chain;
}
WriteBarrier<Structure>* head() { return m_vector.get(); }
static void visitChildren(JSCell*, SlotVisitor&);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) { return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info); }
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) { return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info); }
static ClassInfo s_info;
@@ -64,9 +64,9 @@ namespace JSC {
static void destroy(JSCell*);
protected:
- void finishCreation(JSGlobalData& globalData, Structure* head)
+ void finishCreation(VM& vm, Structure* head)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
size_t size = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
++size;
@@ -75,13 +75,13 @@ namespace JSC {
size_t i = 0;
for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
- m_vector[i++].set(globalData, this, current);
+ m_vector[i++].set(vm, this, current);
}
private:
friend class LLIntOffsetsExtractor;
- StructureChain(JSGlobalData&, Structure*);
+ StructureChain(VM&, Structure*);
OwnArrayPtr<WriteBarrier<Structure> > m_vector;
};
diff --git a/Source/JavaScriptCore/runtime/StructureInlines.h b/Source/JavaScriptCore/runtime/StructureInlines.h
new file mode 100644
index 000000000..75ca40dd7
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/StructureInlines.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 StructureInlines_h
+#define StructureInlines_h
+
+#include "PropertyMapHashTable.h"
+#include "Structure.h"
+
+namespace JSC {
+
+inline Structure* Structure::create(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity)
+{
+ ASSERT(vm.structureStructure);
+ ASSERT(classInfo);
+ Structure* structure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
+ structure->finishCreation(vm);
+ return structure;
+}
+
+inline Structure* Structure::createStructure(VM& vm)
+{
+ ASSERT(!vm.structureStructure);
+ Structure* structure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm);
+ structure->finishCreation(vm, CreatingEarlyCell);
+ return structure;
+}
+
+inline Structure* Structure::create(VM& vm, const Structure* structure)
+{
+ ASSERT(vm.structureStructure);
+ Structure* newStructure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm, structure);
+ newStructure->finishCreation(vm);
+ return newStructure;
+}
+
+inline PropertyOffset Structure::get(VM& vm, PropertyName propertyName)
+{
+ ASSERT(structure()->classInfo() == &s_info);
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
+ return invalidOffset;
+
+ PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first;
+ return entry ? entry->offset : invalidOffset;
+}
+
+inline PropertyOffset Structure::get(VM& vm, const WTF::String& name)
+{
+ ASSERT(structure()->classInfo() == &s_info);
+ materializePropertyMapIfNecessary(vm);
+ if (!propertyTable())
+ return invalidOffset;
+
+ PropertyMapEntry* entry = propertyTable()->findWithString(name.impl()).first;
+ return entry ? entry->offset : invalidOffset;
+}
+
+inline bool Structure::masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject)
+{
+ return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;
+}
+
+ALWAYS_INLINE void SlotVisitor::internalAppend(JSCell* cell)
+{
+ ASSERT(!m_isCheckingForDefaultMarkViolation);
+ if (!cell)
+ return;
+#if ENABLE(GC_VALIDATION)
+ validate(cell);
+#endif
+ if (Heap::testAndSetMarked(cell) || !cell->structure())
+ return;
+
+ m_visitCount++;
+
+ MARK_LOG_CHILD(*this, cell);
+
+ // Should never attempt to mark something that is zapped.
+ ASSERT(!cell->isZapped());
+
+ m_stack.append(cell);
+}
+
+inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
+{
+ for (Structure* current = this; current; current = current->previousID()) {
+ if (current == structureToFind)
+ return true;
+ }
+ return false;
+}
+
+inline void Structure::setEnumerationCache(VM& vm, JSPropertyNameIterator* enumerationCache)
+{
+ ASSERT(!isDictionary());
+ if (!typeInfo().structureHasRareData())
+ allocateRareData(vm);
+ rareData()->setEnumerationCache(vm, this, enumerationCache);
+}
+
+inline JSPropertyNameIterator* Structure::enumerationCache()
+{
+ if (!typeInfo().structureHasRareData())
+ return 0;
+ return rareData()->enumerationCache();
+}
+
+inline JSValue Structure::prototypeForLookup(JSGlobalObject* globalObject) const
+{
+ if (isObject())
+ return m_prototype.get();
+
+ ASSERT(typeInfo().type() == StringType);
+ return globalObject->stringPrototype();
+}
+
+inline JSValue Structure::prototypeForLookup(ExecState* exec) const
+{
+ return prototypeForLookup(exec->lexicalGlobalObject());
+}
+
+inline StructureChain* Structure::prototypeChain(VM& vm, JSGlobalObject* globalObject) const
+{
+ // We cache our prototype chain so our clients can share it.
+ if (!isValid(globalObject, m_cachedPrototypeChain.get())) {
+ JSValue prototype = prototypeForLookup(globalObject);
+ m_cachedPrototypeChain.set(vm, this, StructureChain::create(vm, prototype.isNull() ? 0 : asObject(prototype)->structure()));
+ }
+ return m_cachedPrototypeChain.get();
+}
+
+inline StructureChain* Structure::prototypeChain(ExecState* exec) const
+{
+ return prototypeChain(exec->vm(), exec->lexicalGlobalObject());
+}
+
+inline bool Structure::isValid(JSGlobalObject* globalObject, StructureChain* cachedPrototypeChain) const
+{
+ if (!cachedPrototypeChain)
+ return false;
+
+ JSValue prototype = prototypeForLookup(globalObject);
+ WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
+ while (*cachedStructure && !prototype.isNull()) {
+ if (asObject(prototype)->structure() != cachedStructure->get())
+ return false;
+ ++cachedStructure;
+ prototype = asObject(prototype)->prototype();
+ }
+ return prototype.isNull() && !*cachedStructure;
+}
+
+inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const
+{
+ return isValid(exec->lexicalGlobalObject(), cachedPrototypeChain);
+}
+
+inline bool Structure::putWillGrowOutOfLineStorage()
+{
+ checkOffsetConsistency();
+
+ ASSERT(outOfLineCapacity() >= outOfLineSize());
+
+ if (!propertyTable()) {
+ unsigned currentSize = numberOfOutOfLineSlotsForLastOffset(m_offset);
+ ASSERT(outOfLineCapacity() >= currentSize);
+ return currentSize == outOfLineCapacity();
+ }
+
+ ASSERT(totalStorageCapacity() >= propertyTable()->propertyStorageSize());
+ if (propertyTable()->hasDeletedOffset())
+ return false;
+
+ ASSERT(totalStorageCapacity() >= propertyTable()->size());
+ return propertyTable()->size() == totalStorageCapacity();
+}
+
+ALWAYS_INLINE WriteBarrier<PropertyTable>& Structure::propertyTable()
+{
+ ASSERT(!globalObject() || !globalObject()->vm().heap.isBusy());
+ return m_propertyTableUnsafe;
+}
+
+ALWAYS_INLINE bool Structure::checkOffsetConsistency() const
+{
+ PropertyTable* propertyTable = m_propertyTableUnsafe.get();
+
+ if (!propertyTable) {
+ ASSERT(!m_isPinnedPropertyTable);
+ return true;
+ }
+
+ RELEASE_ASSERT(numberOfSlotsForLastOffset(m_offset, m_inlineCapacity) == propertyTable->propertyStorageSize());
+ unsigned totalSize = propertyTable->propertyStorageSize();
+ RELEASE_ASSERT((totalSize < inlineCapacity() ? 0 : totalSize - inlineCapacity()) == numberOfOutOfLineSlotsForLastOffset(m_offset));
+
+ return true;
+}
+
+} // namespace JSC
+
+#endif // StructureInlines_h
+
diff --git a/Source/JavaScriptCore/runtime/StructureRareData.cpp b/Source/JavaScriptCore/runtime/StructureRareData.cpp
new file mode 100644
index 000000000..00880d32c
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/StructureRareData.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StructureRareData.h"
+
+#include "JSString.h"
+#include "Operations.h"
+
+namespace JSC {
+
+const ClassInfo StructureRareData::s_info = { "StructureRareData", 0, 0, 0, CREATE_METHOD_TABLE(StructureRareData) };
+
+Structure* StructureRareData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info);
+}
+
+StructureRareData* StructureRareData::create(VM& vm, Structure* previous)
+{
+ StructureRareData* rareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, previous);
+ rareData->finishCreation(vm);
+ return rareData;
+}
+
+StructureRareData* StructureRareData::clone(VM& vm, const StructureRareData* other)
+{
+ StructureRareData* newRareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, other);
+ newRareData->finishCreation(vm);
+ return newRareData;
+}
+
+StructureRareData::StructureRareData(VM& vm, Structure* previous)
+ : JSCell(vm, vm.structureRareDataStructure.get())
+{
+ if (previous)
+ m_previous.set(vm, this, previous);
+}
+
+StructureRareData::StructureRareData(VM& vm, const StructureRareData* other)
+ : JSCell(vm, other->structure())
+{
+ if (other->previousID())
+ m_previous.set(vm, this, other->previousID());
+ if (other->objectToStringValue())
+ m_objectToStringValue.set(vm, this, other->objectToStringValue());
+}
+
+void StructureRareData::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ StructureRareData* thisObject = jsCast<StructureRareData*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
+ ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
+
+ JSCell::visitChildren(thisObject, visitor);
+ visitor.append(&thisObject->m_previous);
+ visitor.append(&thisObject->m_objectToStringValue);
+ visitor.append(&thisObject->m_enumerationCache);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/StructureRareData.h b/Source/JavaScriptCore/runtime/StructureRareData.h
new file mode 100644
index 000000000..e5db9e5f4
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/StructureRareData.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StructureRareData_h
+#define StructureRareData_h
+
+#include "ClassInfo.h"
+#include "JSCell.h"
+#include "JSTypeInfo.h"
+
+namespace JSC {
+
+class JSPropertyNameIterator;
+class Structure;
+
+class StructureRareData : public JSCell {
+ friend class Structure;
+public:
+ static StructureRareData* create(VM&, Structure*);
+ static StructureRareData* clone(VM&, const StructureRareData* other);
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+ // Returns true if this StructureRareData should also be cloned when cloning the owner Structure.
+ bool needsCloning() const { return false; }
+
+ Structure* previousID() const;
+ void setPreviousID(VM&, Structure* transition, Structure*);
+ void clearPreviousID();
+
+ JSString* objectToStringValue() const;
+ void setObjectToStringValue(VM&, const JSCell* owner, JSString* value);
+
+ JSPropertyNameIterator* enumerationCache();
+ void setEnumerationCache(VM&, const Structure* owner, JSPropertyNameIterator* value);
+
+ static JS_EXPORTDATA const ClassInfo s_info;
+
+private:
+ StructureRareData(VM&, Structure*);
+ StructureRareData(VM&, const StructureRareData*);
+
+ static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
+
+ WriteBarrier<Structure> m_previous;
+ WriteBarrier<JSString> m_objectToStringValue;
+ WriteBarrier<JSPropertyNameIterator> m_enumerationCache;
+};
+
+} // namespace JSC
+
+#endif // StructureRareData_h
diff --git a/Source/JavaScriptCore/runtime/StructureRareDataInlines.h b/Source/JavaScriptCore/runtime/StructureRareDataInlines.h
new file mode 100644
index 000000000..20b7f8b12
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/StructureRareDataInlines.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StructureRareDataInlines_h
+#define StructureRareDataInlines_h
+
+#include "StructureRareData.h"
+
+namespace JSC {
+
+inline Structure* StructureRareData::previousID() const
+{
+ return m_previous.get();
+}
+
+inline void StructureRareData::setPreviousID(VM& vm, Structure* transition, Structure* structure)
+{
+ m_previous.set(vm, transition, structure);
+}
+
+inline void StructureRareData::clearPreviousID()
+{
+ m_previous.clear();
+}
+
+inline JSString* StructureRareData::objectToStringValue() const
+{
+ return m_objectToStringValue.get();
+}
+
+inline void StructureRareData::setObjectToStringValue(VM& vm, const JSCell* owner, JSString* value)
+{
+ m_objectToStringValue.set(vm, owner, value);
+}
+
+} // namespace JSC
+
+#endif // StructureRareDataInlines_h
diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
index 5291ed540..601202017 100644
--- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -85,7 +85,7 @@ inline IndexingType newIndexingType(IndexingType oldType, NonPropertyTransition
case AddIndexedAccessors:
return oldType | MayHaveIndexedAccessors;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return oldType;
}
}
@@ -111,21 +111,7 @@ class StructureTransitionTable {
static const bool safeToCompareToEmptyOrDeleted = true;
};
- struct WeakGCMapFinalizerCallback {
- static void* finalizerContextFor(Hash::Key)
- {
- return 0;
- }
-
- static inline Hash::Key keyForFinalizer(void* context, Structure* structure)
- {
- return keyForWeakGCMapFinalizer(context, structure);
- }
- };
-
- typedef WeakGCMap<Hash::Key, Structure, WeakGCMapFinalizerCallback, Hash> TransitionMap;
-
- static Hash::Key keyForWeakGCMapFinalizer(void* context, Structure*);
+ typedef WeakGCMap<Hash::Key, Structure, Hash> TransitionMap;
public:
StructureTransitionTable()
@@ -146,7 +132,7 @@ public:
WeakSet::deallocate(impl);
}
- inline void add(JSGlobalData&, Structure*);
+ inline void add(VM&, Structure*);
inline bool contains(StringImpl* rep, unsigned attributes) const;
inline Structure* get(StringImpl* rep, unsigned attributes) const;
@@ -191,7 +177,7 @@ private:
return 0;
}
- void setSingleTransition(JSGlobalData&, Structure* structure)
+ void setSingleTransition(VM&, Structure* structure)
{
ASSERT(isUsingSingleSlot());
if (WeakImpl* impl = this->weakImpl())
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.cpp b/Source/JavaScriptCore/runtime/SymbolTable.cpp
index 1b7fd89c5..8c5a00b03 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.cpp
+++ b/Source/JavaScriptCore/runtime/SymbolTable.cpp
@@ -38,7 +38,7 @@ SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other)
ASSERT(other.isFat());
FatEntry* newFatEntry = new FatEntry(*other.fatEntry());
freeFatEntry();
- m_bits = bitwise_cast<intptr_t>(newFatEntry) | FatFlag;
+ m_bits = bitwise_cast<intptr_t>(newFatEntry);
return *this;
}
@@ -94,7 +94,7 @@ void SymbolTableEntry::notifyWriteSlow()
SymbolTableEntry::FatEntry* SymbolTableEntry::inflateSlow()
{
FatEntry* entry = new FatEntry(m_bits);
- m_bits = bitwise_cast<intptr_t>(entry) | FatFlag;
+ m_bits = bitwise_cast<intptr_t>(entry);
return entry;
}
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h
index 87d1c8be5..49a00dd39 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.h
+++ b/Source/JavaScriptCore/runtime/SymbolTable.h
@@ -31,375 +31,374 @@
#include "JSObject.h"
#include "Watchpoint.h"
-#include <wtf/AlwaysInline.h>
#include <wtf/HashTraits.h>
#include <wtf/text/StringImpl.h>
namespace JSC {
- class Watchpoint;
- class WatchpointSet;
+class Watchpoint;
+class WatchpointSet;
- struct SlowArgument {
- enum Status {
- Normal = 0,
- Captured = 1,
- Deleted = 2
- };
-
- SlowArgument()
- : status(Normal)
- , index(0)
- {
- }
-
- Status status;
- int index; // If status is 'Deleted', index is bogus.
+struct SlowArgument {
+ enum Status {
+ Normal = 0,
+ Captured = 1,
+ Deleted = 2
};
- static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
-
- // The bit twiddling in this class assumes that every register index is a
- // reasonably small positive or negative number, and therefore has its high
- // four bits all set or all unset.
-
- // In addition to implementing semantics-mandated variable attributes and
- // implementation-mandated variable indexing, this class also implements
- // watchpoints to be used for JIT optimizations. Because watchpoints are
- // meant to be relatively rare, this class optimizes heavily for the case
- // that they are not being used. To that end, this class uses the thin-fat
- // idiom: either it is thin, in which case it contains an in-place encoded
- // word that consists of attributes, the index, and a bit saying that it is
- // thin; or it is fat, in which case it contains a pointer to a malloc'd
- // data structure and a bit saying that it is fat. The malloc'd data
- // structure will be malloced a second time upon copy, to preserve the
- // property that in-place edits to SymbolTableEntry do not manifest in any
- // copies. However, the malloc'd FatEntry data structure contains a ref-
- // counted pointer to a shared WatchpointSet. Thus, in-place edits of the
- // WatchpointSet will manifest in all copies. Here's a picture:
- //
- // SymbolTableEntry --> FatEntry --> WatchpointSet
- //
- // If you make a copy of a SymbolTableEntry, you will have:
- //
- // original: SymbolTableEntry --> FatEntry --> WatchpointSet
- // copy: SymbolTableEntry --> FatEntry -----^
-
- struct SymbolTableEntry {
- // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
- // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
- // and (2) you are in a hot path where you need to minimize the number of times
- // that you branch on isFat() when getting the bits().
- class Fast {
- public:
- Fast()
- : m_bits(0)
- {
- }
-
- ALWAYS_INLINE Fast(const SymbolTableEntry& entry)
- : m_bits(entry.bits())
- {
- }
-
- bool isNull() const
- {
- return !m_bits;
- }
-
- int getIndex() const
- {
- return static_cast<int>(m_bits >> FlagBits);
- }
-
- bool isReadOnly() const
- {
- return m_bits & ReadOnlyFlag;
- }
-
- unsigned getAttributes() const
- {
- unsigned attributes = 0;
- if (m_bits & ReadOnlyFlag)
- attributes |= ReadOnly;
- if (m_bits & DontEnumFlag)
- attributes |= DontEnum;
- return attributes;
- }
-
- bool isFat() const
- {
- return m_bits & FatFlag;
- }
-
- private:
- friend struct SymbolTableEntry;
- intptr_t m_bits;
- };
-
- SymbolTableEntry()
- : m_bits(0)
- {
- }
-
- SymbolTableEntry(int index)
- : m_bits(0)
- {
- ASSERT(isValidIndex(index));
- pack(index, false, false);
- }
-
- SymbolTableEntry(int index, unsigned attributes)
- : m_bits(0)
- {
- ASSERT(isValidIndex(index));
- pack(index, attributes & ReadOnly, attributes & DontEnum);
- }
-
- ~SymbolTableEntry()
- {
- freeFatEntry();
- }
-
- SymbolTableEntry(const SymbolTableEntry& other)
- : m_bits(0)
+ SlowArgument()
+ : status(Normal)
+ , index(0)
+ {
+ }
+
+ Status status;
+ int index; // If status is 'Deleted', index is bogus.
+};
+
+static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
+
+// The bit twiddling in this class assumes that every register index is a
+// reasonably small positive or negative number, and therefore has its high
+// four bits all set or all unset.
+
+// In addition to implementing semantics-mandated variable attributes and
+// implementation-mandated variable indexing, this class also implements
+// watchpoints to be used for JIT optimizations. Because watchpoints are
+// meant to be relatively rare, this class optimizes heavily for the case
+// that they are not being used. To that end, this class uses the thin-fat
+// idiom: either it is thin, in which case it contains an in-place encoded
+// word that consists of attributes, the index, and a bit saying that it is
+// thin; or it is fat, in which case it contains a pointer to a malloc'd
+// data structure and a bit saying that it is fat. The malloc'd data
+// structure will be malloced a second time upon copy, to preserve the
+// property that in-place edits to SymbolTableEntry do not manifest in any
+// copies. However, the malloc'd FatEntry data structure contains a ref-
+// counted pointer to a shared WatchpointSet. Thus, in-place edits of the
+// WatchpointSet will manifest in all copies. Here's a picture:
+//
+// SymbolTableEntry --> FatEntry --> WatchpointSet
+//
+// If you make a copy of a SymbolTableEntry, you will have:
+//
+// original: SymbolTableEntry --> FatEntry --> WatchpointSet
+// copy: SymbolTableEntry --> FatEntry -----^
+
+struct SymbolTableEntry {
+ // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
+ // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
+ // and (2) you are in a hot path where you need to minimize the number of times
+ // that you branch on isFat() when getting the bits().
+ class Fast {
+ public:
+ Fast()
+ : m_bits(SlimFlag)
{
- *this = other;
}
- SymbolTableEntry& operator=(const SymbolTableEntry& other)
+ ALWAYS_INLINE Fast(const SymbolTableEntry& entry)
+ : m_bits(entry.bits())
{
- if (UNLIKELY(other.isFat()))
- return copySlow(other);
- freeFatEntry();
- m_bits = other.m_bits;
- return *this;
}
-
+
bool isNull() const
{
- return !bits();
+ return !(m_bits & ~SlimFlag);
}
int getIndex() const
{
- return static_cast<int>(bits() >> FlagBits);
- }
-
- ALWAYS_INLINE Fast getFast() const
- {
- return Fast(*this);
+ return static_cast<int>(m_bits >> FlagBits);
}
-
- ALWAYS_INLINE Fast getFast(bool& wasFat) const
+
+ bool isReadOnly() const
{
- Fast result;
- wasFat = isFat();
- if (wasFat)
- result.m_bits = fatEntry()->m_bits;
- else
- result.m_bits = m_bits;
- return result;
+ return m_bits & ReadOnlyFlag;
}
unsigned getAttributes() const
{
- return getFast().getAttributes();
- }
-
- void setAttributes(unsigned attributes)
- {
- pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
+ unsigned attributes = 0;
+ if (m_bits & ReadOnlyFlag)
+ attributes |= ReadOnly;
+ if (m_bits & DontEnumFlag)
+ attributes |= DontEnum;
+ return attributes;
}
- bool isReadOnly() const
- {
- return bits() & ReadOnlyFlag;
- }
-
- bool couldBeWatched();
-
- // Notify an opportunity to create a watchpoint for a variable. This is
- // idempotent and fail-silent. It is idempotent in the sense that if
- // a watchpoint set had already been created, then another one will not
- // be created. Hence two calls to this method have the same effect as
- // one call. It is also fail-silent, in the sense that if a watchpoint
- // set had been created and had already been invalidated, then this will
- // just return. This means that couldBeWatched() may return false even
- // immediately after a call to attemptToWatch().
- void attemptToWatch();
-
- bool* addressOfIsWatched();
-
- void addWatchpoint(Watchpoint*);
-
- WatchpointSet* watchpointSet()
- {
- return fatEntry()->m_watchpoints.get();
- }
-
- ALWAYS_INLINE void notifyWrite()
- {
- if (LIKELY(!isFat()))
- return;
- notifyWriteSlow();
- }
-
- private:
- static const intptr_t FatFlag = 0x1;
- static const intptr_t ReadOnlyFlag = 0x2;
- static const intptr_t DontEnumFlag = 0x4;
- static const intptr_t NotNullFlag = 0x8;
- static const intptr_t FlagBits = 4;
-
- class FatEntry {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- FatEntry(intptr_t bits)
- : m_bits(bits | FatFlag)
- {
- }
-
- intptr_t m_bits; // always has FatFlag set and exactly matches what the bits would have been if this wasn't fat.
-
- RefPtr<WatchpointSet> m_watchpoints;
- };
-
- SymbolTableEntry& copySlow(const SymbolTableEntry&);
- JS_EXPORT_PRIVATE void notifyWriteSlow();
-
bool isFat() const
{
- return m_bits & FatFlag;
- }
-
- const FatEntry* fatEntry() const
- {
- ASSERT(isFat());
- return bitwise_cast<const FatEntry*>(m_bits & ~FatFlag);
- }
-
- FatEntry* fatEntry()
- {
- ASSERT(isFat());
- return bitwise_cast<FatEntry*>(m_bits & ~FatFlag);
- }
-
- FatEntry* inflate()
- {
- if (LIKELY(isFat()))
- return fatEntry();
- return inflateSlow();
- }
-
- FatEntry* inflateSlow();
-
- ALWAYS_INLINE intptr_t bits() const
- {
- if (isFat())
- return fatEntry()->m_bits;
- return m_bits;
- }
-
- ALWAYS_INLINE intptr_t& bits()
- {
- if (isFat())
- return fatEntry()->m_bits;
- return m_bits;
- }
-
- void freeFatEntry()
- {
- if (LIKELY(!isFat()))
- return;
- freeFatEntrySlow();
- }
-
- void freeFatEntrySlow();
-
- void pack(int index, bool readOnly, bool dontEnum)
- {
- intptr_t& bitsRef = bits();
- bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag;
- if (readOnly)
- bitsRef |= ReadOnlyFlag;
- if (dontEnum)
- bitsRef |= DontEnumFlag;
+ return !(m_bits & SlimFlag);
}
- bool isValidIndex(int index)
- {
- return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
- }
-
+ private:
+ friend struct SymbolTableEntry;
intptr_t m_bits;
};
- struct SymbolTableIndexHashTraits : HashTraits<SymbolTableEntry> {
- static const bool emptyValueIsZero = true;
- static const bool needsDestruction = true;
- };
-
- typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable;
-
- class SharedSymbolTable : public JSCell, public SymbolTable {
+ SymbolTableEntry()
+ : m_bits(SlimFlag)
+ {
+ }
+
+ SymbolTableEntry(int index)
+ : m_bits(SlimFlag)
+ {
+ ASSERT(isValidIndex(index));
+ pack(index, false, false);
+ }
+
+ SymbolTableEntry(int index, unsigned attributes)
+ : m_bits(SlimFlag)
+ {
+ ASSERT(isValidIndex(index));
+ pack(index, attributes & ReadOnly, attributes & DontEnum);
+ }
+
+ ~SymbolTableEntry()
+ {
+ freeFatEntry();
+ }
+
+ SymbolTableEntry(const SymbolTableEntry& other)
+ : m_bits(SlimFlag)
+ {
+ *this = other;
+ }
+
+ SymbolTableEntry& operator=(const SymbolTableEntry& other)
+ {
+ if (UNLIKELY(other.isFat()))
+ return copySlow(other);
+ freeFatEntry();
+ m_bits = other.m_bits;
+ return *this;
+ }
+
+ bool isNull() const
+ {
+ return !(bits() & ~SlimFlag);
+ }
+
+ int getIndex() const
+ {
+ return static_cast<int>(bits() >> FlagBits);
+ }
+
+ ALWAYS_INLINE Fast getFast() const
+ {
+ return Fast(*this);
+ }
+
+ ALWAYS_INLINE Fast getFast(bool& wasFat) const
+ {
+ Fast result;
+ wasFat = isFat();
+ if (wasFat)
+ result.m_bits = fatEntry()->m_bits | SlimFlag;
+ else
+ result.m_bits = m_bits;
+ return result;
+ }
+
+ unsigned getAttributes() const
+ {
+ return getFast().getAttributes();
+ }
+
+ void setAttributes(unsigned attributes)
+ {
+ pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
+ }
+
+ bool isReadOnly() const
+ {
+ return bits() & ReadOnlyFlag;
+ }
+
+ bool couldBeWatched();
+
+ // Notify an opportunity to create a watchpoint for a variable. This is
+ // idempotent and fail-silent. It is idempotent in the sense that if
+ // a watchpoint set had already been created, then another one will not
+ // be created. Hence two calls to this method have the same effect as
+ // one call. It is also fail-silent, in the sense that if a watchpoint
+ // set had been created and had already been invalidated, then this will
+ // just return. This means that couldBeWatched() may return false even
+ // immediately after a call to attemptToWatch().
+ void attemptToWatch();
+
+ bool* addressOfIsWatched();
+
+ void addWatchpoint(Watchpoint*);
+
+ WatchpointSet* watchpointSet()
+ {
+ return fatEntry()->m_watchpoints.get();
+ }
+
+ ALWAYS_INLINE void notifyWrite()
+ {
+ if (LIKELY(!isFat()))
+ return;
+ notifyWriteSlow();
+ }
+
+private:
+ static const intptr_t SlimFlag = 0x1;
+ static const intptr_t ReadOnlyFlag = 0x2;
+ static const intptr_t DontEnumFlag = 0x4;
+ static const intptr_t NotNullFlag = 0x8;
+ static const intptr_t FlagBits = 4;
+
+ class FatEntry {
+ WTF_MAKE_FAST_ALLOCATED;
public:
- typedef JSCell Base;
-
- static SharedSymbolTable* create(JSGlobalData& globalData)
- {
- SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(globalData.heap)) SharedSymbolTable(globalData);
- sharedSymbolTable->finishCreation(globalData);
- return sharedSymbolTable;
- }
- static const bool needsDestruction = true;
- static const bool hasImmortalStructure = true;
- static void destroy(JSCell*);
-
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
- {
- return Structure::create(globalData, globalObject, prototype, TypeInfo(LeafType, StructureFlags), &s_info);
- }
-
- bool usesNonStrictEval() { return m_usesNonStrictEval; }
- void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
-
- int captureStart() { return m_captureStart; }
- void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
-
- int captureEnd() { return m_captureEnd; }
- void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
-
- int captureCount() { return m_captureEnd - m_captureStart; }
-
- int parameterCount() { return m_parameterCountIncludingThis - 1; }
- int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
- void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
-
- // 0 if we don't capture any arguments; parameterCount() in length if we do.
- const SlowArgument* slowArguments() { return m_slowArguments.get(); }
- void setSlowArguments(PassOwnArrayPtr<SlowArgument> slowArguments) { m_slowArguments = slowArguments; }
-
- static JS_EXPORTDATA const ClassInfo s_info;
-
- private:
- SharedSymbolTable(JSGlobalData& globalData)
- : JSCell(globalData, globalData.sharedSymbolTableStructure.get())
- , m_parameterCountIncludingThis(0)
- , m_usesNonStrictEval(false)
- , m_captureStart(0)
- , m_captureEnd(0)
+ FatEntry(intptr_t bits)
+ : m_bits(bits & ~SlimFlag)
{
}
-
- int m_parameterCountIncludingThis;
- bool m_usesNonStrictEval;
-
- int m_captureStart;
- int m_captureEnd;
-
- OwnArrayPtr<SlowArgument> m_slowArguments;
+
+ intptr_t m_bits; // always has FatFlag set and exactly matches what the bits would have been if this wasn't fat.
+
+ RefPtr<WatchpointSet> m_watchpoints;
};
+
+ SymbolTableEntry& copySlow(const SymbolTableEntry&);
+ JS_EXPORT_PRIVATE void notifyWriteSlow();
+
+ bool isFat() const
+ {
+ return !(m_bits & SlimFlag);
+ }
+
+ const FatEntry* fatEntry() const
+ {
+ ASSERT(isFat());
+ return bitwise_cast<const FatEntry*>(m_bits);
+ }
+
+ FatEntry* fatEntry()
+ {
+ ASSERT(isFat());
+ return bitwise_cast<FatEntry*>(m_bits);
+ }
+
+ FatEntry* inflate()
+ {
+ if (LIKELY(isFat()))
+ return fatEntry();
+ return inflateSlow();
+ }
+
+ FatEntry* inflateSlow();
+
+ ALWAYS_INLINE intptr_t bits() const
+ {
+ if (isFat())
+ return fatEntry()->m_bits;
+ return m_bits;
+ }
+
+ ALWAYS_INLINE intptr_t& bits()
+ {
+ if (isFat())
+ return fatEntry()->m_bits;
+ return m_bits;
+ }
+
+ void freeFatEntry()
+ {
+ if (LIKELY(!isFat()))
+ return;
+ freeFatEntrySlow();
+ }
+
+ JS_EXPORT_PRIVATE void freeFatEntrySlow();
+
+ void pack(int index, bool readOnly, bool dontEnum)
+ {
+ ASSERT(!isFat());
+ intptr_t& bitsRef = bits();
+ bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag | SlimFlag;
+ if (readOnly)
+ bitsRef |= ReadOnlyFlag;
+ if (dontEnum)
+ bitsRef |= DontEnumFlag;
+ }
+
+ bool isValidIndex(int index)
+ {
+ return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
+ }
+
+ intptr_t m_bits;
+};
+
+struct SymbolTableIndexHashTraits : HashTraits<SymbolTableEntry> {
+ static const bool needsDestruction = true;
+};
+
+typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable;
+
+class SharedSymbolTable : public JSCell, public SymbolTable {
+public:
+ typedef JSCell Base;
+
+ static SharedSymbolTable* create(VM& vm)
+ {
+ SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(vm.heap)) SharedSymbolTable(vm);
+ sharedSymbolTable->finishCreation(vm);
+ return sharedSymbolTable;
+ }
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+ static void destroy(JSCell*);
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(LeafType, StructureFlags), &s_info);
+ }
+
+ bool usesNonStrictEval() { return m_usesNonStrictEval; }
+ void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
+
+ int captureStart() { return m_captureStart; }
+ void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
+
+ int captureEnd() { return m_captureEnd; }
+ void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
+
+ int captureCount() { return m_captureEnd - m_captureStart; }
+
+ int parameterCount() { return m_parameterCountIncludingThis - 1; }
+ int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
+ void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
+
+ // 0 if we don't capture any arguments; parameterCount() in length if we do.
+ const SlowArgument* slowArguments() { return m_slowArguments.get(); }
+ void setSlowArguments(PassOwnArrayPtr<SlowArgument> slowArguments) { m_slowArguments = slowArguments; }
+
+ static JS_EXPORTDATA const ClassInfo s_info;
+
+private:
+ SharedSymbolTable(VM& vm)
+ : JSCell(vm, vm.sharedSymbolTableStructure.get())
+ , m_parameterCountIncludingThis(0)
+ , m_usesNonStrictEval(false)
+ , m_captureStart(0)
+ , m_captureEnd(0)
+ {
+ }
+
+ int m_parameterCountIncludingThis;
+ bool m_usesNonStrictEval;
+
+ int m_captureStart;
+ int m_captureEnd;
+
+ OwnArrayPtr<SlowArgument> m_slowArguments;
+};
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Terminator.h b/Source/JavaScriptCore/runtime/Terminator.h
deleted file mode 100644
index 6b0f2366f..000000000
--- a/Source/JavaScriptCore/runtime/Terminator.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Google Inc. ("Google") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Terminator_h
-#define Terminator_h
-
-namespace JSC {
-
-class Terminator {
-public:
- Terminator() : m_shouldTerminate(false) { }
-
- void terminateSoon() { m_shouldTerminate = true; }
- bool shouldTerminate() const { return m_shouldTerminate; }
-
-private:
- bool m_shouldTerminate;
-};
-
-} // namespace JSC
-
-#endif // Terminator_h
diff --git a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
deleted file mode 100644
index 56d6d4b71..000000000
--- a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "TimeoutChecker.h"
-
-#include "CallFrame.h"
-#include "JSGlobalObject.h"
-
-#if OS(DARWIN)
-#include <mach/mach.h>
-#elif OS(WINDOWS)
-#include <windows.h>
-#else
-#include <wtf/CurrentTime.h>
-#endif
-
-using namespace std;
-
-namespace JSC {
-
-// Number of ticks before the first timeout check is done.
-static const int ticksUntilFirstCheck = 1024;
-
-// Number of milliseconds between each timeout check.
-static const int intervalBetweenChecks = 1000;
-
-// Returns the time the current thread has spent executing, in milliseconds.
-static inline unsigned getCPUTime()
-{
-#if OS(DARWIN)
- mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
- thread_basic_info_data_t info;
-
- // Get thread information
- mach_port_t threadPort = mach_thread_self();
- thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
- mach_port_deallocate(mach_task_self(), threadPort);
-
- unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
- time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
-
- return time;
-#elif OS(WINDOWS)
- union {
- FILETIME fileTime;
- unsigned long long fileTimeAsLong;
- } userTime, kernelTime;
-
- // GetThreadTimes won't accept NULL arguments so we pass these even though
- // they're not used.
- FILETIME creationTime, exitTime;
-
- GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
-
- return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
-#elif OS(QNX)
- struct timespec time;
- if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time))
- CRASH();
- return time.tv_sec * 1000.0 + time.tv_nsec / 1.0e6;
-#else
- // FIXME: We should return the time the current thread has spent executing.
-
- // use a relative time from first call in order to avoid an overflow
- static double firstTime = currentTime();
- return static_cast<unsigned> ((currentTime() - firstTime) * 1000);
-#endif
-}
-
-TimeoutChecker::TimeoutChecker()
- : m_timeoutInterval(0)
- , m_startCount(0)
-{
- reset();
-}
-
-void TimeoutChecker::reset()
-{
- m_ticksUntilNextCheck = ticksUntilFirstCheck;
- m_timeAtLastCheck = 0;
- m_timeExecuting = 0;
-}
-
-bool TimeoutChecker::didTimeOut(ExecState* exec)
-{
- unsigned currentTime = getCPUTime();
-
- if (!m_timeAtLastCheck) {
- // Suspicious amount of looping in a script -- start timing it
- m_timeAtLastCheck = currentTime;
- return false;
- }
-
- unsigned timeDiff = currentTime - m_timeAtLastCheck;
-
- if (timeDiff == 0)
- timeDiff = 1;
-
- m_timeExecuting += timeDiff;
- m_timeAtLastCheck = currentTime;
-
- // Adjust the tick threshold so we get the next checkTimeout call in the
- // interval specified in intervalBetweenChecks.
- m_ticksUntilNextCheck = static_cast<unsigned>((static_cast<float>(intervalBetweenChecks) / timeDiff) * m_ticksUntilNextCheck);
- // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
- // preferred script check time interval.
- if (m_ticksUntilNextCheck == 0)
- m_ticksUntilNextCheck = ticksUntilFirstCheck;
-
- if (m_timeoutInterval && m_timeExecuting > m_timeoutInterval) {
- if (exec->dynamicGlobalObject()->globalObjectMethodTable()->shouldInterruptScript(exec->dynamicGlobalObject()))
- return true;
-
- reset();
- }
-
- return false;
-}
-
-} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/TimeoutChecker.h b/Source/JavaScriptCore/runtime/TimeoutChecker.h
deleted file mode 100644
index 89d6158cc..000000000
--- a/Source/JavaScriptCore/runtime/TimeoutChecker.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TimeoutChecker_h
-#define TimeoutChecker_h
-
-#include <wtf/Assertions.h>
-
-namespace JSC {
-
- class ExecState;
-
- class TimeoutChecker {
- public:
- TimeoutChecker();
-
- void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; }
- unsigned timeoutInterval() const { return m_timeoutInterval; }
-
- unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; }
-
- void start()
- {
- if (!m_startCount)
- reset();
- ++m_startCount;
- }
-
- void stop()
- {
- ASSERT(m_startCount);
- --m_startCount;
- }
-
- JS_EXPORT_PRIVATE void reset();
-
- JS_EXPORT_PRIVATE bool didTimeOut(ExecState*);
-
- private:
- unsigned m_timeoutInterval;
- unsigned m_timeAtLastCheck;
- unsigned m_timeExecuting;
- unsigned m_startCount;
- unsigned m_ticksUntilNextCheck;
- };
-
-} // namespace JSC
-
-#endif // TimeoutChecker_h
diff --git a/Source/JavaScriptCore/runtime/Uint16WithFraction.h b/Source/JavaScriptCore/runtime/Uint16WithFraction.h
index 0e5c5f91c..9a30100eb 100644
--- a/Source/JavaScriptCore/runtime/Uint16WithFraction.h
+++ b/Source/JavaScriptCore/runtime/Uint16WithFraction.h
@@ -41,7 +41,7 @@ class Uint16WithFraction {
public:
explicit Uint16WithFraction(double number, uint16_t divideByExponent = 0)
{
- ASSERT(number && isfinite(number) && !signbit(number));
+ ASSERT(number && std::isfinite(number) && !std::signbit(number));
// Check for values out of uint16_t range.
if (number >= oneGreaterThanMaxUInt16) {
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/VM.cpp
index 74429c7a7..3ca134ba2 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/VM.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,11 +27,12 @@
*/
#include "config.h"
-#include "JSGlobalData.h"
+#include "VM.h"
#include "ArgList.h"
#include "CodeCache.h"
#include "CommonIdentifiers.h"
+#include "DFGLongLivedState.h"
#include "DebuggerActivation.h"
#include "FunctionConstructor.h"
#include "GCActivityCallback.h"
@@ -43,7 +44,6 @@
#include "JSActivation.h"
#include "JSAPIValueWrapper.h"
#include "JSArray.h"
-#include "JSClassRef.h"
#include "JSFunction.h"
#include "JSLock.h"
#include "JSNameScope.h"
@@ -56,10 +56,13 @@
#include "ParserArena.h"
#include "RegExpCache.h"
#include "RegExpObject.h"
+#include "SourceProviderCache.h"
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
#include "UnlinkedCodeBlock.h"
+#include <wtf/ProcessID.h>
#include <wtf/RetainPtr.h>
+#include <wtf/StringPrintStream.h>
#include <wtf/Threading.h>
#include <wtf/WTFThreadData.h>
@@ -91,12 +94,10 @@ extern const HashTable mathTable;
extern const HashTable numberConstructorTable;
extern const HashTable numberPrototypeTable;
JS_EXPORTDATA extern const HashTable objectConstructorTable;
-extern const HashTable objectPrototypeTable;
extern const HashTable privateNamePrototypeTable;
extern const HashTable regExpTable;
extern const HashTable regExpConstructorTable;
extern const HashTable regExpPrototypeTable;
-extern const HashTable stringTable;
extern const HashTable stringConstructorTable;
// Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either
@@ -113,12 +114,12 @@ static bool enableAssembler(ExecutableAllocator& executableAllocator)
#if COMPILER(GCC) && !COMPILER(CLANG)
// FIXME: remove this once the EWS have been upgraded to LLVM.
// Work around a bug of GCC with strict-aliasing.
- RetainPtr<CFStringRef> canUseJITKeyRetain(AdoptCF, CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman));
+ RetainPtr<CFStringRef> canUseJITKeyRetain = adoptCF(CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman));
CFStringRef canUseJITKey = canUseJITKeyRetain.get();
#else
CFStringRef canUseJITKey = CFSTR("JavaScriptCoreUseJIT");
#endif // COMPILER(GCC) && !COMPILER(CLANG)
- RetainPtr<CFBooleanRef> canUseJIT(AdoptCF, (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication));
+ RetainPtr<CFTypeRef> canUseJIT = adoptCF(CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication));
if (canUseJIT)
return kCFBooleanTrue == canUseJIT.get();
#endif
@@ -132,13 +133,13 @@ static bool enableAssembler(ExecutableAllocator& executableAllocator)
}
#endif // ENABLE(!ASSEMBLER)
-JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
- :
+VM::VM(VMType vmType, HeapType heapType)
+ : m_apiLock(adoptRef(new JSLock(this)))
#if ENABLE(ASSEMBLER)
- executableAllocator(*this),
+ , executableAllocator(*this)
#endif
- heap(this, heapType)
- , globalDataType(globalDataType)
+ , heap(this, heapType)
+ , vmType(vmType)
, clientData(0)
, topCallFrame(CallFrame::noCaller())
, arrayConstructorTable(fastNew<HashTable>(JSC::arrayConstructorTable))
@@ -153,14 +154,12 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
, numberConstructorTable(fastNew<HashTable>(JSC::numberConstructorTable))
, numberPrototypeTable(fastNew<HashTable>(JSC::numberPrototypeTable))
, objectConstructorTable(fastNew<HashTable>(JSC::objectConstructorTable))
- , objectPrototypeTable(fastNew<HashTable>(JSC::objectPrototypeTable))
, privateNamePrototypeTable(fastNew<HashTable>(JSC::privateNamePrototypeTable))
, regExpTable(fastNew<HashTable>(JSC::regExpTable))
, regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
, regExpPrototypeTable(fastNew<HashTable>(JSC::regExpPrototypeTable))
- , stringTable(fastNew<HashTable>(JSC::stringTable))
, stringConstructorTable(fastNew<HashTable>(JSC::stringConstructorTable))
- , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
+ , identifierTable(vmType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
, parserArena(adoptPtr(new ParserArena))
@@ -172,7 +171,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
, sizeOfLastScratchBuffer(0)
#endif
, dynamicGlobalObject(0)
- , cachedUTCOffset(QNaN)
, m_enabledProfiler(0)
, m_regExpCache(new RegExpCache(this))
#if ENABLE(REGEXP_TRACING)
@@ -181,10 +179,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
#ifndef NDEBUG
, exclusiveThread(0)
#endif
-#if CPU(X86) && ENABLE(JIT)
- , m_timeoutCount(512)
-#endif
- , m_newStringsSinceLastHashConst(0)
+ , m_newStringsSinceLastHashCons(0)
#if ENABLE(ASSEMBLER)
, m_canUseAssembler(enableAssembler(executableAllocator))
#endif
@@ -198,7 +193,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
, m_initializingObjectClass(0)
#endif
, m_inDefineOwnProperty(false)
- , m_codeCache(CodeCache::create())
+ , m_codeCache(CodeCache::create(CodeCache::GlobalCodeCache))
{
interpreter = new Interpreter(*this);
@@ -206,8 +201,8 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
JSLockHolder lock(this);
IdentifierTable* existingEntryIdentifierTable = wtfThreadData().setCurrentIdentifierTable(identifierTable);
structureStructure.set(*this, Structure::createStructure(*this));
+ structureRareDataStructure.set(*this, StructureRareData::createStructure(*this, 0, jsNull()));
debuggerActivationStructure.set(*this, DebuggerActivation::createStructure(*this, 0, jsNull()));
- interruptedExecutionErrorStructure.set(*this, InterruptedExecutionError::createStructure(*this, 0, jsNull()));
terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull()));
stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull()));
notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, 0, jsNull()));
@@ -229,11 +224,14 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull()));
unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull()));
unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
+ propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
+ smallStrings.initializeCommonStrings(*this);
wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
#if ENABLE(JIT)
- jitStubs = adoptPtr(new JITThunks(this));
+ jitStubs = adoptPtr(new JITThunks());
+ performPlatformSpecificJITAssertions(this);
#endif
interpreter->initialize(this->canUseJIT());
@@ -243,14 +241,36 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
#endif
heap.notifyIsSafeToCollect();
-
+
LLInt::Data::performAssertions(*this);
+
+ if (Options::enableProfiler()) {
+ m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*this));
+
+ StringPrintStream pathOut;
+#if !OS(WINCE)
+ const char* profilerPath = getenv("JSC_PROFILER_PATH");
+ if (profilerPath)
+ pathOut.print(profilerPath, "/");
+#endif
+ pathOut.print("JSCProfile-", getCurrentProcessID(), "-", m_perBytecodeProfiler->databaseID(), ".json");
+ m_perBytecodeProfiler->registerToSaveAtExit(pathOut.toCString().data());
+ }
+
+#if ENABLE(DFG_JIT)
+ if (canUseJIT())
+ m_dfgState = adoptPtr(new DFG::LongLivedState());
+#endif
}
-JSGlobalData::~JSGlobalData()
+VM::~VM()
{
- ASSERT(!m_apiLock.currentThreadIsHoldingLock());
- heap.didStartVMShutdown();
+ // Clear this first to ensure that nobody tries to remove themselves from it.
+ m_perBytecodeProfiler.clear();
+
+ ASSERT(m_apiLock->currentThreadIsHoldingLock());
+ m_apiLock->willDestroyVM(this);
+ heap.lastChanceToFinalize();
delete interpreter;
#ifndef NDEBUG
@@ -269,12 +289,10 @@ JSGlobalData::~JSGlobalData()
numberConstructorTable->deleteTable();
numberPrototypeTable->deleteTable();
objectConstructorTable->deleteTable();
- objectPrototypeTable->deleteTable();
privateNamePrototypeTable->deleteTable();
regExpTable->deleteTable();
regExpConstructorTable->deleteTable();
regExpPrototypeTable->deleteTable();
- stringTable->deleteTable();
stringConstructorTable->deleteTable();
fastDelete(const_cast<HashTable*>(arrayConstructorTable));
@@ -289,20 +307,16 @@ JSGlobalData::~JSGlobalData()
fastDelete(const_cast<HashTable*>(numberConstructorTable));
fastDelete(const_cast<HashTable*>(numberPrototypeTable));
fastDelete(const_cast<HashTable*>(objectConstructorTable));
- fastDelete(const_cast<HashTable*>(objectPrototypeTable));
fastDelete(const_cast<HashTable*>(privateNamePrototypeTable));
fastDelete(const_cast<HashTable*>(regExpTable));
fastDelete(const_cast<HashTable*>(regExpConstructorTable));
fastDelete(const_cast<HashTable*>(regExpPrototypeTable));
- fastDelete(const_cast<HashTable*>(stringTable));
fastDelete(const_cast<HashTable*>(stringConstructorTable));
- opaqueJSClassData.clear();
-
delete emptyList;
delete propertyNames;
- if (globalDataType != Default)
+ if (vmType != Default)
deleteIdentifierTable(identifierTable);
delete clientData;
@@ -317,40 +331,40 @@ JSGlobalData::~JSGlobalData()
#endif
}
-PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(HeapType heapType)
+PassRefPtr<VM> VM::createContextGroup(HeapType heapType)
{
- return adoptRef(new JSGlobalData(APIContextGroup, heapType));
+ return adoptRef(new VM(APIContextGroup, heapType));
}
-PassRefPtr<JSGlobalData> JSGlobalData::create(HeapType heapType)
+PassRefPtr<VM> VM::create(HeapType heapType)
{
- return adoptRef(new JSGlobalData(Default, heapType));
+ return adoptRef(new VM(Default, heapType));
}
-PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(HeapType heapType)
+PassRefPtr<VM> VM::createLeaked(HeapType heapType)
{
return create(heapType);
}
-bool JSGlobalData::sharedInstanceExists()
+bool VM::sharedInstanceExists()
{
return sharedInstanceInternal();
}
-JSGlobalData& JSGlobalData::sharedInstance()
+VM& VM::sharedInstance()
{
GlobalJSLock globalLock;
- JSGlobalData*& instance = sharedInstanceInternal();
+ VM*& instance = sharedInstanceInternal();
if (!instance) {
- instance = adoptRef(new JSGlobalData(APIShared, SmallHeap)).leakRef();
+ instance = adoptRef(new VM(APIShared, SmallHeap)).leakRef();
instance->makeUsableFromMultipleThreads();
}
return *instance;
}
-JSGlobalData*& JSGlobalData::sharedInstanceInternal()
+VM*& VM::sharedInstanceInternal()
{
- static JSGlobalData* sharedInstance;
+ static VM* sharedInstance;
return sharedInstance;
}
@@ -380,52 +394,60 @@ static ThunkGenerator thunkGeneratorForIntrinsic(Intrinsic intrinsic)
return expThunkGenerator;
case LogIntrinsic:
return logThunkGenerator;
+ case IMulIntrinsic:
+ return imulThunkGenerator;
default:
return 0;
}
}
-NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
+NativeExecutable* VM::getHostFunction(NativeFunction function, NativeFunction constructor)
{
return jitStubs->hostFunctionStub(this, function, constructor);
}
-NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, Intrinsic intrinsic)
+NativeExecutable* VM::getHostFunction(NativeFunction function, Intrinsic intrinsic)
{
ASSERT(canUseJIT());
return jitStubs->hostFunctionStub(this, function, intrinsic != NoIntrinsic ? thunkGeneratorForIntrinsic(intrinsic) : 0, intrinsic);
}
#else // !ENABLE(JIT)
-NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
+NativeExecutable* VM::getHostFunction(NativeFunction function, NativeFunction constructor)
{
return NativeExecutable::create(*this, function, constructor);
}
#endif // !ENABLE(JIT)
-JSGlobalData::ClientData::~ClientData()
+VM::ClientData::~ClientData()
{
}
-void JSGlobalData::resetDateCache()
+void VM::resetDateCache()
{
- cachedUTCOffset = QNaN;
- dstOffsetCache.reset();
+ localTimeOffsetCache.reset();
cachedDateString = String();
cachedDateStringValue = QNaN;
dateInstanceCache.reset();
}
-void JSGlobalData::startSampling()
+void VM::startSampling()
{
interpreter->startSampling();
}
-void JSGlobalData::stopSampling()
+void VM::stopSampling()
{
interpreter->stopSampling();
}
-void JSGlobalData::dumpSampleData(ExecState* exec)
+void VM::discardAllCode()
+{
+ m_codeCache->clear();
+ heap.deleteAllCompiledCode();
+ heap.reportAbandonedObjectGraph();
+}
+
+void VM::dumpSampleData(ExecState* exec)
{
interpreter->dumpSampleData(exec);
#if ENABLE(ASSEMBLER)
@@ -433,6 +455,19 @@ void JSGlobalData::dumpSampleData(ExecState* exec)
#endif
}
+SourceProviderCache* VM::addSourceProviderCache(SourceProvider* sourceProvider)
+{
+ SourceProviderCacheMap::AddResult addResult = sourceProviderCacheMap.add(sourceProvider, 0);
+ if (addResult.isNewEntry)
+ addResult.iterator->value = adoptRef(new SourceProviderCache);
+ return addResult.iterator->value.get();
+}
+
+void VM::clearSourceProviderCaches()
+{
+ sourceProviderCacheMap.clear();
+}
+
struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor {
HashSet<FunctionExecutable*> currentlyExecutingFunctions;
void operator()(JSCell* cell)
@@ -446,11 +481,12 @@ struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor {
}
};
-void JSGlobalData::releaseExecutableMemory()
+void VM::releaseExecutableMemory()
{
if (dynamicGlobalObject) {
StackPreservingRecompiler recompiler;
HashSet<JSCell*> roots;
+ heap.canonicalizeCellLivenessData();
heap.getConservativeRegisterRoots(roots);
HashSet<JSCell*>::iterator end = roots.end();
for (HashSet<JSCell*>::iterator ptr = roots.begin(); ptr != end; ++ptr) {
@@ -476,14 +512,19 @@ void JSGlobalData::releaseExecutableMemory()
m_regExpCache->invalidateCode();
heap.collectAllGarbage();
}
+
+void VM::clearExceptionStack()
+{
+ m_exceptionStack = RefCountedArray<StackFrame>();
+}
-void releaseExecutableMemory(JSGlobalData& globalData)
+void releaseExecutableMemory(VM& vm)
{
- globalData.releaseExecutableMemory();
+ vm.releaseExecutableMemory();
}
#if ENABLE(DFG_JIT)
-void JSGlobalData::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
+void VM::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
{
for (size_t i = 0; i < scratchBuffers.size(); i++) {
ScratchBuffer* scratchBuffer = scratchBuffers[i];
@@ -496,12 +537,12 @@ void JSGlobalData::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
#endif
#if ENABLE(REGEXP_TRACING)
-void JSGlobalData::addRegExpToTrace(RegExp* regExp)
+void VM::addRegExpToTrace(RegExp* regExp)
{
m_rtTraceList->add(regExp);
}
-void JSGlobalData::dumpRegExpTrace()
+void VM::dumpRegExpTrace()
{
// The first RegExp object is ignored. It is create by the RegExpPrototype ctor and not used.
RTTraceList::iterator iter = ++m_rtTraceList->begin();
@@ -523,7 +564,7 @@ void JSGlobalData::dumpRegExpTrace()
m_rtTraceList->clear();
}
#else
-void JSGlobalData::dumpRegExpTrace()
+void VM::dumpRegExpTrace()
{
}
#endif
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/VM.h
index 01e6059da..dcd525107 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.h
+++ b/Source/JavaScriptCore/runtime/VM.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,29 +26,35 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef JSGlobalData_h
-#define JSGlobalData_h
+#ifndef VM_h
+#define VM_h
#include "CachedTranscendentalFunction.h"
#include "DateInstanceCache.h"
#include "ExecutableAllocator.h"
#include "Heap.h"
#include "Intrinsic.h"
-#include "JITStubs.h"
+#include "JITThunks.h"
+#include "JITThunks.h"
+#include "JSCJSValue.h"
#include "JSLock.h"
-#include "JSValue.h"
#include "LLIntData.h"
+#include "MacroAssemblerCodeRef.h"
#include "NumericStrings.h"
+#include "ProfilerDatabase.h"
#include "PrivateName.h"
+#include "PrototypeMap.h"
#include "SmallStrings.h"
#include "Strong.h"
-#include "Terminator.h"
-#include "TimeoutChecker.h"
+#include "ThunkGenerators.h"
#include "TypedArrayDescriptor.h"
+#include "Watchdog.h"
#include "WeakRandom.h"
#include <wtf/BumpPointerAllocator.h>
+#include <wtf/DateMath.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
+#include <wtf/RefCountedArray.h>
#include <wtf/SimpleStats.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/ThreadSpecific.h>
@@ -57,14 +63,12 @@
#include <wtf/ListHashSet.h>
#endif
-struct OpaqueJSClass;
-struct OpaqueJSClassContextData;
-
namespace JSC {
class CodeBlock;
class CodeCache;
class CommonIdentifiers;
+ class ExecState;
class HandleStack;
class IdentifierTable;
class Interpreter;
@@ -72,10 +76,13 @@ namespace JSC {
class JSObject;
class Keywords;
class LLIntOffsetsExtractor;
+ class LegacyProfiler;
class NativeExecutable;
class ParserArena;
- class Profiler;
class RegExpCache;
+ class SourceProvider;
+ class SourceProviderCache;
+ struct StackFrame;
class Stringifier;
class Structure;
#if ENABLE(REGEXP_TRACING)
@@ -86,24 +93,32 @@ namespace JSC {
class UnlinkedFunctionExecutable;
class UnlinkedProgramCodeBlock;
+#if ENABLE(DFG_JIT)
+ namespace DFG {
+ class LongLivedState;
+ }
+#endif // ENABLE(DFG_JIT)
+
struct HashTable;
struct Instruction;
- struct DSTOffsetCache {
- DSTOffsetCache()
+ struct LocalTimeOffsetCache {
+ LocalTimeOffsetCache()
+ : start(0.0)
+ , end(-1.0)
+ , increment(0.0)
{
- reset();
}
void reset()
{
- offset = 0.0;
+ offset = LocalTimeOffset();
start = 0.0;
end = -1.0;
increment = 0.0;
}
- double offset;
+ LocalTimeOffset offset;
double start;
double end;
double increment;
@@ -118,8 +133,8 @@ namespace JSC {
#endif
struct ScratchBuffer {
ScratchBuffer()
- : m_activeLength(0)
{
+ u.m_activeLength = 0;
}
static ScratchBuffer* create(size_t size)
@@ -130,12 +145,15 @@ namespace JSC {
}
static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
- void setActiveLength(size_t activeLength) { m_activeLength = activeLength; }
- size_t activeLength() const { return m_activeLength; };
- size_t* activeLengthPtr() { return &m_activeLength; };
+ void setActiveLength(size_t activeLength) { u.m_activeLength = activeLength; }
+ size_t activeLength() const { return u.m_activeLength; };
+ size_t* activeLengthPtr() { return &u.m_activeLength; };
void* dataBuffer() { return m_buffer; }
- size_t m_activeLength;
+ union {
+ size_t m_activeLength;
+ double pad; // Make sure m_buffer is double aligned.
+ } u;
#if CPU(MIPS) && (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == 2)
void* m_buffer[0] __attribute__((aligned(8)));
#else
@@ -147,36 +165,36 @@ namespace JSC {
#endif
#endif
- class JSGlobalData : public ThreadSafeRefCounted<JSGlobalData> {
+ class VM : public ThreadSafeRefCounted<VM> {
public:
- // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
+ // WebCore has a one-to-one mapping of threads to VMs;
// either create() or createLeaked() should only be called once
- // on a thread, this is the 'default' JSGlobalData (it uses the
+ // on a thread, this is the 'default' VM (it uses the
// thread's default string uniquing table from wtfThreadData).
// API contexts created using the new context group aware interface
// create APIContextGroup objects which require less locking of JSC
- // than the old singleton APIShared JSGlobalData created for use by
+ // than the old singleton APIShared VM created for use by
// the original API.
- enum GlobalDataType { Default, APIContextGroup, APIShared };
+ enum VMType { Default, APIContextGroup, APIShared };
struct ClientData {
JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
};
- bool isSharedInstance() { return globalDataType == APIShared; }
- bool usingAPI() { return globalDataType != Default; }
+ bool isSharedInstance() { return vmType == APIShared; }
+ bool usingAPI() { return vmType != Default; }
static bool sharedInstanceExists();
- JS_EXPORT_PRIVATE static JSGlobalData& sharedInstance();
+ JS_EXPORT_PRIVATE static VM& sharedInstance();
- JS_EXPORT_PRIVATE static PassRefPtr<JSGlobalData> create(HeapType = SmallHeap);
- JS_EXPORT_PRIVATE static PassRefPtr<JSGlobalData> createLeaked(HeapType = SmallHeap);
- static PassRefPtr<JSGlobalData> createContextGroup(HeapType = SmallHeap);
- JS_EXPORT_PRIVATE ~JSGlobalData();
+ JS_EXPORT_PRIVATE static PassRefPtr<VM> create(HeapType = SmallHeap);
+ JS_EXPORT_PRIVATE static PassRefPtr<VM> createLeaked(HeapType = SmallHeap);
+ static PassRefPtr<VM> createContextGroup(HeapType = SmallHeap);
+ JS_EXPORT_PRIVATE ~VM();
void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
private:
- JSLock m_apiLock;
+ RefPtr<JSLock> m_apiLock;
public:
#if ENABLE(ASSEMBLER)
@@ -188,10 +206,15 @@ namespace JSC {
// The heap should be just after executableAllocator and before other members to ensure that it's
// destructed after all the objects that reference it.
Heap heap;
+
+#if ENABLE(DFG_JIT)
+ OwnPtr<DFG::LongLivedState> m_dfgState;
+#endif // ENABLE(DFG_JIT)
- GlobalDataType globalDataType;
+ VMType vmType;
ClientData* clientData;
- CallFrame* topCallFrame;
+ ExecState* topCallFrame;
+ Watchdog watchdog;
const HashTable* arrayConstructorTable;
const HashTable* arrayPrototypeTable;
@@ -205,17 +228,15 @@ namespace JSC {
const HashTable* numberConstructorTable;
const HashTable* numberPrototypeTable;
const HashTable* objectConstructorTable;
- const HashTable* objectPrototypeTable;
const HashTable* privateNamePrototypeTable;
const HashTable* regExpTable;
const HashTable* regExpConstructorTable;
const HashTable* regExpPrototypeTable;
- const HashTable* stringTable;
const HashTable* stringConstructorTable;
Strong<Structure> structureStructure;
+ Strong<Structure> structureRareDataStructure;
Strong<Structure> debuggerActivationStructure;
- Strong<Structure> interruptedExecutionErrorStructure;
Strong<Structure> terminatedExecutionErrorStructure;
Strong<Structure> stringStructure;
Strong<Structure> notAnObjectStructure;
@@ -237,6 +258,7 @@ namespace JSC {
Strong<Structure> unlinkedProgramCodeBlockStructure;
Strong<Structure> unlinkedEvalCodeBlockStructure;
Strong<Structure> unlinkedFunctionCodeBlockStructure;
+ Strong<Structure> propertyTableStructure;
IdentifierTable* identifierTable;
CommonIdentifiers* propertyNames;
@@ -267,7 +289,7 @@ namespace JSC {
return m_inDefineOwnProperty;
}
- Profiler* enabledProfiler()
+ LegacyProfiler* enabledProfiler()
{
return m_enabledProfiler;
}
@@ -286,9 +308,14 @@ namespace JSC {
bool canUseRegExpJIT() { return false; } // interpreter only
#endif
- PrivateName m_inheritorIDKey;
+ SourceProviderCache* addSourceProviderCache(SourceProvider*);
+ void clearSourceProviderCaches();
+
+ PrototypeMap prototypeMap;
OwnPtr<ParserArena> parserArena;
+ typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache> > SourceProviderCacheMap;
+ SourceProviderCacheMap sourceProviderCacheMap;
OwnPtr<Keywords> keywords;
Interpreter* interpreter;
#if ENABLE(JIT)
@@ -301,17 +328,16 @@ namespace JSC {
#endif
NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
- TimeoutChecker timeoutChecker;
- Terminator terminator;
-
JSValue exception;
+ JS_EXPORT_PRIVATE void clearExceptionStack();
+ RefCountedArray<StackFrame>& exceptionStack() { return m_exceptionStack; }
const ClassInfo* const jsArrayClassInfo;
const ClassInfo* const jsFinalObjectClassInfo;
ReturnAddressPtr exceptionLocation;
JSValue hostCallReturnValue;
- CallFrame* callFrameForThrow;
+ ExecState* callFrameForThrow;
void* targetMachinePCForThrow;
Instruction* targetInterpreterPCForThrow;
#if ENABLE(DFG_JIT)
@@ -343,19 +369,17 @@ namespace JSC {
void gatherConservativeRoots(ConservativeRoots&);
#endif
- HashMap<OpaqueJSClass*, OwnPtr<OpaqueJSClassContextData> > opaqueJSClassData;
-
JSGlobalObject* dynamicGlobalObject;
HashSet<JSObject*> stringRecursionCheckVisitedObjects;
- double cachedUTCOffset;
- DSTOffsetCache dstOffsetCache;
+ LocalTimeOffsetCache localTimeOffsetCache;
String cachedDateString;
double cachedDateStringValue;
- Profiler* m_enabledProfiler;
+ LegacyProfiler* m_enabledProfiler;
+ OwnPtr<Profiler::Database> m_perBytecodeProfiler;
RegExpCache* m_regExpCache;
BumpPointerAllocator m_regExpAllocator;
@@ -368,7 +392,7 @@ namespace JSC {
ThreadIdentifier exclusiveThread;
#endif
- CachedTranscendentalFunction<sin> cachedSin;
+ CachedTranscendentalFunction<std::sin> cachedSin;
JS_EXPORT_PRIVATE void resetDateCache();
@@ -389,16 +413,12 @@ namespace JSC {
void setInitializingObjectClass(const ClassInfo*);
#endif
-#if CPU(X86) && ENABLE(JIT)
- unsigned m_timeoutCount;
-#endif
-
- unsigned m_newStringsSinceLastHashConst;
+ unsigned m_newStringsSinceLastHashCons;
- static const unsigned s_minNumberOfNewStringsToHashConst = 100;
+ static const unsigned s_minNumberOfNewStringsToHashCons = 100;
- bool haveEnoughNewStringsToHashConst() { return m_newStringsSinceLastHashConst > s_minNumberOfNewStringsToHashConst; }
- void resetNewStringsSinceLastHashConst() { m_newStringsSinceLastHashConst = 0; }
+ bool haveEnoughNewStringsToHashCons() { return m_newStringsSinceLastHashCons > s_minNumberOfNewStringsToHashCons; }
+ void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; }
#define registerTypedArrayFunction(type, capitalizedType) \
void registerTypedArrayDescriptor(const capitalizedType##Array*, const TypedArrayDescriptor& descriptor) \
@@ -449,14 +469,16 @@ namespace JSC {
}
}
- JSLock& apiLock() { return m_apiLock; }
+ JSLock& apiLock() { return *m_apiLock; }
CodeCache* codeCache() { return m_codeCache.get(); }
+ JS_EXPORT_PRIVATE void discardAllCode();
+
private:
friend class LLIntOffsetsExtractor;
- JSGlobalData(GlobalDataType, HeapType);
- static JSGlobalData*& sharedInstanceInternal();
+ VM(VMType, HeapType);
+ static VM*& sharedInstanceInternal();
void createNativeThunk();
#if ENABLE(ASSEMBLER)
bool m_canUseAssembler;
@@ -471,7 +493,8 @@ namespace JSC {
const ClassInfo* m_initializingObjectClass;
#endif
bool m_inDefineOwnProperty;
- OwnPtr<CodeCache> m_codeCache;
+ RefPtr<CodeCache> m_codeCache;
+ RefCountedArray<StackFrame> m_exceptionStack;
TypedArrayDescriptor m_int8ArrayDescriptor;
TypedArrayDescriptor m_int16ArrayDescriptor;
@@ -485,12 +508,12 @@ namespace JSC {
};
#if ENABLE(GC_VALIDATION)
- inline bool JSGlobalData::isInitializingObject() const
+ inline bool VM::isInitializingObject() const
{
return !!m_initializingObjectClass;
}
- inline void JSGlobalData::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
+ inline void VM::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
{
m_initializingObjectClass = initializingObjectClass;
}
@@ -498,9 +521,9 @@ namespace JSC {
inline Heap* WeakSet::heap() const
{
- return &m_globalData->heap;
+ return &m_vm->heap;
}
} // namespace JSC
-#endif // JSGlobalData_h
+#endif // VM_h
diff --git a/Source/JavaScriptCore/runtime/VMStackBounds.h b/Source/JavaScriptCore/runtime/VMStackBounds.h
new file mode 100644
index 000000000..76a3ebd30
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/VMStackBounds.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VMStackBounds_h
+#define VMStackBounds_h
+
+#include "VM.h"
+#include <wtf/StackBounds.h>
+
+namespace JSC {
+
+class VMStackBounds {
+public:
+ VMStackBounds(VM& vm, const StackBounds& bounds)
+ : m_vm(vm)
+ , m_bounds(bounds)
+ {
+ }
+
+ bool isSafeToRecurse() const { return m_bounds.isSafeToRecurse(requiredCapacity()); }
+
+private:
+ inline size_t requiredCapacity() const
+ {
+ Interpreter* interpreter = m_vm.interpreter;
+
+ // We have two separate stack limits, one for regular JS execution, and one
+ // for when we're handling errors. We need the error stack to be smaller
+ // otherwise there would obviously not be any stack left to execute JS in when
+ // there's a stack overflow.
+ //
+ // These sizes were derived from the stack usage of a number of sites when
+ // layout occurs when we've already consumed most of the C stack.
+ const size_t requiredStack = 128 * KB;
+ const size_t errorModeRequiredStack = 64 * KB;
+
+ size_t requiredCapacity = interpreter->isInErrorHandlingMode() ? errorModeRequiredStack : requiredStack;
+ RELEASE_ASSERT(m_bounds.size() >= requiredCapacity);
+ return requiredCapacity;
+ }
+
+ VM& m_vm;
+ const StackBounds& m_bounds;
+};
+
+} // namespace JSC
+
+#endif // VMStackBounds_h
+
diff --git a/Source/JavaScriptCore/runtime/Watchdog.cpp b/Source/JavaScriptCore/runtime/Watchdog.cpp
new file mode 100644
index 000000000..573260b16
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/Watchdog.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Watchdog.h"
+
+#include "CallFrame.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+#define NO_LIMIT std::numeric_limits<double>::infinity()
+
+Watchdog::Watchdog()
+ : m_timerDidFire(false)
+ , m_didFire(false)
+ , m_limit(NO_LIMIT)
+ , m_startTime(0)
+ , m_elapsedTime(0)
+ , m_reentryCount(0)
+ , m_isStopped(true)
+ , m_callback(0)
+ , m_callbackData1(0)
+ , m_callbackData2(0)
+{
+ initTimer();
+}
+
+Watchdog::~Watchdog()
+{
+ ASSERT(!isArmed());
+ stopCountdown();
+ destroyTimer();
+}
+
+void Watchdog::setTimeLimit(VM& vm, double limit,
+ ShouldTerminateCallback callback, void* data1, void* data2)
+{
+ bool wasEnabled = isEnabled();
+
+ if (!m_isStopped)
+ stopCountdown();
+
+ m_didFire = false; // Reset the watchdog.
+
+ m_limit = limit;
+ m_callback = callback;
+ m_callbackData1 = data1;
+ m_callbackData2 = data2;
+
+ // If this is the first time that timeout is being enabled, then any
+ // previously JIT compiled code will not have the needed polling checks.
+ // Hence, we need to flush all the pre-existing compiled code.
+ //
+ // However, if the timeout is already enabled, and we're just changing the
+ // timeout value, then any existing JITted code will have the appropriate
+ // polling checks. Hence, there is no need to re-do this flushing.
+ if (!wasEnabled) {
+ // And if we've previously compiled any functions, we need to revert
+ // them because they don't have the needed polling checks yet.
+ vm.releaseExecutableMemory();
+ }
+
+ startCountdownIfNeeded();
+}
+
+bool Watchdog::didFire(ExecState* exec)
+{
+ if (m_didFire)
+ return true;
+
+ if (!m_timerDidFire)
+ return false;
+ m_timerDidFire = false;
+ stopCountdown();
+
+ double currentTime = currentCPUTime();
+ double deltaTime = currentTime - m_startTime;
+ double totalElapsedTime = m_elapsedTime + deltaTime;
+ if (totalElapsedTime > m_limit) {
+ // Case 1: the allowed CPU time has elapsed.
+
+ // If m_callback is not set, then we terminate by default.
+ // Else, we let m_callback decide if we should terminate or not.
+ bool needsTermination = !m_callback
+ || m_callback(exec, m_callbackData1, m_callbackData2);
+ if (needsTermination) {
+ m_didFire = true;
+ return true;
+ }
+
+ // The m_callback may have set a new limit. So, we may need to restart
+ // the countdown.
+ startCountdownIfNeeded();
+
+ } else {
+ // Case 2: the allowed CPU time has NOT elapsed.
+
+ // Tell the timer to alarm us again when it thinks we've reached the
+ // end of the allowed time.
+ double remainingTime = m_limit - totalElapsedTime;
+ m_elapsedTime = totalElapsedTime;
+ m_startTime = currentTime;
+ startCountdown(remainingTime);
+ }
+
+ return false;
+}
+
+bool Watchdog::isEnabled()
+{
+ return (m_limit != NO_LIMIT);
+}
+
+void Watchdog::fire()
+{
+ m_didFire = true;
+}
+
+void Watchdog::arm()
+{
+ m_reentryCount++;
+ if (m_reentryCount == 1)
+ startCountdownIfNeeded();
+}
+
+void Watchdog::disarm()
+{
+ ASSERT(m_reentryCount > 0);
+ if (m_reentryCount == 1)
+ stopCountdown();
+ m_reentryCount--;
+}
+
+void Watchdog::startCountdownIfNeeded()
+{
+ if (!m_isStopped)
+ return; // Already started.
+
+ if (!isArmed())
+ return; // Not executing JS script. No need to start.
+
+ if (isEnabled()) {
+ m_elapsedTime = 0;
+ m_startTime = currentCPUTime();
+ startCountdown(m_limit);
+ }
+}
+
+void Watchdog::startCountdown(double limit)
+{
+ ASSERT(m_isStopped);
+ m_isStopped = false;
+ startTimer(limit);
+}
+
+void Watchdog::stopCountdown()
+{
+ if (m_isStopped)
+ return;
+ stopTimer();
+ m_isStopped = true;
+}
+
+Watchdog::Scope::Scope(Watchdog& watchdog)
+ : m_watchdog(watchdog)
+{
+ m_watchdog.arm();
+}
+
+Watchdog::Scope::~Scope()
+{
+ m_watchdog.disarm();
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/Watchdog.h b/Source/JavaScriptCore/runtime/Watchdog.h
new file mode 100644
index 000000000..08c0ccb95
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/Watchdog.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Watchdog_h
+#define Watchdog_h
+
+#if PLATFORM(MAC) || PLATFORM(IOS)
+#include <dispatch/dispatch.h>
+#endif
+
+namespace JSC {
+
+class ExecState;
+class VM;
+
+class Watchdog {
+public:
+ class Scope;
+
+ Watchdog();
+ ~Watchdog();
+
+ typedef bool (*ShouldTerminateCallback)(ExecState*, void* data1, void* data2);
+ void setTimeLimit(VM&, double seconds, ShouldTerminateCallback = 0, void* data1 = 0, void* data2 = 0);
+
+ // This version of didFire() will check the elapsed CPU time and call the
+ // callback (if needed) to determine if the watchdog should fire.
+ bool didFire(ExecState*);
+
+ bool isEnabled();
+
+ // This version of didFire() is a more efficient version for when we want
+ // to know if the watchdog has fired in the past, and not whether it should
+ // fire right now.
+ JS_EXPORT_PRIVATE bool didFire() { return m_didFire; }
+ JS_EXPORT_PRIVATE void fire();
+
+ void* timerDidFireAddress() { return &m_timerDidFire; }
+
+private:
+ void arm();
+ void disarm();
+ void startCountdownIfNeeded();
+ void startCountdown(double limit);
+ void stopCountdown();
+ bool isArmed() { return !!m_reentryCount; }
+
+ // Platform specific timer implementation:
+ void initTimer();
+ void destroyTimer();
+ void startTimer(double limit);
+ void stopTimer();
+
+ // m_timerDidFire (above) indicates whether the timer fired. The Watchdog
+ // still needs to check if the allowed CPU time has elapsed. If so, then
+ // the Watchdog fires and m_didFire will be set.
+ // NOTE: m_timerDidFire is only set by the platform specific timer
+ // (probably from another thread) but is only cleared in the script thread.
+ bool m_timerDidFire;
+ bool m_didFire;
+
+ // All time units are in seconds.
+ double m_limit;
+ double m_startTime;
+ double m_elapsedTime;
+
+ int m_reentryCount;
+ bool m_isStopped;
+
+ ShouldTerminateCallback m_callback;
+ void* m_callbackData1;
+ void* m_callbackData2;
+
+#if PLATFORM(MAC) || PLATFORM(IOS)
+ dispatch_queue_t m_queue;
+ dispatch_source_t m_timer;
+#endif
+
+ friend class Watchdog::Scope;
+ friend class LLIntOffsetsExtractor;
+};
+
+class Watchdog::Scope {
+public:
+ Scope(Watchdog&);
+ ~Scope();
+
+private:
+ Watchdog& m_watchdog;
+};
+
+} // namespace JSC
+
+#endif // Watchdog_h
diff --git a/Source/JavaScriptCore/runtime/WatchdogMac.cpp b/Source/JavaScriptCore/runtime/WatchdogMac.cpp
new file mode 100644
index 000000000..ca474df2f
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/WatchdogMac.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Watchdog.h"
+
+namespace JSC {
+
+void Watchdog::initTimer()
+{
+ m_queue = 0;
+ m_timer = 0;
+}
+
+void Watchdog::destroyTimer()
+{
+ ASSERT(!m_timer);
+ if (m_queue)
+ dispatch_release(m_queue);
+}
+
+void Watchdog::startTimer(double limit)
+{
+ ASSERT(!m_timer);
+ if (!m_queue)
+ m_queue = dispatch_queue_create("jsc.watchdog.queue", 0);
+ m_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_queue);
+
+ dispatch_source_set_timer(m_timer,
+ dispatch_time(DISPATCH_TIME_NOW, limit * NSEC_PER_SEC),
+ DISPATCH_TIME_FOREVER, 0);
+
+ dispatch_source_set_event_handler(m_timer, ^{
+ m_timerDidFire = true;
+ });
+
+ dispatch_resume(m_timer);
+}
+
+void Watchdog::stopTimer()
+{
+ ASSERT(m_queue);
+ dispatch_sync(m_queue, ^{
+ dispatch_source_cancel(m_timer);
+ });
+ dispatch_release(m_timer);
+ m_timer = 0;
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/WatchdogNone.cpp b/Source/JavaScriptCore/runtime/WatchdogNone.cpp
new file mode 100644
index 000000000..615314bb3
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/WatchdogNone.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Watchdog.h"
+
+namespace JSC {
+
+// This is a stub for platforms that have not implemented this functionality.
+// In this case, the platform timer here never fires.
+
+void Watchdog::initTimer()
+{
+}
+
+void Watchdog::destroyTimer()
+{
+}
+
+void Watchdog::startTimer(double)
+{
+}
+
+void Watchdog::stopTimer()
+{
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h
index 52e5e2946..f741fa4c4 100644
--- a/Source/JavaScriptCore/runtime/WeakGCMap.h
+++ b/Source/JavaScriptCore/runtime/WeakGCMap.h
@@ -26,88 +26,104 @@
#ifndef WeakGCMap_h
#define WeakGCMap_h
-#include "Handle.h"
-#include "JSGlobalData.h"
+#include <heap/Weak.h>
+#include <heap/WeakInlines.h>
#include <wtf/HashMap.h>
namespace JSC {
-// A HashMap for GC'd values that removes entries when the associated value
-// dies.
-template <typename KeyType, typename MappedType> struct DefaultWeakGCMapFinalizerCallback {
- static void* finalizerContextFor(KeyType key)
- {
- return reinterpret_cast<void*>(key);
- }
+// A HashMap with Weak<JSCell> values, which automatically removes values once they're garbage collected.
- static KeyType keyForFinalizer(void* context, typename HandleTypes<MappedType>::ExternalType)
- {
- return reinterpret_cast<KeyType>(context);
- }
-};
-
-template<typename KeyType, typename MappedType, typename FinalizerCallback = DefaultWeakGCMapFinalizerCallback<KeyType, MappedType>, typename HashArg = typename DefaultHash<KeyType>::Hash, typename KeyTraitsArg = HashTraits<KeyType> >
-class WeakGCMap : private WeakHandleOwner {
- WTF_MAKE_FAST_ALLOCATED;
- WTF_MAKE_NONCOPYABLE(WeakGCMap);
-
- typedef HashMap<KeyType, WeakImpl*, HashArg, KeyTraitsArg> MapType;
- typedef typename HandleTypes<MappedType>::ExternalType ExternalType;
+template<typename KeyArg, typename RawMappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
+ typename KeyTraitsArg = HashTraits<KeyArg> >
+class WeakGCMap : public HashMap<KeyArg, Weak<RawMappedArg>, HashArg, KeyTraitsArg> {
+ typedef Weak<RawMappedArg> MappedType;
+ typedef HashMap<KeyArg, MappedType, HashArg, KeyTraitsArg> Base;
+ typedef WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg> Self;
+ typedef HashTraits<MappedType> MappedTraits;
+ typedef typename MappedTraits::PassInType MappedPassInType;
public:
+ typedef typename Base::KeyType KeyType;
+ typedef typename Base::AddResult AddResult;
+ typedef typename Base::iterator iterator;
+ typedef typename Base::const_iterator const_iterator;
+ using Base::begin;
+ using Base::end;
+ using Base::size;
+ using Base::remove;
+
WeakGCMap()
+ : m_gcThreshold(minGCThreshold)
{
}
- void clear()
+ AddResult set(const KeyType& key, MappedPassInType value)
{
- typename MapType::iterator end = m_map.end();
- for (typename MapType::iterator ptr = m_map.begin(); ptr != end; ++ptr)
- WeakSet::deallocate(ptr->value);
- m_map.clear();
+ gcMapIfNeeded();
+ return Base::set(key, value);
}
- ExternalType get(const KeyType& key) const
+ AddResult add(const KeyType& key, MappedPassInType value)
{
- WeakImpl* impl = m_map.get(key);
- if (!impl || impl->state() != WeakImpl::Live)
- return ExternalType();
- return HandleTypes<MappedType>::getFromSlot(const_cast<JSValue*>(&impl->jsValue()));
+ gcMapIfNeeded();
+ AddResult addResult = Base::add(key, nullptr);
+ if (!addResult.iterator->value) { // New value or found a zombie value.
+ addResult.isNewEntry = true;
+ addResult.iterator->value = value;
+ }
+ return addResult;
}
- void set(JSGlobalData& globalData, const KeyType& key, ExternalType value)
+ iterator find(const KeyType& key)
{
- ASSERT_UNUSED(globalData, globalData.apiLock().currentThreadIsHoldingLock());
- typename MapType::AddResult result = m_map.add(key, 0);
- if (!result.isNewEntry)
- WeakSet::deallocate(result.iterator->value);
- result.iterator->value = WeakSet::allocate(value, this, FinalizerCallback::finalizerContextFor(key));
+ iterator it = Base::find(key);
+ iterator end = Base::end();
+ if (it != end && !it->value) // Found a zombie value.
+ return end;
+ return it;
}
- void remove(const KeyType& key)
+ const_iterator find(const KeyType& key) const
{
- WeakImpl* impl = m_map.take(key);
- if (!impl)
- return;
- WeakSet::deallocate(impl);
+ return const_cast<Self*>(this)->find(key);
}
- ~WeakGCMap()
+ bool contains(const KeyType& key) const
{
- clear();
+ return find(key) != end();
}
-
+
private:
- virtual void finalize(Handle<Unknown> handle, void* context)
+ static const int minGCThreshold = 3;
+
+ void gcMap()
+ {
+ Vector<KeyType, 4> zombies;
+ iterator end = this->end();
+ for (iterator it = begin(); it != end; ++it) {
+ if (!it->value)
+ zombies.append(it->key);
+ }
+ for (size_t i = 0; i < zombies.size(); ++i)
+ remove(zombies[i]);
+ }
+
+ void gcMapIfNeeded()
{
- WeakImpl* impl = m_map.take(FinalizerCallback::keyForFinalizer(context, HandleTypes<MappedType>::getFromSlot(handle.slot())));
- ASSERT(impl);
- WeakSet::deallocate(impl);
+ if (size() < m_gcThreshold)
+ return;
+
+ gcMap();
+ m_gcThreshold = std::max(minGCThreshold, size() * 2 - 1);
}
- MapType m_map;
+ int m_gcThreshold;
};
+template<typename KeyArg, typename RawMappedArg, typename HashArg, typename KeyTraitsArg>
+const int WeakGCMap<KeyArg, RawMappedArg, HashArg, KeyTraitsArg>::minGCThreshold;
+
} // namespace JSC
#endif // WeakGCMap_h
diff --git a/Source/JavaScriptCore/runtime/WriteBarrier.h b/Source/JavaScriptCore/runtime/WriteBarrier.h
index ef8c3aff8..fe07cf532 100644
--- a/Source/JavaScriptCore/runtime/WriteBarrier.h
+++ b/Source/JavaScriptCore/runtime/WriteBarrier.h
@@ -35,7 +35,7 @@
namespace JSC {
class JSCell;
-class JSGlobalData;
+class VM;
class JSGlobalObject;
template<class T> class WriteBarrierBase;
@@ -68,11 +68,11 @@ template<class T> inline void validateCell(T)
// We have a separate base class with no constructors for use in Unions.
template <typename T> class WriteBarrierBase {
public:
- void set(JSGlobalData& globalData, const JSCell* owner, T* value)
+ void set(VM& vm, const JSCell* owner, T* value)
{
ASSERT(value);
validateCell(value);
- setEarlyValue(globalData, owner, value);
+ setEarlyValue(vm, owner, value);
}
// This is meant to be used like operator=, but is called copyFrom instead, in
@@ -82,16 +82,16 @@ public:
m_cell = other.m_cell;
}
- void setMayBeNull(JSGlobalData& globalData, const JSCell* owner, T* value)
+ void setMayBeNull(VM& vm, const JSCell* owner, T* value)
{
if (value)
validateCell(value);
- setEarlyValue(globalData, owner, value);
+ setEarlyValue(vm, owner, value);
}
// Should only be used by JSCell during early initialisation
// when some basic types aren't yet completely instantiated
- void setEarlyValue(JSGlobalData&, const JSCell* owner, T* value)
+ void setEarlyValue(VM&, const JSCell* owner, T* value)
{
this->m_cell = reinterpret_cast<JSCell*>(value);
Heap::writeBarrier(owner, this->m_cell);
@@ -99,9 +99,11 @@ public:
T* get() const
{
- if (m_cell)
- validateCell(m_cell);
- return reinterpret_cast<T*>(static_cast<void*>(m_cell));
+ // Copy m_cell to a local to avoid multiple-read issues. (See <http://webkit.org/b/110854>)
+ JSCell* cell = m_cell;
+ if (cell)
+ validateCell(cell);
+ return reinterpret_cast<T*>(static_cast<void*>(cell));
}
T* operator*() const
@@ -145,7 +147,7 @@ private:
template <> class WriteBarrierBase<Unknown> {
public:
- void set(JSGlobalData&, const JSCell* owner, JSValue value)
+ void set(VM&, const JSCell* owner, JSValue value)
{
m_value = JSValue::encode(value);
Heap::writeBarrier(owner, value);
@@ -195,15 +197,15 @@ public:
this->setWithoutWriteBarrier(0);
}
- WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value)
+ WriteBarrier(VM& vm, const JSCell* owner, T* value)
{
- this->set(globalData, owner, value);
+ this->set(vm, owner, value);
}
enum MayBeNullTag { MayBeNull };
- WriteBarrier(JSGlobalData& globalData, const JSCell* owner, T* value, MayBeNullTag)
+ WriteBarrier(VM& vm, const JSCell* owner, T* value, MayBeNullTag)
{
- this->setMayBeNull(globalData, owner, value);
+ this->setMayBeNull(vm, owner, value);
}
};
@@ -214,9 +216,9 @@ public:
this->setWithoutWriteBarrier(JSValue());
}
- WriteBarrier(JSGlobalData& globalData, const JSCell* owner, JSValue value)
+ WriteBarrier(VM& vm, const JSCell* owner, JSValue value)
{
- this->set(globalData, owner, value);
+ this->set(vm, owner, value);
}
};
diff --git a/Source/JavaScriptCore/shell/CMakeLists.txt b/Source/JavaScriptCore/shell/CMakeLists.txt
index d1b4abf52..fcbe429c0 100644
--- a/Source/JavaScriptCore/shell/CMakeLists.txt
+++ b/Source/JavaScriptCore/shell/CMakeLists.txt
@@ -1,28 +1,33 @@
-SET(JSC_SOURCES
+set(JSC_SOURCES
../jsc.cpp
)
-SET(JSC_LIBRARIES
- ${WTF_LIBRARY_NAME}
- ${JavaScriptCore_LIBRARY_NAME}
+set(JSC_LIBRARIES
+ WTF
+ JavaScriptCore
+ ${CMAKE_DL_LIBS}
)
-IF ("${JavaScriptCore_LIBRARY_TYPE}" MATCHES "STATIC")
- ADD_DEFINITIONS(-DSTATICALLY_LINKED_WITH_JavaScriptCore)
-ENDIF ()
+if ("${JavaScriptCore_LIBRARY_TYPE}" MATCHES "STATIC")
+ add_definitions(-DSTATICALLY_LINKED_WITH_JavaScriptCore)
+endif ()
WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS()
WEBKIT_WRAP_SOURCELIST(${JSC_SOURCES})
-INCLUDE_DIRECTORIES(./ ${JavaScriptCore_INCLUDE_DIRECTORIES})
-ADD_EXECUTABLE(${JSC_EXECUTABLE_NAME} ${JSC_SOURCES})
-TARGET_LINK_LIBRARIES(${JSC_EXECUTABLE_NAME} ${JSC_LIBRARIES})
-SET_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} PROPERTIES FOLDER "JavaScriptCore")
+include_directories(./ ${JavaScriptCore_INCLUDE_DIRECTORIES})
+add_executable(jsc ${JSC_SOURCES})
+target_link_libraries(jsc ${JSC_LIBRARIES})
+set_target_properties(jsc PROPERTIES FOLDER "JavaScriptCore")
-IF (JSC_LINK_FLAGS)
- ADD_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} LINK_FLAGS "${JSC_LINK_FLAGS}")
-ENDIF ()
+if (JSC_OUTPUT_NAME)
+ set_target_properties(jsc PROPERTIES OUTPUT_NAME ${JSC_OUTPUT_NAME})
+endif ()
-IF (SHOULD_INSTALL_JS_SHELL)
- INSTALL(TARGETS ${JSC_EXECUTABLE_NAME} DESTINATION "${EXEC_INSTALL_DIR}")
-ENDIF ()
+if (JSC_LINK_FLAGS)
+ ADD_TARGET_PROPERTIES(jsc LINK_FLAGS "${JSC_LINK_FLAGS}")
+endif ()
+
+if (SHOULD_INSTALL_JS_SHELL)
+ install(TARGETS jsc DESTINATION "${EXEC_INSTALL_DIR}")
+endif ()
diff --git a/Source/JavaScriptCore/shell/PlatformBlackBerry.cmake b/Source/JavaScriptCore/shell/PlatformBlackBerry.cmake
index aff77caf7..2ec35c885 100644
--- a/Source/JavaScriptCore/shell/PlatformBlackBerry.cmake
+++ b/Source/JavaScriptCore/shell/PlatformBlackBerry.cmake
@@ -1,17 +1,16 @@
FIND_STAGING_LIBRARY(SLOG2_LIBRARY slog2)
-LIST(APPEND JSC_LIBRARIES
+list(APPEND JSC_LIBRARIES
${ICUI18N_LIBRARY}
${ICUUC_LIBRARY}
${INTL_LIBRARY} # Required for x86 builds
${M_LIBRARY}
${Screen_LIBRARY}
- ${Skia_QNX_LIBRARY}
${WebKitPlatform_LIBRARY}
${SLOG2_LIBRARY}
)
-IF (PROFILING)
- LIST(APPEND JSC_LIBRARIES
+if (PROFILING)
+ list(APPEND JSC_LIBRARIES
${PROFILING_LIBRARY}
)
-ENDIF ()
+endif ()
diff --git a/Source/JavaScriptCore/shell/PlatformEfl.cmake b/Source/JavaScriptCore/shell/PlatformEfl.cmake
index 22fe20a8e..1d2e8c1ad 100644
--- a/Source/JavaScriptCore/shell/PlatformEfl.cmake
+++ b/Source/JavaScriptCore/shell/PlatformEfl.cmake
@@ -1,5 +1,4 @@
-LIST(APPEND JSC_LIBRARIES
+list(APPEND JSC_LIBRARIES
${GLIB_LIBRARIES}
${ECORE_LIBRARIES}
- ${CMAKE_DL_LIBS}
)
diff --git a/Source/JavaScriptCore/shell/PlatformGTK.cmake b/Source/JavaScriptCore/shell/PlatformGTK.cmake
new file mode 100644
index 000000000..623183a2b
--- /dev/null
+++ b/Source/JavaScriptCore/shell/PlatformGTK.cmake
@@ -0,0 +1,3 @@
+list(APPEND JSC_LIBRARIES
+ ${GLIB_LIBRARIES}
+)
diff --git a/Source/JavaScriptCore/shell/PlatformWinCE.cmake b/Source/JavaScriptCore/shell/PlatformWinCE.cmake
deleted file mode 100644
index 0b7a3bfbf..000000000
--- a/Source/JavaScriptCore/shell/PlatformWinCE.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-LIST(APPEND JSC_SOURCES
- ../os-win32/WinMain.cpp
-)
diff --git a/Source/JavaScriptCore/testRegExp.cpp b/Source/JavaScriptCore/testRegExp.cpp
index 527c9359d..9185d7281 100644
--- a/Source/JavaScriptCore/testRegExp.cpp
+++ b/Source/JavaScriptCore/testRegExp.cpp
@@ -21,9 +21,11 @@
#include "config.h"
#include "RegExp.h"
+#include "APIShims.h"
#include <wtf/CurrentTime.h>
#include "InitializeThreading.h"
#include "JSGlobalObject.h"
+#include "Operations.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -108,15 +110,15 @@ struct RegExpTest {
class GlobalObject : public JSGlobalObject {
private:
- GlobalObject(JSGlobalData&, Structure*, const Vector<String>& arguments);
+ GlobalObject(VM&, Structure*, const Vector<String>& arguments);
public:
typedef JSGlobalObject Base;
- static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<String>& arguments)
+ static GlobalObject* create(VM& vm, Structure* structure, const Vector<String>& arguments)
{
- GlobalObject* globalObject = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments);
- globalData.heap.addFinalizer(globalObject, destroy);
+ GlobalObject* globalObject = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure, arguments);
+ vm.heap.addFinalizer(globalObject, destroy);
return globalObject;
}
@@ -124,15 +126,15 @@ public:
static const bool needsDestructor = false;
- static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
+ static Structure* createStructure(VM& vm, JSValue prototype)
{
- return Structure::create(globalData, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
+ return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info);
}
protected:
- void finishCreation(JSGlobalData& globalData, const Vector<String>& arguments)
+ void finishCreation(VM& vm, const Vector<String>& arguments)
{
- Base::finishCreation(globalData);
+ Base::finishCreation(vm);
UNUSED_PARAM(arguments);
}
};
@@ -141,10 +143,10 @@ COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false
const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) };
-GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure, const Vector<String>& arguments)
- : JSGlobalObject(globalData, structure)
+GlobalObject::GlobalObject(VM& vm, Structure* structure, const Vector<String>& arguments)
+ : JSGlobalObject(vm, structure)
{
- finishCreation(globalData, arguments);
+ finishCreation(vm, arguments);
}
// Use SEH for Release builds only to get rid of the crash report dialog
@@ -188,7 +190,7 @@ int main(int argc, char** argv)
QCoreApplication app(argc, argv);
#endif
- // Initialize JSC before getting JSGlobalData.
+ // Initialize JSC before getting VM.
JSC::initializeThreading();
// We can't use destructors in the following code because it uses Windows
@@ -200,12 +202,12 @@ int main(int argc, char** argv)
return res;
}
-static bool testOneRegExp(JSGlobalData& globalData, RegExp* regexp, RegExpTest* regExpTest, bool verbose, unsigned int lineNumber)
+static bool testOneRegExp(VM& vm, RegExp* regexp, RegExpTest* regExpTest, bool verbose, unsigned int lineNumber)
{
bool result = true;
Vector<int, 32> outVector;
outVector.resize(regExpTest->expectVector.size());
- int matchResult = regexp->match(globalData, regExpTest->subject, regExpTest->offset, outVector);
+ int matchResult = regexp->match(vm, regExpTest->subject, regExpTest->offset, outVector);
if (matchResult != regExpTest->result) {
result = false;
@@ -308,7 +310,7 @@ static int scanString(char* buffer, int bufferLength, StringBuilder& builder, ch
return -1;
}
-static RegExp* parseRegExpLine(JSGlobalData& globalData, char* line, int lineLength)
+static RegExp* parseRegExpLine(VM& vm, char* line, int lineLength)
{
StringBuilder pattern;
@@ -322,7 +324,7 @@ static RegExp* parseRegExpLine(JSGlobalData& globalData, char* line, int lineLen
++i;
- return RegExp::create(globalData, pattern.toString(), regExpFlags(line + i));
+ return RegExp::create(vm, pattern.toString(), regExpFlags(line + i));
}
static RegExpTest* parseTestLine(char* line, int lineLength)
@@ -406,7 +408,7 @@ static bool runFromFiles(GlobalObject* globalObject, const Vector<String>& files
unsigned failures = 0;
char* lineBuffer = new char[MaxLineLength + 1];
- JSGlobalData& globalData = globalObject->globalData();
+ VM& vm = globalObject->vm();
bool success = true;
for (size_t i = 0; i < files.size(); i++) {
@@ -434,13 +436,13 @@ static bool runFromFiles(GlobalObject* globalObject, const Vector<String>& files
continue;
if (linePtr[0] == '/') {
- regexp = parseRegExpLine(globalData, linePtr, lineLength);
+ regexp = parseRegExpLine(vm, linePtr, lineLength);
} else if (linePtr[0] == ' ') {
RegExpTest* regExpTest = parseTestLine(linePtr, lineLength);
if (regexp && regExpTest) {
++tests;
- if (!testOneRegExp(globalData, regexp, regExpTest, verbose, lineNumber)) {
+ if (!testOneRegExp(vm, regexp, regExpTest, verbose, lineNumber)) {
failures++;
printf("Failure on line %u\n", lineNumber);
}
@@ -461,9 +463,9 @@ static bool runFromFiles(GlobalObject* globalObject, const Vector<String>& files
delete[] lineBuffer;
- globalData.dumpSampleData(globalObject->globalExec());
+ vm.dumpSampleData(globalObject->globalExec());
#if ENABLE(REGEXP_TRACING)
- globalData.dumpRegExpTrace();
+ vm.dumpRegExpTrace();
#endif
return success;
}
@@ -498,13 +500,13 @@ static void parseArguments(int argc, char** argv, CommandLine& options)
int realMain(int argc, char** argv)
{
- RefPtr<JSGlobalData> globalData = JSGlobalData::create(LargeHeap);
- JSLockHolder lock(globalData.get());
+ VM* vm = VM::create(LargeHeap).leakRef();
+ APIEntryShim shim(vm);
CommandLine options;
parseArguments(argc, argv, options);
- GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.arguments);
+ GlobalObject* globalObject = GlobalObject::create(*vm, GlobalObject::createStructure(*vm, jsNull()), options.arguments);
bool success = runFromFiles(globalObject, options.files, options.verbose);
return success ? 0 : 3;
diff --git a/Source/JavaScriptCore/tests/mozilla/jsDriver.pl b/Source/JavaScriptCore/tests/mozilla/jsDriver.pl
index 4a774cefd..ccdd6c69f 100644
--- a/Source/JavaScriptCore/tests/mozilla/jsDriver.pl
+++ b/Source/JavaScriptCore/tests/mozilla/jsDriver.pl
@@ -65,9 +65,10 @@ my $opt_console_failures = 0;
my $opt_lxr_url = "./"; # "http://lxr.mozilla.org/mozilla/source/js/tests/";
my $opt_exit_munge = ($os_type ne "MAC") ? 1 : 0;
my $opt_arch= "";
+my $opt_sim_sdk = "";
# command line option definition
-my $options = "a=s arch>a b=s bugurl>b c=s classpath>c e=s engine>e f=s file>f " .
+my $options = "a=s arch>a b=s bugurl>b c=s classpath>c d=s sdk>d e=s engine>e f=s file>f " .
"h help>h i j=s javapath>j k confail>k l=s list>l L=s neglist>L " .
"o=s opt>o p=s testpath>p s=s shellpath>s t trace>t u=s lxrurl>u " .
"x noexitmunge>x";
@@ -148,7 +149,8 @@ sub main {
sub execute_tests {
my (@test_list) = @_;
- my ($test, $shell_command, $line, @output, $path);
+ my ($test, $line, @output, $path);
+ my $shell_command = "";
my $file_param = " -f ";
my ($last_suite, $last_test_dir);
@@ -175,8 +177,13 @@ sub execute_tests {
# (only check for their existance if the suite or test_dir has changed
# since the last time we looked.)
if ($last_suite ne $suite || $last_test_dir ne $test_dir) {
- $shell_command = $opt_arch . " ";
-
+ if ($opt_sim_sdk) {
+ chomp($shell_command = `xcrun -sdk $opt_sim_sdk -find sim`);
+ $shell_command .= " --adopt-pid $opt_arch ";
+ } else {
+ $shell_command = "$opt_arch ";
+ }
+
$shell_command .= &xp_path($engine_command) . " -s ";
# FIXME: <https://bugs.webkit.org/show_bug.cgi?id=90119>
@@ -449,6 +456,11 @@ sub parse_args {
&dd ("opt: adding negative list '$value'.");
push (@opt_neg_list_files, $value);
+ } elsif ($option eq "d") {
+ $option = 'd';
+ &dd ("opt: using $value simulator SDK to run jsc.");
+ $opt_sim_sdk = $value;
+
} elsif ($option eq "o") {
$opt_engine_params = $value;
&dd ("opt: setting engine params to '$opt_engine_params'.");
@@ -511,6 +523,7 @@ sub usage {
"(-b|--bugurl) Bugzilla URL.\n" .
" (default is $opt_bug_url)\n" .
"(-c|--classpath) Classpath (Rhino only.)\n" .
+ "(-d|--sdk) Use a simulator SDK to run jsc\n" .
"(-e|--engine) <type> ... Specify the type of engine(s) to test.\n" .
" <type> is one or more of\n" .
" (squirrelfish|smopt|smdebug|lcopt|lcdebug|xpcshell|" .
diff --git a/Source/JavaScriptCore/tools/CodeProfile.cpp b/Source/JavaScriptCore/tools/CodeProfile.cpp
index b3c4ff448..de86e52ef 100644
--- a/Source/JavaScriptCore/tools/CodeProfile.cpp
+++ b/Source/JavaScriptCore/tools/CodeProfile.cpp
@@ -133,7 +133,7 @@ void CodeProfile::sample(void* pc, void** framePointer)
framePointer = 0;
#else
// This platform is not yet supported!
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
#endif
}
diff --git a/Source/JavaScriptCore/tools/TieredMMapArray.h b/Source/JavaScriptCore/tools/TieredMMapArray.h
index 03d9df2b7..e0dfa3628 100644
--- a/Source/JavaScriptCore/tools/TieredMMapArray.h
+++ b/Source/JavaScriptCore/tools/TieredMMapArray.h
@@ -78,8 +78,7 @@ public:
// Reallocate the directory.
size_t oldDirectorySize = m_directoryCount * sizeof(T*);
size_t newDirectorySize = oldDirectorySize * 2;
- if (newDirectorySize < oldDirectorySize)
- CRASH();
+ RELEASE_ASSERT(newDirectorySize < oldDirectorySize);
m_directory = OSAllocator::reallocateCommitted(m_directory, oldDirectorySize, newDirectorySize);
//
diff --git a/Source/JavaScriptCore/wscript b/Source/JavaScriptCore/wscript
deleted file mode 100644
index 2270455c8..000000000
--- a/Source/JavaScriptCore/wscript
+++ /dev/null
@@ -1,90 +0,0 @@
-#! /usr/bin/env python
-
-# Copyright (C) 2009 Kevin Ollivier All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# JavaScriptCore build script for the waf build system
-
-import commands
-
-from settings import *
-
-def build(bld):
-
- import Options
-
- jscore_excludes = ['jsc.cpp', 'ExecutableAllocatorPosix.cpp', 'LLIntOffsetsExtractor.cpp', 'udis86_itab.c']
- jscore_exclude_patterns = get_port_excludes(Options.options.port)
- jscore_exclude_patterns.append('*None.cpp')
-
- sources = []
-
- if Options.options.port == "wx":
- if building_on_win32:
- jscore_excludes += ['OSAllocatorPosix.cpp', 'ThreadingPthreads.cpp']
- sources.extend(['../WTF/wtf/ThreadingWin.cpp', '../WTF/wtf/ThreadSpecificWin.cpp', '../WTF/wtf/OSAllocatorWin.cpp'])
- else:
- jscore_excludes.append('JSStringRefBSTR.cpp')
-
- bld.env.LIBDIR = output_dir
- full_dirs = get_dirs_for_features(jscore_dir, features=[Options.options.port.lower()], dirs=jscore_dirs)
- abs_dirs = []
- for adir in full_dirs:
- abs_dirs.append(os.path.join(jscore_dir, adir))
-
- jscore_excludes.extend(get_excludes_in_dirs(abs_dirs, jscore_exclude_patterns))
-
- includes = common_includes + full_dirs + [output_dir]
- if sys.platform.startswith('darwin'):
- includes.append(os.path.join(jscore_dir, 'icu'))
-
- # 1. A simple program
- jscore = bld.new_task_gen(
- features = 'cc cxx cshlib',
- includes = '. .. assembler ../WTF ' + ' '.join(includes),
- source = sources,
- defines = ['BUILDING_JavaScriptCore'],
- target = 'jscore',
- uselib = 'WX ICU ' + get_config(),
- uselib_local = '',
- install_path = output_dir)
-
- jscore.find_sources_in_dirs(full_dirs, excludes = jscore_excludes)
-
- obj = bld.new_task_gen(
- features = 'cxx cprogram',
- includes = '. .. assembler ../WTF ' + ' '.join(includes),
- source = 'jsc.cpp',
- target = 'jsc',
- uselib = 'WX ICU ' + get_config(),
- uselib_local = 'jscore',
- install_path = output_dir,
- )
-
- if building_on_win32:
- myenv = obj.env.copy()
- myenv.CXXFLAGS = myenv.CXXFLAGS[:]
- myenv.CXXFLAGS.remove('/EHsc')
- obj.env = myenv
-
- bld.add_group()
diff --git a/Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.h b/Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.h
index be0ead43d..9dce78200 100644
--- a/Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.h
+++ b/Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.h
@@ -93,9 +93,9 @@ inline UChar getCanonicalPair(UCS2CanonicalizationRange* info, UChar ch)
case CanonicalizeAlternatingUnaligned:
return ((ch - 1) ^ 1) + 1;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return 0;
}
@@ -129,7 +129,7 @@ inline bool areCanonicallyEquivalent(UChar a, UChar b)
return ((a - 1) | 1) == ((b - 1) | 1);
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
index 31603f6d3..f0312ea25 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
@@ -83,8 +83,8 @@ public:
static inline void popParenthesesDisjunctionContext(BackTrackInfoParentheses* backTrack)
{
- ASSERT(backTrack->matchAmount);
- ASSERT(backTrack->lastContext);
+ RELEASE_ASSERT(backTrack->matchAmount);
+ RELEASE_ASSERT(backTrack->lastContext);
backTrack->lastContext = backTrack->lastContext->next;
--backTrack->matchAmount;
}
@@ -111,8 +111,7 @@ public:
{
size_t size = sizeof(DisjunctionContext) - sizeof(uintptr_t) + disjunction->m_frameSize * sizeof(uintptr_t);
allocatorPool = allocatorPool->ensureCapacity(size);
- if (!allocatorPool)
- CRASH();
+ RELEASE_ASSERT(allocatorPool);
return new (allocatorPool->alloc(size)) DisjunctionContext();
}
@@ -161,8 +160,7 @@ public:
{
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();
+ RELEASE_ASSERT(allocatorPool);
return new (allocatorPool->alloc(size)) ParenthesesDisjunctionContext(output, term);
}
@@ -207,8 +205,7 @@ public:
int readChecked(unsigned negativePositionOffest)
{
- if (pos < negativePositionOffest)
- CRASH();
+ RELEASE_ASSERT(pos >= negativePositionOffest);
unsigned p = pos - negativePositionOffest;
ASSERT(p < length);
return input[p];
@@ -264,8 +261,7 @@ public:
void uncheckInput(unsigned count)
{
- if (pos < count)
- CRASH();
+ RELEASE_ASSERT(pos >= count);
pos -= count;
}
@@ -276,8 +272,7 @@ public:
bool atEnd(unsigned negativePositionOffest)
{
- if (pos < negativePositionOffest)
- CRASH();
+ RELEASE_ASSERT(pos >= negativePositionOffest);
return (pos - negativePositionOffest) == length;
}
@@ -485,7 +480,7 @@ public:
return true;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
@@ -567,7 +562,7 @@ public:
return true;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
@@ -801,7 +796,7 @@ public:
{
// 'Terminal' parentheses are at the end of the regex, and as such a match past end
// should always be returned as a successful match - we should never backtrack to here.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return false;
}
@@ -927,7 +922,7 @@ public:
return JSRegExpMatch;
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return JSRegExpErrorNoMatch;
}
@@ -1067,7 +1062,7 @@ public:
}
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return JSRegExpErrorNoMatch;
}
@@ -1273,7 +1268,7 @@ public:
}
// We should never fall-through to here.
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
backtrack:
ASSERT(context->term < static_cast<int>(disjunction->terms.size()));
@@ -1282,7 +1277,7 @@ public:
case ByteTerm::TypeSubpatternBegin:
return JSRegExpNoMatch;
case ByteTerm::TypeSubpatternEnd:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case ByteTerm::TypeBodyAlternativeBegin:
case ByteTerm::TypeBodyAlternativeDisjunction: {
@@ -1304,7 +1299,7 @@ public:
MATCH_NEXT();
}
case ByteTerm::TypeBodyAlternativeEnd:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case ByteTerm::TypeAlternativeBegin:
case ByteTerm::TypeAlternativeDisjunction: {
@@ -1393,10 +1388,10 @@ public:
BACKTRACK();
case ByteTerm::TypeDotStarEnclosure:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
return JSRegExpErrorNoMatch;
}
@@ -1425,8 +1420,7 @@ public:
output[i << 1] = offsetNoMatch;
allocatorPool = pattern->m_allocator->startAllocator();
- if (!allocatorPool)
- CRASH();
+ RELEASE_ASSERT(allocatorPool);
DisjunctionContext* context = allocDisjunctionContext(pattern->m_body.get());
@@ -1461,8 +1455,6 @@ private:
unsigned remainingMatchCount;
};
-
-
class ByteCompiler {
struct ParenthesesStackEntry {
unsigned beginTerm;
@@ -1718,17 +1710,20 @@ public:
unsigned subpatternId = parenthesesBegin.atom.subpatternId;
unsigned numSubpatterns = lastSubpatternId - subpatternId + 1;
- ByteDisjunction* parenthesesDisjunction = new ByteDisjunction(numSubpatterns, callFrameSize);
+ OwnPtr<ByteDisjunction> parenthesesDisjunction = adoptPtr(new ByteDisjunction(numSubpatterns, callFrameSize));
+
+ unsigned firstTermInParentheses = beginTerm + 1;
+ parenthesesDisjunction->terms.reserveInitialCapacity(endTerm - firstTermInParentheses + 2);
parenthesesDisjunction->terms.append(ByteTerm::SubpatternBegin());
- for (unsigned termInParentheses = beginTerm + 1; termInParentheses < endTerm; ++termInParentheses)
+ for (unsigned termInParentheses = firstTermInParentheses; termInParentheses < endTerm; ++termInParentheses)
parenthesesDisjunction->terms.append(m_bodyDisjunction->terms[termInParentheses]);
parenthesesDisjunction->terms.append(ByteTerm::SubpatternEnd());
m_bodyDisjunction->terms.shrink(beginTerm);
- m_allParenthesesInfo.append(parenthesesDisjunction);
- m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture, inputPosition));
+ m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction.get(), capture, inputPosition));
+ m_allParenthesesInfo.append(parenthesesDisjunction.release());
m_bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount.unsafeGet();
m_bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType;
@@ -1815,7 +1810,7 @@ public:
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
unsigned currentCountAlreadyChecked = inputCountAlreadyChecked;
- PatternAlternative* alternative = disjunction->m_alternatives[alt];
+ PatternAlternative* alternative = disjunction->m_alternatives[alt].get();
if (alt) {
if (disjunction == m_pattern.m_body)
@@ -1926,7 +1921,7 @@ private:
OwnPtr<ByteDisjunction> m_bodyDisjunction;
unsigned m_currentAlternativeIndex;
Vector<ParenthesesStackEntry> m_parenthesesStack;
- Vector<ByteDisjunction*> m_allParenthesesInfo;
+ Vector<OwnPtr<ByteDisjunction> > m_allParenthesesInfo;
};
PassOwnPtr<BytecodePattern> byteCompile(YarrPattern& pattern, BumpPointerAllocator* allocator)
diff --git a/Source/JavaScriptCore/yarr/YarrInterpreter.h b/Source/JavaScriptCore/yarr/YarrInterpreter.h
index fb60bd979..bb64e6d91 100644
--- a/Source/JavaScriptCore/yarr/YarrInterpreter.h
+++ b/Source/JavaScriptCore/yarr/YarrInterpreter.h
@@ -337,42 +337,37 @@ public:
struct BytecodePattern {
WTF_MAKE_FAST_ALLOCATED;
public:
- BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<ByteDisjunction*> allParenthesesInfo, YarrPattern& pattern, BumpPointerAllocator* allocator)
+ BytecodePattern(PassOwnPtr<ByteDisjunction> body, Vector<OwnPtr<ByteDisjunction> >& parenthesesInfoToAdopt, YarrPattern& pattern, BumpPointerAllocator* allocator)
: m_body(body)
, m_ignoreCase(pattern.m_ignoreCase)
, m_multiline(pattern.m_multiline)
, m_allocator(allocator)
{
+ m_body->terms.shrinkToFit();
+
newlineCharacterClass = pattern.newlineCharacterClass();
wordcharCharacterClass = pattern.wordcharCharacterClass();
- m_allParenthesesInfo.append(allParenthesesInfo);
- m_userCharacterClasses.append(pattern.m_userCharacterClasses);
- // 'Steal' the YarrPattern's CharacterClasses! We clear its
- // array, so that it won't delete them on destruction. We'll
- // take responsibility for that.
- pattern.m_userCharacterClasses.clear();
- }
+ m_allParenthesesInfo.swap(parenthesesInfoToAdopt);
+ m_allParenthesesInfo.shrinkToFit();
- ~BytecodePattern()
- {
- deleteAllValues(m_allParenthesesInfo);
- deleteAllValues(m_userCharacterClasses);
+ m_userCharacterClasses.swap(pattern.m_userCharacterClasses);
+ m_userCharacterClasses.shrinkToFit();
}
OwnPtr<ByteDisjunction> m_body;
bool m_ignoreCase;
bool m_multiline;
// Each BytecodePattern is associated with a RegExp, each RegExp is associated
- // with a JSGlobalData. Cache a pointer to out JSGlobalData's m_regExpAllocator.
+ // with a VM. Cache a pointer to out VM's m_regExpAllocator.
BumpPointerAllocator* m_allocator;
CharacterClass* newlineCharacterClass;
CharacterClass* wordcharCharacterClass;
private:
- Vector<ByteDisjunction*> m_allParenthesesInfo;
- Vector<CharacterClass*> m_userCharacterClasses;
+ Vector<OwnPtr<ByteDisjunction> > m_allParenthesesInfo;
+ Vector<OwnPtr<CharacterClass> > m_userCharacterClasses;
};
JS_EXPORT_PRIVATE PassOwnPtr<BytecodePattern> byteCompile(YarrPattern&, BumpPointerAllocator*);
diff --git a/Source/JavaScriptCore/yarr/YarrJIT.cpp b/Source/JavaScriptCore/yarr/YarrJIT.cpp
index 1aef49bdf..1b2b03131 100644
--- a/Source/JavaScriptCore/yarr/YarrJIT.cpp
+++ b/Source/JavaScriptCore/yarr/YarrJIT.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,7 +40,7 @@ namespace JSC { namespace Yarr {
template<YarrJITCompileMode compileMode>
class YarrGenerator : private MacroAssembler {
- friend void jitCompile(JSGlobalData*, YarrCodeBlock& jitObject, const String& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
+ friend void jitCompile(VM*, YarrCodeBlock& jitObject, const String& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
#if CPU(ARM)
static const RegisterID input = ARMRegisters::r0;
@@ -179,8 +179,8 @@ class YarrGenerator : private MacroAssembler {
void matchCharacterClass(RegisterID character, JumpList& matchDest, const CharacterClass* charClass)
{
if (charClass->m_table) {
- ExtendedAddress tableEntry(character, reinterpret_cast<intptr_t>(charClass->m_table->m_table));
- matchDest.append(branchTest8(charClass->m_table->m_inverted ? Zero : NonZero, tableEntry));
+ ExtendedAddress tableEntry(character, reinterpret_cast<intptr_t>(charClass->m_table));
+ matchDest.append(branchTest8(charClass->m_tableInverted ? Zero : NonZero, tableEntry));
return;
}
Jump unicodeFail;
@@ -1265,7 +1265,7 @@ class YarrGenerator : private MacroAssembler {
case PatternTerm::TypeParenthesesSubpattern:
case PatternTerm::TypeParentheticalAssertion:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case PatternTerm::TypeBackReference:
m_shouldFallBack = true;
break;
@@ -1331,7 +1331,7 @@ class YarrGenerator : private MacroAssembler {
case PatternTerm::TypeParenthesesSubpattern:
case PatternTerm::TypeParentheticalAssertion:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
case PatternTerm::TypeDotStarEnclosure:
backtrackDotStarEnclosure(opIndex);
@@ -2325,11 +2325,11 @@ class YarrGenerator : private MacroAssembler {
m_ops.append(alternativeBeginOpCode);
m_ops.last().m_previousOp = notFound;
m_ops.last().m_term = term;
- Vector<PatternAlternative*>& alternatives = term->parentheses.disjunction->m_alternatives;
+ Vector<OwnPtr<PatternAlternative> >& alternatives = term->parentheses.disjunction->m_alternatives;
for (unsigned i = 0; i < alternatives.size(); ++i) {
size_t lastOpIndex = m_ops.size() - 1;
- PatternAlternative* nestedAlternative = alternatives[i];
+ PatternAlternative* nestedAlternative = alternatives[i].get();
opCompileAlternative(nestedAlternative);
size_t thisOpIndex = m_ops.size();
@@ -2376,11 +2376,11 @@ class YarrGenerator : private MacroAssembler {
m_ops.append(OpSimpleNestedAlternativeBegin);
m_ops.last().m_previousOp = notFound;
m_ops.last().m_term = term;
- Vector<PatternAlternative*>& alternatives = term->parentheses.disjunction->m_alternatives;
+ Vector<OwnPtr<PatternAlternative> >& alternatives = term->parentheses.disjunction->m_alternatives;
for (unsigned i = 0; i < alternatives.size(); ++i) {
size_t lastOpIndex = m_ops.size() - 1;
- PatternAlternative* nestedAlternative = alternatives[i];
+ PatternAlternative* nestedAlternative = alternatives[i].get();
opCompileAlternative(nestedAlternative);
size_t thisOpIndex = m_ops.size();
@@ -2450,7 +2450,7 @@ class YarrGenerator : private MacroAssembler {
// to return the failing result.
void opCompileBody(PatternDisjunction* disjunction)
{
- Vector<PatternAlternative*>& alternatives = disjunction->m_alternatives;
+ Vector<OwnPtr<PatternAlternative> >& alternatives = disjunction->m_alternatives;
size_t currentAlternativeIndex = 0;
// Emit the 'once through' alternatives.
@@ -2460,7 +2460,7 @@ class YarrGenerator : private MacroAssembler {
do {
size_t lastOpIndex = m_ops.size() - 1;
- PatternAlternative* alternative = alternatives[currentAlternativeIndex];
+ PatternAlternative* alternative = alternatives[currentAlternativeIndex].get();
opCompileAlternative(alternative);
size_t thisOpIndex = m_ops.size();
@@ -2495,7 +2495,7 @@ class YarrGenerator : private MacroAssembler {
m_ops.last().m_previousOp = notFound;
do {
size_t lastOpIndex = m_ops.size() - 1;
- PatternAlternative* alternative = alternatives[currentAlternativeIndex];
+ PatternAlternative* alternative = alternatives[currentAlternativeIndex].get();
ASSERT(!alternative->onceThrough());
opCompileAlternative(alternative);
@@ -2524,6 +2524,9 @@ class YarrGenerator : private MacroAssembler {
push(X86Registers::ebp);
move(stackPointerRegister, X86Registers::ebp);
push(X86Registers::ebx);
+ // The ABI doesn't guarantee the upper bits are zero on unsigned arguments, so clear them ourselves.
+ zeroExtend32ToPtr(index, index);
+ zeroExtend32ToPtr(length, length);
#if OS(WINDOWS)
if (compileMode == IncludeSubpatterns)
loadPtr(Address(X86Registers::ebp, 6 * sizeof(void*)), output);
@@ -2605,7 +2608,7 @@ public:
{
}
- void compile(JSGlobalData* globalData, YarrCodeBlock& jitObject)
+ void compile(VM* vm, YarrCodeBlock& jitObject)
{
generateEnter();
@@ -2639,7 +2642,7 @@ public:
backtrack();
// Link & finalize the code.
- LinkBuffer linkBuffer(*globalData, this, REGEXP_CODE_ID);
+ LinkBuffer linkBuffer(*vm, this, REGEXP_CODE_ID);
m_backtrackingState.linkDataLabels(linkBuffer);
if (compileMode == MatchOnly) {
@@ -2686,12 +2689,12 @@ private:
BacktrackingState m_backtrackingState;
};
-void jitCompile(YarrPattern& pattern, YarrCharSize charSize, JSGlobalData* globalData, YarrCodeBlock& jitObject, YarrJITCompileMode mode)
+void jitCompile(YarrPattern& pattern, YarrCharSize charSize, VM* vm, YarrCodeBlock& jitObject, YarrJITCompileMode mode)
{
if (mode == MatchOnly)
- YarrGenerator<MatchOnly>(pattern, charSize).compile(globalData, jitObject);
+ YarrGenerator<MatchOnly>(pattern, charSize).compile(vm, jitObject);
else
- YarrGenerator<IncludeSubpatterns>(pattern, charSize).compile(globalData, jitObject);
+ YarrGenerator<IncludeSubpatterns>(pattern, charSize).compile(vm, jitObject);
}
}}
diff --git a/Source/JavaScriptCore/yarr/YarrJIT.h b/Source/JavaScriptCore/yarr/YarrJIT.h
index bb7033fde..b7ce7d38f 100644
--- a/Source/JavaScriptCore/yarr/YarrJIT.h
+++ b/Source/JavaScriptCore/yarr/YarrJIT.h
@@ -28,7 +28,7 @@
#if ENABLE(YARR_JIT)
-#include "JSGlobalData.h"
+#include "VM.h"
#include "MacroAssemblerCodeRef.h"
#include "MatchResult.h"
#include "Yarr.h"
@@ -42,7 +42,7 @@
namespace JSC {
-class JSGlobalData;
+class VM;
class ExecutablePool;
namespace Yarr {
@@ -132,7 +132,7 @@ enum YarrJITCompileMode {
MatchOnly,
IncludeSubpatterns
};
-void jitCompile(YarrPattern&, YarrCharSize, JSGlobalData*, YarrCodeBlock& jitObject, YarrJITCompileMode = IncludeSubpatterns);
+void jitCompile(YarrPattern&, YarrCharSize, VM*, YarrCodeBlock& jitObject, YarrJITCompileMode = IncludeSubpatterns);
} } // namespace JSC::Yarr
diff --git a/Source/JavaScriptCore/yarr/YarrParser.h b/Source/JavaScriptCore/yarr/YarrParser.h
index 4bab1a090..8c5d71b5f 100644
--- a/Source/JavaScriptCore/yarr/YarrParser.h
+++ b/Source/JavaScriptCore/yarr/YarrParser.h
@@ -212,8 +212,8 @@ private:
// parseEscape() should never call these delegate methods when
// invoked with inCharacterClass set.
- NO_RETURN_DUE_TO_ASSERT void assertionWordBoundary(bool) { ASSERT_NOT_REACHED(); }
- NO_RETURN_DUE_TO_ASSERT void atomBackReference(unsigned) { ASSERT_NOT_REACHED(); }
+ NO_RETURN_DUE_TO_ASSERT void assertionWordBoundary(bool) { RELEASE_ASSERT_NOT_REACHED(); }
+ NO_RETURN_DUE_TO_ASSERT void atomBackReference(unsigned) { RELEASE_ASSERT_NOT_REACHED(); }
private:
Delegate& m_delegate;
diff --git a/Source/JavaScriptCore/yarr/YarrPattern.cpp b/Source/JavaScriptCore/yarr/YarrPattern.cpp
index c953a38d2..3ce0216e5 100644
--- a/Source/JavaScriptCore/yarr/YarrPattern.cpp
+++ b/Source/JavaScriptCore/yarr/YarrPattern.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
*
* Redistribution and use in source and binary forms, with or without
@@ -175,16 +175,16 @@ public:
}
- CharacterClass* charClass()
+ PassOwnPtr<CharacterClass> charClass()
{
- CharacterClass* characterClass = new CharacterClass(0);
+ OwnPtr<CharacterClass> characterClass = adoptPtr(new CharacterClass);
characterClass->m_matches.swap(m_matches);
characterClass->m_ranges.swap(m_ranges);
characterClass->m_matchesUnicode.swap(m_matchesUnicode);
characterClass->m_rangesUnicode.swap(m_rangesUnicode);
- return characterClass;
+ return characterClass.release();
}
private:
@@ -274,9 +274,10 @@ public:
, m_characterClassConstructor(pattern.m_ignoreCase)
, m_invertParentheticalAssertion(false)
{
- m_pattern.m_body = new PatternDisjunction();
- m_alternative = m_pattern.m_body->addNewAlternative();
- m_pattern.m_disjunctions.append(m_pattern.m_body);
+ OwnPtr<PatternDisjunction> body = adoptPtr(new PatternDisjunction);
+ m_pattern.m_body = body.get();
+ m_alternative = body->addNewAlternative();
+ m_pattern.m_disjunctions.append(body.release());
}
~YarrPatternConstructor()
@@ -288,9 +289,10 @@ public:
m_pattern.reset();
m_characterClassConstructor.reset();
- m_pattern.m_body = new PatternDisjunction();
- m_alternative = m_pattern.m_body->addNewAlternative();
- m_pattern.m_disjunctions.append(m_pattern.m_body);
+ OwnPtr<PatternDisjunction> body = adoptPtr(new PatternDisjunction);
+ m_pattern.m_body = body.get();
+ m_alternative = body->addNewAlternative();
+ m_pattern.m_disjunctions.append(body.release());
}
void assertionBOL()
@@ -327,9 +329,9 @@ public:
}
m_characterClassConstructor.putUnicodeIgnoreCase(ch, info);
- CharacterClass* newCharacterClass = m_characterClassConstructor.charClass();
- m_pattern.m_userCharacterClasses.append(newCharacterClass);
- m_alternative->m_terms.append(PatternTerm(newCharacterClass, false));
+ OwnPtr<CharacterClass> newCharacterClass = m_characterClassConstructor.charClass();
+ m_alternative->m_terms.append(PatternTerm(newCharacterClass.get(), false));
+ m_pattern.m_userCharacterClasses.append(newCharacterClass.release());
}
void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert)
@@ -383,15 +385,15 @@ public:
break;
default:
- ASSERT_NOT_REACHED();
+ RELEASE_ASSERT_NOT_REACHED();
}
}
void atomCharacterClassEnd()
{
- CharacterClass* newCharacterClass = m_characterClassConstructor.charClass();
- m_pattern.m_userCharacterClasses.append(newCharacterClass);
- m_alternative->m_terms.append(PatternTerm(newCharacterClass, m_invertCharacterClass));
+ OwnPtr<CharacterClass> newCharacterClass = m_characterClassConstructor.charClass();
+ m_alternative->m_terms.append(PatternTerm(newCharacterClass.get(), m_invertCharacterClass));
+ m_pattern.m_userCharacterClasses.append(newCharacterClass.release());
}
void atomParenthesesSubpatternBegin(bool capture = true)
@@ -400,19 +402,19 @@ public:
if (capture)
m_pattern.m_numSubpatterns++;
- PatternDisjunction* parenthesesDisjunction = new PatternDisjunction(m_alternative);
- m_pattern.m_disjunctions.append(parenthesesDisjunction);
- m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture, false));
+ OwnPtr<PatternDisjunction> parenthesesDisjunction = adoptPtr(new PatternDisjunction(m_alternative));
+ m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction.get(), capture, false));
m_alternative = parenthesesDisjunction->addNewAlternative();
+ m_pattern.m_disjunctions.append(parenthesesDisjunction.release());
}
void atomParentheticalAssertionBegin(bool invert = false)
{
- PatternDisjunction* parenthesesDisjunction = new PatternDisjunction(m_alternative);
- m_pattern.m_disjunctions.append(parenthesesDisjunction);
- m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, false, invert));
+ OwnPtr<PatternDisjunction> parenthesesDisjunction = adoptPtr(new PatternDisjunction(m_alternative));
+ m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction.get(), false, invert));
m_alternative = parenthesesDisjunction->addNewAlternative();
m_invertParentheticalAssertion = invert;
+ m_pattern.m_disjunctions.append(parenthesesDisjunction.release());
}
void atomParenthesesEnd()
@@ -477,23 +479,27 @@ public:
// skip alternatives with m_startsWithBOL set true.
PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction, bool filterStartsWithBOL = false)
{
- PatternDisjunction* newDisjunction = 0;
+ OwnPtr<PatternDisjunction> newDisjunction;
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
- PatternAlternative* alternative = disjunction->m_alternatives[alt];
+ PatternAlternative* alternative = disjunction->m_alternatives[alt].get();
if (!filterStartsWithBOL || !alternative->m_startsWithBOL) {
if (!newDisjunction) {
- newDisjunction = new PatternDisjunction();
+ newDisjunction = adoptPtr(new PatternDisjunction());
newDisjunction->m_parent = disjunction->m_parent;
}
PatternAlternative* newAlternative = newDisjunction->addNewAlternative();
+ newAlternative->m_terms.reserveInitialCapacity(alternative->m_terms.size());
for (unsigned i = 0; i < alternative->m_terms.size(); ++i)
newAlternative->m_terms.append(copyTerm(alternative->m_terms[i], filterStartsWithBOL));
}
}
- if (newDisjunction)
- m_pattern.m_disjunctions.append(newDisjunction);
- return newDisjunction;
+ if (!newDisjunction)
+ return 0;
+
+ PatternDisjunction* copiedDisjunction = newDisjunction.get();
+ m_pattern.m_disjunctions.append(newDisjunction.release());
+ return copiedDisjunction;
}
PatternTerm copyTerm(PatternTerm& term, bool filterStartsWithBOL = false)
@@ -655,7 +661,7 @@ public:
bool hasFixedSize = true;
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
- PatternAlternative* alternative = disjunction->m_alternatives[alt];
+ PatternAlternative* alternative = disjunction->m_alternatives[alt].get();
unsigned currentAlternativeCallFrameSize = setupAlternativeOffsets(alternative, initialCallFrameSize, initialInputPosition);
minimumInputSize = std::min(minimumInputSize, alternative->m_minimumSize);
maximumCallFrameSize = std::max(maximumCallFrameSize, currentAlternativeCallFrameSize);
@@ -690,7 +696,7 @@ public:
if (m_pattern.m_numSubpatterns)
return;
- Vector<PatternAlternative*>& alternatives = m_pattern.m_body->m_alternatives;
+ Vector<OwnPtr<PatternAlternative> >& alternatives = m_pattern.m_body->m_alternatives;
for (size_t i = 0; i < alternatives.size(); ++i) {
Vector<PatternTerm>& terms = alternatives[i]->m_terms;
if (terms.size()) {
@@ -725,7 +731,7 @@ public:
if (loopDisjunction) {
// Move alternatives from loopDisjunction to disjunction
for (unsigned alt = 0; alt < loopDisjunction->m_alternatives.size(); ++alt)
- disjunction->m_alternatives.append(loopDisjunction->m_alternatives[alt]);
+ disjunction->m_alternatives.append(loopDisjunction->m_alternatives[alt].release());
loopDisjunction->m_alternatives.clear();
}
@@ -744,7 +750,7 @@ public:
if (term.type == PatternTerm::TypeParenthesesSubpattern) {
PatternDisjunction* nestedDisjunction = term.parentheses.disjunction;
for (unsigned alt = 0; alt < nestedDisjunction->m_alternatives.size(); ++alt) {
- if (containsCapturingTerms(nestedDisjunction->m_alternatives[alt], 0, nestedDisjunction->m_alternatives[alt]->m_terms.size() - 1))
+ if (containsCapturingTerms(nestedDisjunction->m_alternatives[alt].get(), 0, nestedDisjunction->m_alternatives[alt]->m_terms.size() - 1))
return true;
}
}
@@ -760,11 +766,11 @@ public:
// beginning and the end of the match.
void optimizeDotStarWrappedExpressions()
{
- Vector<PatternAlternative*>& alternatives = m_pattern.m_body->m_alternatives;
+ Vector<OwnPtr<PatternAlternative> >& alternatives = m_pattern.m_body->m_alternatives;
if (alternatives.size() != 1)
return;
- PatternAlternative* alternative = alternatives[0];
+ PatternAlternative* alternative = alternatives[0].get();
Vector<PatternTerm>& terms = alternative->m_terms;
if (terms.size() >= 3) {
bool startsWithBOL = false;
diff --git a/Source/JavaScriptCore/yarr/YarrPattern.h b/Source/JavaScriptCore/yarr/YarrPattern.h
index 14e89b8e0..e7d187c2b 100644
--- a/Source/JavaScriptCore/yarr/YarrPattern.h
+++ b/Source/JavaScriptCore/yarr/YarrPattern.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,8 @@
#define YarrPattern_h
#include <wtf/CheckedArithmetic.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
@@ -48,37 +50,28 @@ struct CharacterRange {
}
};
-struct CharacterClassTable : RefCounted<CharacterClassTable> {
- const char* m_table;
- bool m_inverted;
- static PassRefPtr<CharacterClassTable> create(const char* table, bool inverted)
- {
- return adoptRef(new CharacterClassTable(table, inverted));
- }
-
-private:
- CharacterClassTable(const char* table, bool inverted)
- : m_table(table)
- , m_inverted(inverted)
- {
- }
-};
-
struct CharacterClass {
WTF_MAKE_FAST_ALLOCATED;
public:
// All CharacterClass instances have to have the full set of matches and ranges,
- // they may have an optional table for faster lookups (which must match the
+ // they may have an optional m_table for faster lookups (which must match the
// specified matches and ranges)
- CharacterClass(PassRefPtr<CharacterClassTable> table)
+ CharacterClass()
+ : m_table(0)
+ {
+ }
+ CharacterClass(const char* table, bool inverted)
: m_table(table)
+ , m_tableInverted(inverted)
{
}
Vector<UChar> m_matches;
Vector<CharacterRange> m_ranges;
Vector<UChar> m_matchesUnicode;
Vector<CharacterRange> m_rangesUnicode;
- RefPtr<CharacterClassTable> m_table;
+
+ const char* m_table;
+ bool m_tableInverted;
};
enum QuantifierType {
@@ -275,19 +268,14 @@ public:
{
}
- ~PatternDisjunction()
- {
- deleteAllValues(m_alternatives);
- }
-
PatternAlternative* addNewAlternative()
{
PatternAlternative* alternative = new PatternAlternative(this);
- m_alternatives.append(alternative);
+ m_alternatives.append(adoptPtr(alternative));
return alternative;
}
- Vector<PatternAlternative*> m_alternatives;
+ Vector<OwnPtr<PatternAlternative> > m_alternatives;
PatternAlternative* m_parent;
unsigned m_minimumSize;
unsigned m_callFrameSize;
@@ -318,12 +306,6 @@ struct TermChain {
struct YarrPattern {
JS_EXPORT_PRIVATE YarrPattern(const String& pattern, bool ignoreCase, bool multiline, const char** error);
- ~YarrPattern()
- {
- deleteAllValues(m_disjunctions);
- deleteAllValues(m_userCharacterClasses);
- }
-
void reset()
{
m_numSubpatterns = 0;
@@ -340,9 +322,7 @@ struct YarrPattern {
nonspacesCached = 0;
nonwordcharCached = 0;
- deleteAllValues(m_disjunctions);
m_disjunctions.clear();
- deleteAllValues(m_userCharacterClasses);
m_userCharacterClasses.clear();
}
@@ -354,43 +334,43 @@ struct YarrPattern {
CharacterClass* newlineCharacterClass()
{
if (!newlineCached)
- m_userCharacterClasses.append(newlineCached = newlineCreate());
+ m_userCharacterClasses.append(adoptPtr(newlineCached = newlineCreate()));
return newlineCached;
}
CharacterClass* digitsCharacterClass()
{
if (!digitsCached)
- m_userCharacterClasses.append(digitsCached = digitsCreate());
+ m_userCharacterClasses.append(adoptPtr(digitsCached = digitsCreate()));
return digitsCached;
}
CharacterClass* spacesCharacterClass()
{
if (!spacesCached)
- m_userCharacterClasses.append(spacesCached = spacesCreate());
+ m_userCharacterClasses.append(adoptPtr(spacesCached = spacesCreate()));
return spacesCached;
}
CharacterClass* wordcharCharacterClass()
{
if (!wordcharCached)
- m_userCharacterClasses.append(wordcharCached = wordcharCreate());
+ m_userCharacterClasses.append(adoptPtr(wordcharCached = wordcharCreate()));
return wordcharCached;
}
CharacterClass* nondigitsCharacterClass()
{
if (!nondigitsCached)
- m_userCharacterClasses.append(nondigitsCached = nondigitsCreate());
+ m_userCharacterClasses.append(adoptPtr(nondigitsCached = nondigitsCreate()));
return nondigitsCached;
}
CharacterClass* nonspacesCharacterClass()
{
if (!nonspacesCached)
- m_userCharacterClasses.append(nonspacesCached = nonspacesCreate());
+ m_userCharacterClasses.append(adoptPtr(nonspacesCached = nonspacesCreate()));
return nonspacesCached;
}
CharacterClass* nonwordcharCharacterClass()
{
if (!nonwordcharCached)
- m_userCharacterClasses.append(nonwordcharCached = nonwordcharCreate());
+ m_userCharacterClasses.append(adoptPtr(nonwordcharCached = nonwordcharCreate()));
return nonwordcharCached;
}
@@ -401,8 +381,8 @@ struct YarrPattern {
unsigned m_numSubpatterns;
unsigned m_maxBackReference;
PatternDisjunction* m_body;
- Vector<PatternDisjunction*, 4> m_disjunctions;
- Vector<CharacterClass*> m_userCharacterClasses;
+ Vector<OwnPtr<PatternDisjunction>, 4> m_disjunctions;
+ Vector<OwnPtr<CharacterClass> > m_userCharacterClasses;
private:
const char* compile(const String& patternString);